Back in the 21.4 days, `set-window-configuration' was written in C. In that
code were a few commented-out sections:
/* JV: This is bogus,
First of all, the units are inconsistent. The frame sizes are measured
in characters but the window sizes are stored in pixels. So if a
font size change happened between saving and restoring, the
frame "sizes" maybe equal but the windows still should be
resized. This is tickled a lot by the new "character size
stays constant" policy in 21.0. It leads to very weird
glitches (and possibly crashes when asserts are tickled).
Just changing the units doesn't help because changing the
toolbar configuration can also change the pixel positions.
Luckily there is a much simpler way of doing this, see below.
previous_frame_width = FRAME_WIDTH (f);
previous_frame_height = FRAME_HEIGHT (f);
/* If the frame has been resized since this window configuration was
made, we change the frame to the size specified in the
configuration, restore the configuration, and then resize it
back. We keep track of the prevailing height in these variables. */
if (config->frame_height != FRAME_HEIGHT (f)
|| config->frame_width != FRAME_WIDTH (f))
change_frame_size (f, config->frame_height, config->frame_width, 0);
In the move of this code to Lisp, this feature was implemented, which is
probably a good thing: otherwise, you can try to restore a window
configuration and then find that there isn't room to restore it because
the frame is too small.
Unfortunately, another feature was added at the same time: frame
positions are now saved in window configurations, and restored on
`set-window-configuration'. This is profoundly counterintuitive, for
- the position of a frame does not conceptually affect its contents:
the half-dozen XEmacs users I've informally polled consider that if
they drag a frame halfway across the screen with a *Help* buffer open,
say, closing it should not pop the frame back where it came from!
(There was a strong current of opinion saying that the frame size
should remain unchanged, as well, but that's harder to implement:
we'd have to attempt window restoration, and then restore the frame
size only if there's not enough room, and that sort of seemingly-
inconsistent behaviour is perhaps even more annoying than the
behaviour it replaces.)
- window configurations are used by all sorts of things not directly
commanded by the user: the window-configuration stack uses it, as
I just mentioned, and unless like me you've bound
`pushpop-window-configuration' to something this will remain an
undocumented feature which only people who read .el files for fun
will discover. But, more than that, `save-window-excursion' uses
it, and the docstring for that function says that it saves `window
sizes and contents': nothing about positions. A lot of functions far
from user view call `save-window-excursion', often to enable them to
repurpose user-interface functions for their own use.
A particularly extreme example is `bbdb-hashtable', which expands
the `bbdb-with-db-buffer' function, which calls `save-window-excursion',
and which is used by a huge number of functions in BBDB. e.g., if you
have the BBDB set up to replace full in Gnus with names from the BBDB,
this function gets called when populating summary buffers *once for
- window positions are modified by the window manager, as well as by
the user, and are modified extensively in ways the user might not
expect. e.g. if FVWM-style viewports are in use, the position of every
window on the system will change whenever you flip viewports --- and
if XEmacs grabs a window configuration, then you change desktops,
and then it restores, XEmacs may just have pushed one of its frames
completely off the visible viewport area, and will definitely have
made it spontaneously change virtual desktops. This is supremely
annoying, particularly when combined with the previous item: now
you can start going into a summary buffer, flip to another viewport
to do something else while Gnus churns to itself, and *whoops*!
XEmacs has just chosen to move itself somewhere else for you!
So this patch (against CVS HEAD as of this morning) makes this feature
optional, and *off* by default (because a *lot* of people use
viewport-based virtual desktops, and it breaks for all of them, and my
informal poll found that people considered it counterintuitive anyway).
2006-10-28 Nix <nix(a)esperi.org.uk>
* window-xemacs.el (window-configuration-includes-position): New.
* window-xemacs.el (window-configuration-equal): Use it: window
configurations with distinct positions are equal by default.
* window-xemacs.el (really-set-window-configuration): Do not
restore window positions unless requested.
--- 21.5.orig/lisp/window-xemacs.el 2006-10-20 19:50:53.000000000 +0100
+++ 21.5/lisp/window-xemacs.el 2006-10-28 15:02:30.000000000 +0100
＠＠ -107,6 +107,15 ＠＠
;; Window configurations
+(defcustom window-configuration-includes-position nil
+ "*Whether restoring window configurations will restore positions too.
+If nil, only the size of windows will be restored.
+Note that setting this value to t may have counterintuitive consequences,
+if a window manager employing virtual desktops is in use."
currentp minibufferp minibuffer-scrollp
＠＠ -128,7 +137,11 ＠＠
(defun window-configuration-equal (conf-1 conf-2)
"Returns a boolean indicating whether the two given configurations
+Window configurations containing windows with different window
+positions are not identical iff `window-configuration-includes-position'
(or (eq conf-1 conf-2)
(and (eq (window-configuration-frame conf-1)
＠＠ -136,10 +149,12 ＠＠
(= (window-configuration-frame-pixel-height conf-1)
- (equal (window-configuration-frame-top conf-1)
- (window-configuration-frame-top conf-2))
- (equal (window-configuration-frame-left conf-1)
- (window-configuration-frame-left conf-2))
+ (if window-configuration-includes-position
+ (and (equal (window-configuration-frame-top conf-1)
+ (window-configuration-frame-top conf-2))
+ (equal (window-configuration-frame-left conf-1)
+ (window-configuration-frame-left conf-2)))
(eq (window-configuration-current-buffer conf-1)
(saved-window-equal (window-configuration-saved-root-window conf-1)
＠＠ -294,12 +309,13 ＠＠
; avoid setting these if they're already up-to-date
; This also avoids potential inaccuracies in these settings --Mike
- (let ((left (window-configuration-frame-left configuration))
- (top (window-configuration-frame-top configuration)))
- (if (not (equal left (frame-property frame 'left)))
- (set-frame-property frame 'left left))
- (if (not (equal top (frame-property frame 'top)))
- (set-frame-property frame 'top top)))
+ (when window-configuration-includes-position
+ (let ((left (window-configuration-frame-left configuration))
+ (top (window-configuration-frame-top configuration)))
+ (if (not (equal left (frame-property frame 'left)))
+ (set-frame-property frame 'left left))
+ (if (not (equal top (frame-property frame 'top)))
+ (set-frame-property frame 'top top))))
;; these may have changed because of the delete
(let ((root-window (frame-root-window frame)))
XEmacs-Patches mailing list