Package: emacs;
Reported by: Michael Bach <phaebz <at> gmail.com>
Date: Thu, 22 Dec 2011 01:40:08 UTC
Severity: normal
Found in version 24.0.92
Done: martin rudalics <rudalics <at> gmx.at>
Bug is archived. No further changes may be made.
Message #86 received at 10348 <at> debbugs.gnu.org (full text, mbox):
From: martin rudalics <rudalics <at> gmx.at> To: Stefan Monnier <monnier <at> iro.umontreal.ca> Cc: Michael Bach <phaebz <at> gmail.com>, 10348 <at> debbugs.gnu.org Subject: Re: bug#10348: 24.0.92; Save and load window states Date: Wed, 28 Dec 2011 10:50:17 +0100
[Message part 1 (text/plain, inline)]
I wrote a tentative patch to handle this. Please have a look. Thanks, martin
[window-parameters.diff (text/plain, inline)]
=== modified file 'doc/lispref/windows.texi' --- doc/lispref/windows.texi 2011-12-13 13:37:48 +0000 +++ doc/lispref/windows.texi 2011-12-27 17:51:15 +0000 @@ -3104,9 +3104,24 @@ @defun current-window-configuration &optional frame This function returns a new object representing @var{frame}'s current window configuration. The default for @var{frame} is the selected -frame. +frame. This function copies the value of all window parameters listed +by @code{window-persistent-parameters}, see below. @end defun +@defvar window-persistent-parameters +This variable lists all window parameters that shall be saved by +@code{current-window-configuration}, see above, and restored by +@code{set-window-configuration}, see below. This means that the value +of any parameter listed by this variable and changed within the body of +@code{save-window-excursion} is restored to its previous value when the +window excursion exits. Parameters not listed by this variable are left +alone when the window excursion terminates. + +The parameters listed by this variable are treated in a similar manner +by the functions @code{window-state-get} and @code{window-state-put}, +see below. +@end defvar + @defun set-window-configuration configuration This function restores the configuration of windows and buffers as specified by @var{configuration}, for the frame that @var{configuration} @@ -3121,6 +3136,10 @@ know how to tell whether the new configuration actually differs from the old one. +This function restores the values of all window parameters listed by +@code{window-persistent-parameters}, see above, to their values saved in +@var{configuration}. + If the frame which @var{configuration} was saved from is dead, all this function does is restore the three variables @code{window-min-height}, @code{window-min-width} and @code{minibuffer-scroll-window}. In this @@ -3209,18 +3228,28 @@ configuration on disk and read it back in another Emacs session the following two functions can be used. -@defun window-state-get &optional window markers +@defun window-state-get &optional window ignore This function returns the state of @var{window} as a Lisp object. The argument @var{window} can be any window and defaults to the root window of the selected frame. -The optional argument @var{markers} non-@code{nil} means to use markers -for sampling positions like @code{window-point} or @code{window-start}. -This argument should be non-@code{nil} only if the value is used for -putting the state back in the same session since markers slow down -processing. +If the optional argument @var{ignore} is non-@code{nil}, this means to +not use markers for sampling positions like @code{window-point} or +@code{window-start} and to not save values of parameters in the list +@code{window-state-ignored-parameters}, see below. This argument should +be non-@code{nil} when the state shall be written on disk and read back +in another session. + +This function copies the value of all window parameters listed by the +variable @code{window-persistent-parameters}, see above. @end defun +@defvar window-state-ignored-parameters +This variable lists all parameters whose value must not be recorded by +the function @code{window-state-get} when its @var{ignore} argument is +non-@code{nil}, see above. +@end defvar + The value returned by @code{window-state-get} can be converted by using one of the functions defined by Desktop Save Mode (@pxref{Desktop Save Mode}) to an object that can be written to a file. Such objects can be @@ -3239,6 +3268,10 @@ minimum window sizes and fixed size restrictions. If @var{ignore} equals @code{safe}, this means windows can get as small as one line and/or two columns. + +This function restores the values of all window parameters listed by +@code{window-persistent-parameters}, see above, to their values in +@var{state}. @end defun === modified file 'lisp/window.el' --- lisp/window.el 2011-12-24 19:16:53 +0000 +++ lisp/window.el 2011-12-27 16:36:57 +0000 @@ -3568,10 +3568,12 @@ )) ;;; Window states, how to get them and how to put them in a window. -(defvar window-state-ignored-parameters '(quit-restore) - "List of window parameters ignored by `window-state-get'.") +(defvar window-state-ignored-parameters '(quit-restore clone-of) + "Window parameters ignored by `window-state-get'. +Parameters in this list are not saved by `window-state-get' when +its IGNORE argument is non-nil.") -(defun window--state-get-1 (window &optional markers) +(defun window--state-get-1 (window &optional ignore) "Helper function for `window-state-get'." (let* ((type (cond @@ -3590,11 +3592,18 @@ (combination-limit . ,(window-combination-limit window)) ,@(let (list) (dolist (parameter (window-parameters window)) - (unless (memq (car parameter) - window-state-ignored-parameters) - (setq list (cons parameter list)))) - (unless (window-parameter window 'clone-of) - ;; Make a clone-of parameter. + ;; When IGNORE is nil, add a parameter only if it is + ;; in `window-persistent-parameters'. When IGNORE is + ;; non-nil, add a parameter if and only if it is not + ;; in `window-state-ignored-parameters'. + (when (if ignore + (not (memq (car parameter) + window-state-ignored-parameters)) + (memq (car parameter) window-persistent-parameters)) + (setq list (cons (cons (car parameter) (cdr parameter)) + list)))) + (unless (or ignore (window-parameter window 'clone-of)) + ;; Make `clone-of' parameter unless IGNORE is non-nil. (setq list (cons (cons 'clone-of window) list))) (when list `((parameters . ,list)))) @@ -3616,30 +3625,32 @@ (scroll-bars . ,(window-scroll-bars window)) (vscroll . ,(window-vscroll window)) (dedicated . ,(window-dedicated-p window)) - (point . ,(if markers (copy-marker point) point)) - (start . ,(if markers (copy-marker start) start)) + (point . ,(if ignore point (copy-marker point))) + (start . ,(if ignore start (copy-marker start))) ,@(when mark - `((mark . ,(if markers - (copy-marker mark) mark))))))))))) + `((mark . ,(if ignore + mark (copy-marker mark)))))))))))) (tail (when (memq type '(vc hc)) (let (list) (setq window (window-child window)) (while window - (setq list (cons (window--state-get-1 window markers) list)) + (setq list (cons (window--state-get-1 window ignore) list)) (setq window (window-right window))) (nreverse list))))) (append head tail))) -(defun window-state-get (&optional window markers) +(defun window-state-get (&optional window ignore) "Return state of WINDOW as a Lisp object. WINDOW can be any window and defaults to the root window of the selected frame. -Optional argument MARKERS non-nil means use markers for sampling -positions like `window-point' or `window-start'. MARKERS should -be non-nil only if the value is used for putting the state back -in the same session (note that markers slow down processing). +Optional argument IGNORE non-nil means do not use markers for +sampling positions like `window-point' or `window-start' and do +not record ignored window parameters as specified by +`window-state-ignored-parameters'. IGNORE should be non-nil when +the return value shall be written to a file and read back in +another session. The return value can be used as argument for `window-state-put' to put the state recorded here into an arbitrary window. The @@ -3665,7 +3676,7 @@ ;; These are probably not needed. ,@(when (window-size-fixed-p window) `((fixed-height . t))) ,@(when (window-size-fixed-p window t) `((fixed-width . t)))) - (window--state-get-1 window markers))) + (window--state-get-1 window ignore))) (defvar window-state-put-list nil "Helper variable for `window-state-put'.") @@ -3744,6 +3755,10 @@ (state (cdr (assq 'buffer item)))) (when combination-limit (set-window-combination-limit window combination-limit)) + ;; nil out values of parameters in `window-persistent-parameters'. + (dolist (parameter (window-parameters window)) + (when (memq (car parameter) window-persistent-parameters) + (set-window-parameter window (car parameter) nil))) ;; Process parameters. (when parameters (dolist (parameter parameters) === modified file 'src/window.c' --- src/window.c 2011-12-13 13:58:20 +0000 +++ src/window.c 2011-12-27 09:37:03 +0000 @@ -5349,6 +5349,7 @@ (Lisp_Object configuration) { register struct save_window_data *data; + register Lisp_Object tem, car; struct Lisp_Vector *saved_windows; Lisp_Object new_current_buffer; Lisp_Object frame; @@ -5543,7 +5544,25 @@ w->vertical_scroll_bar_type = p->vertical_scroll_bar_type; w->dedicated = p->dedicated; w->combination_limit = p->combination_limit; - w->window_parameters = p->window_parameters; + /* nil out values of persistent window parameters. */ + if (!NILP (w->window_parameters)) + for (tem = w->window_parameters; CONSP (tem); tem = XCDR (tem)) + { + car = XCAR (tem); + if (CONSP (car) + && !NILP (Fmemq (XCAR (car), Vwindow_persistent_parameters))) + Fsetcdr (car, Qnil); + } + + /* Restore persistent window parameters. */ + if (!NILP (p->window_parameters)) + for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem)) + { + car = XCAR (tem); + if (CONSP (car)) + Fset_window_parameter (window, XCAR (car), XCDR (car)); + } + XSETFASTINT (w->last_modified, 0); XSETFASTINT (w->last_overlay_modified, 0); @@ -5810,7 +5829,7 @@ { register struct saved_window *p; register struct window *w; - register Lisp_Object tem; + register Lisp_Object tem, car; for (;!NILP (window); window = w->next) { @@ -5838,7 +5857,18 @@ p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; p->dedicated = w->dedicated; p->combination_limit = w->combination_limit; - p->window_parameters = w->window_parameters; + p->window_parameters = Qnil; + /* Store copies of persistent window parameters. */ + if (!NILP (w->window_parameters)) + for (tem = w->window_parameters; CONSP (tem); tem = XCDR (tem)) + { + car = XCAR (tem); + if (CONSP (car) + && !NILP (Fmemq (XCAR (car), Vwindow_persistent_parameters))) + p->window_parameters = Fcons (Fcons (XCAR (car), XCDR (car)), + p->window_parameters); + } + if (!NILP (w->buffer)) { /* Save w's value of point in the window configuration. @@ -6542,6 +6572,13 @@ function `set-window-combination-limit'. */); Vwindow_combination_limit = Qnil; + DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters, + doc: /* List of persistent window parameters. +The parameters in this list are saved by `current-window-configuration' +and `window-state-get' and restored by `set-window-configuration' and +`window-state-put'. */); + Vwindow_persistent_parameters = Qnil; + defsubr (&Sselected_window); defsubr (&Sminibuffer_window); defsubr (&Swindow_minibuffer_p);
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.