Fix setting windows' old_buffer in 'set-window-configuration' (Bug#81589)

* src/window.c (struct save_window_data): New slot change_stamp.
(Fset_window_configuration): Restore the old_buffer of a window
from the saved old_buffer only if the change stamps of the frame
and save_window_data are the same (Bug#81589).
(Fcurrent_window_configuration): Store FRAME's current change
stamp in save_window_data.
This commit is contained in:
Martin Rudalics 2026-08-09 18:32:31 +02:00
parent 8b32d77a07
commit 73d959233e

View file

@ -7598,7 +7598,8 @@ struct save_window_data
/* All fields above are traced by the GC.
After saved_windows, the fields are ignored by the GC. */
/* The change stamp of the frame at the time of saving. */
int change_stamp;
/* We should be able to do without the following two. */
int frame_cols, frame_lines;
/* These three should get eventually replaced by their pixel
@ -7839,7 +7840,25 @@ the return value is nil. Otherwise the value is t. */)
/* If we squirreled away the buffer, restore it now. */
if (BUFFERP (w->combination_limit))
wset_buffer (w, w->combination_limit);
wset_old_buffer (w, p->old_buffer);
if (data->change_stamp == f->change_stamp)
/* Restore W's old_buffer slot but only if the configuration
was saved and restored in between two redisplay cycles,
that is, if F's saved change stamp and its current change
stamp are equal. In that case we should run W's buffer
change functions provided the saved old_buffer and the
restored buffer differ. If the saved old_buffer and the
restored buffer are one and the same, the window
excursion was only temporary and it would be distracting
to run the buffer change functions for it.
If the change stamps are not equal, run the buffer change
functions provided W's current buffer (which was stored
by delete_all_child_windows above in W's old_buffer slot)
and the buffer that will be restored differ (Bug#81079
and Bug#81589). */
w->old_buffer = p->old_buffer;
w->pixel_left = XFIXNAT (p->pixel_left);
w->pixel_top = XFIXNAT (p->pixel_top);
w->pixel_width = XFIXNAT (p->pixel_width);
@ -8380,6 +8399,7 @@ saved by this function. */)
data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
data->root_window = FRAME_ROOT_WINDOW (f);
data->focus_frame = FRAME_FOCUS_FRAME (f);
data->change_stamp = f->change_stamp;
Lisp_Object tem = make_nil_vector (n_windows);
data->saved_windows = tem;
for (ptrdiff_t i = 0; i < n_windows; i++)