emacs-31 73d959233e2: Fix setting windows' old_buffer in 'set-window-configuration' (Bug#81589)

Martin Rudalics via Mailing list for Emacs changes <[email protected]>
Newsgroups gmane.emacs.diffs
Message-ID <[email protected]>
branch: emacs-31
commit 73d959233e264d29cd327ac259c82ca4bc6d4510
Author: Martin Rudalics <[email protected]>
Commit: Martin Rudalics <[email protected]>

    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.
---
 src/window.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/window.c b/src/window.c
index e4b0e62f3a3..022fb6a0d9f 100644
--- a/src/window.c
+++ b/src/window.c
@@ -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++)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.