Subject: bug#55412: 28.1; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work properly

From: martin rudalics <[email-masked]>
Date: Sun, 15 May 2022 11:28:16 +0200

> ;;; In Emacs 28.1, using ':eval' in 'frame-title-format' doesn't work like it
 > ;;; used to in Emacs 27 and earlier. In fact, it is completely broken, if one
 > ;;; uses a frame-parameter in ':eval'.
 > ;;;
 > ;;; The following elisp snippet demonstrates the problem in an Emacs 28.1
 > ;;; instance started with 'emacs -Q'
 >
 > (defun title-suffix ()
 >    (cdr (assoc 'title-suffix (frame-parameters (selected-frame)))))
 >
 > (defvar title-prefix "Test")
 > (setq frame-title-format (list title-prefix '(:eval (title-suffix)) " %b"))
 >
 > ;;; The original frame should show a frame title of 'Test *scratch*'
 > (set-frame-parameter (selected-frame) 'title-suffix "")
 >
 > ;;; The next frame created should show a frame title of 'Test-xxx *scratch*'
 > (make-frame-command)
 > (set-frame-parameter (selected-frame) 'title-suffix "-xxx")
 >
 > ;;; The third frame created should show a frame title of 'Test-yyy *scratch*'
 > (make-frame-command)
 > (set-frame-parameter (selected-frame) 'title-suffix "-yyy")
 >
 > ;;; In Emacs 27 and earlier, that is exactly what happens. Selecting a
 > ;;; different frame doesn't change the titles of all other frames.
 >
 > ;;; In Emacs 28.1, all frames show the same frame title, with the last one
 > ;;; selected determining which one is shown for the bunch of them. Changing to
 > ;;; a different frame changes the titles of all frames to the title of the
 > ;;; newly selected one.

Could you try the attached patch?  Its purpose is to solve a more
general problem in this area and I had to scrape it out from my sources
so there are most likely dragons around.  But AFAICT it does not exhibit
the problem you see, tested with a GNUstep build on old stable Debian.

Thanks, martin

diff --git a/src/window.c b/src/window.c
index a87b4834aa..7f616bc5ac 100644
--- a/src/window.c
+++ b/src/window.c
@@ -607,6 +607,121 @@ select_window_1 (Lisp_Object window, bool inhibit_point_swap)
   set_point_from_marker (XWINDOW (window)->pointm);
 }
 
+
+/** Temporarily select a window with minimum overhead.  */
+
+static Lisp_Object Vwith_window_selected_vector;
+
+static Lisp_Object
+with_window_selected_unwind_data (Lisp_Object window)
+{
+  Lisp_Object vector, buffer;
+  struct frame *f = WINDOW_XFRAME (XWINDOW (window));
+
+  vector = Vwith_window_selected_vector;
+  Vwith_window_selected_vector = Qnil;
+
+  if (NILP (vector))
+    vector = make_nil_vector (4);
+
+  /* Current buffer.  To be restored if still alive.  */
+  XSETBUFFER (buffer, current_buffer);
+  ASET (vector, 0, buffer);
+  /* Selected window.  To be restored if still alive.  */
+  ASET (vector, 1, selected_window);
+  /* Selected window of WINDOW's frame.  To be restored if still
+     alive.  */
+  ASET (vector, 2, f->selected_window);
+  /* For a TTY frame save its top-frame.  To be restored if still
+     alive.  */
+  if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
+    ASET (vector, 3, FRAME_TTY (f)->top_frame);
+  else
+    ASET (vector, 3, Qnil);
+
+  return vector;
+}
+
+
+static void
+unwind_with_window_selected (Lisp_Object vector)
+{
+  Lisp_Object buffer = AREF (vector, 0);
+  Lisp_Object window = AREF (vector, 1);
+  Lisp_Object frame_selected_window = AREF (vector, 2);
+  Lisp_Object top_frame = AREF (vector, 3);
+
+  /* Restore things iff the window is still alive.  */
+  if (WINDOW_LIVE_P (window))
+    {
+      struct window *w = XWINDOW (window);
+      Lisp_Object frame = WINDOW_FRAME (w);
+      struct frame *f = XFRAME (frame);
+
+      /* Restore the frame's selected window if it's still alive.  */
+      if (WINDOW_LIVE_P (frame_selected_window))
+	WINDOW_XFRAME (XWINDOW (frame_selected_window))->selected_window
+	  = frame_selected_window;
+
+      /* Make w->contents current before calling select_window_1 because
+	 the latter sets PT from w->pointm.  */
+      set_buffer_internal_1 (XBUFFER (w->contents));
+      select_window_1 (window, false);
+
+      if (FRAMEP (top_frame) && FRAME_LIVE_P (XFRAME (top_frame)))
+	selected_frame = top_frame;
+      else
+	selected_frame = frame;
+
+      f->selected_window = window;
+    }
+
+  /* Restore current buffer if it's still alive.  */
+  if (BUFFER_LIVE_P (XBUFFER (buffer)))
+    set_buffer_internal_1 (XBUFFER (buffer));
+
+  Vwith_window_selected_vector = vector;
+}
+
+
+/**  Canonical form to run something with WINDOW temporarily selected.
+     Note: This does not pop the unwind-protect stack and subsequently
+     call unwind_with_window_selected.  Callers have to provide the
+     corresponding unbind_to form themselves.  **/
+void
+with_window_selected (Lisp_Object window)
+{
+  if (!EQ (window, selected_window)
+      || current_buffer != XBUFFER (XWINDOW (selected_window)->contents))
+    {
+      struct window *w = XWINDOW (window);
+      Lisp_Object frame = WINDOW_FRAME (w);
+      struct frame *f = XFRAME (frame);
+      struct window *ow = XWINDOW (selected_window);
+
+      record_unwind_protect (unwind_with_window_selected,
+			     with_window_selected_unwind_data (window));
+
+      set_buffer_internal_1 (XBUFFER (w->contents));
+
+      if (BUFFERP (ow->contents))
+	set_marker_both (ow->pointm, ow->contents,
+			 BUF_PT (XBUFFER (ow->contents)),
+			 BUF_PT_BYTE (XBUFFER (ow->contents)));
+
+      selected_window = window;
+
+      if (!NILP (XWINDOW (window)->pointm))
+	set_point_from_marker (XWINDOW (window)->pointm);
+
+      selected_frame = frame;
+      f->selected_window = window;
+      if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
+	FRAME_TTY (f)->top_frame = frame;
+    }
+}
+
+
 DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
        doc: /* Select WINDOW which must be a live window.
 Also make WINDOW's frame the selected frame and WINDOW that frame's
@@ -8151,6 +8266,9 @@ init_window_once (void)
   minibuf_selected_window = Qnil;
   staticpro (&minibuf_selected_window);
 
+  Vwith_window_selected_vector = Qnil;
+  staticpro (&Vwith_window_selected_vector);
+
   pdumper_do_now_and_after_late_load (init_window_once_for_pdumper);
 }
 
diff --git a/src/window.h b/src/window.h
index 7f7de58846..67f4bbd9e0 100644
--- a/src/window.h
+++ b/src/window.h
@@ -1192,6 +1192,7 @@ #define CHECK_LIVE_WINDOW(WINDOW)				\
 extern void temp_output_buffer_show (Lisp_Object);
 extern void replace_buffer_in_windows (Lisp_Object);
 extern void replace_buffer_in_windows_safely (Lisp_Object);
+extern void with_window_selected (Lisp_Object);
 /* This looks like a setter, but it is a bit special.  */
 extern void wset_buffer (struct window *, Lisp_Object);
 extern bool window_outdated (struct window *);
diff --git a/src/xdisp.c b/src/xdisp.c
index 5ff54b2884..840437f76a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -12967,20 +12967,17 @@ #define MODE_LINE_NOPROP_LEN(start) \
 static Lisp_Object Vmode_line_unwind_vector;
 
 static Lisp_Object
-format_mode_line_unwind_data (struct frame *target_frame,
-			      struct buffer *obuf,
-			      Lisp_Object owin,
-			      bool save_proptrans)
+format_mode_line_unwind_data (bool save_proptrans)
 {
-  Lisp_Object vector, tmp;
+  Lisp_Object vector;
 
   /* Reduce consing by keeping one vector in
-     Vwith_echo_area_save_vector.  */
+     Vmode_line_unwind_vector.  */
   vector = Vmode_line_unwind_vector;
   Vmode_line_unwind_vector = Qnil;
 
   if (NILP (vector))
-    vector = make_nil_vector (12);
+    vector = make_nil_vector (6);
 
   ASET (vector, 0, make_fixnum (mode_line_target));
   ASET (vector, 1, make_fixnum (MODE_LINE_NOPROP_LEN (0)));
@@ -12989,44 +12986,12 @@ format_mode_line_unwind_data (struct frame *target_frame,
   ASET (vector, 4, mode_line_string_face);
   ASET (vector, 5, mode_line_string_face_prop);
 
-  if (obuf)
-    XSETBUFFER (tmp, obuf);
-  else
-    tmp = Qnil;
-  ASET (vector, 6, tmp);
-  ASET (vector, 7, owin);
-  if (target_frame)
-    {
-      Lisp_Object buffer = XWINDOW (target_frame->selected_window)->contents;
-      struct buffer *b = XBUFFER (buffer);
-      struct buffer *cb = current_buffer;
-
-      /* Similarly to `with-selected-window', if the operation selects
-	 a window on another frame, we must restore that frame's
-	 selected window, and (for a tty) the top-frame.  */
-      ASET (vector, 8, target_frame->selected_window);
-      if (FRAME_TERMCAP_P (target_frame))
-	ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
-
-      /* If we select a window on another frame, make sure that that
-	 selection does not leave its buffer's point modified when
-	 unwinding (Bug#32777).  */
-      ASET (vector, 10, buffer);
-      current_buffer = b;
-      ASET (vector, 11, build_marker (current_buffer, PT, PT_BYTE));
-      current_buffer = cb;
-    }
-
   return vector;
 }
 
 static void
 unwind_format_mode_line (Lisp_Object vector)
 {
-  Lisp_Object old_window = AREF (vector, 7);
-  Lisp_Object target_frame_window = AREF (vector, 8);
-  Lisp_Object old_top_frame = AREF (vector, 9);
-
   mode_line_target = XFIXNUM (AREF (vector, 0));
   mode_line_noprop_ptr = mode_line_noprop_buf + XFIXNUM (AREF (vector, 1));
   mode_line_string_list = AREF (vector, 2);
@@ -13035,55 +13000,9 @@ unwind_format_mode_line (Lisp_Object vector)
   mode_line_string_face = AREF (vector, 4);
   mode_line_string_face_prop = AREF (vector, 5);
 
-  /* Select window before buffer, since it may change the buffer.  */
-  if (WINDOW_LIVE_P (old_window))
-    {
-      /* If the operation that we are unwinding had selected a window
-	 on a different frame, reset its frame-selected-window.  For a
-	 text terminal, reset its top-frame if necessary.  */
-      if (WINDOW_LIVE_P (target_frame_window))
-	{
-	  Lisp_Object frame
-	    = WINDOW_FRAME (XWINDOW (target_frame_window));
-
-	  if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
-	    Fselect_window (target_frame_window, Qt);
-
-	  if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
-	    Fselect_frame (old_top_frame, Qt);
-	}
-
-      Fselect_window (old_window, Qt);
-
-      /* Restore point of target_frame_window's buffer (Bug#32777).
-	 But do this only after old_window has been reselected to
-	 avoid that the window point of target_frame_window moves.  */
-      if (WINDOW_LIVE_P (target_frame_window))
-	{
-	  Lisp_Object buffer = AREF (vector, 10);
-
-	  if (BUFFER_LIVE_P (XBUFFER (buffer)))
-	    {
-	      struct buffer *cb = current_buffer;
-
-	      current_buffer = XBUFFER (buffer);
-	      set_point_from_marker (AREF (vector, 11));
-	      ASET (vector, 11, Qnil);
-	      current_buffer = cb;
-	    }
-	}
-    }
-
-  if (!NILP (AREF (vector, 6)))
-    {
-      set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
-      ASET (vector, 6, Qnil);
-    }
-
   Vmode_line_unwind_vector = vector;
 }
 
-
 /* Store a single character C for the frame title in mode_line_noprop_buf.
    Re-allocate mode_line_noprop_buf if necessary.  */
 
@@ -13195,15 +13114,11 @@ gui_consider_frame_title (Lisp_Object frame)
 	 Bug#34317.  */
       specbind (Qinhibit_redisplay, Qt);
 
-      /* Switch to the buffer of selected window of the frame.  Set up
-	 mode_line_target so that display_mode_element will output into
-	 mode_line_noprop_buf; then display the title.  */
+      with_window_selected (f->selected_window);
+
       record_unwind_protect (unwind_format_mode_line,
-			     format_mode_line_unwind_data
-			     (NULL, current_buffer, Qnil, false));
+			     format_mode_line_unwind_data (false));
 
-      set_buffer_internal_1
-	(XBUFFER (XWINDOW (f->selected_window)->contents));
       fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
 
       mode_line_target = MODE_LINE_TITLE;
@@ -13497,69 +13412,6 @@ update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run)
 			       Tab-bars
  ***********************************************************************/
 
-/* Restore WINDOW as the selected window and its frame as the selected
-   frame.  If WINDOW is dead but the selected frame is live, make the
-   latter's selected window the selected window.  If both, WINDOW and
-   the selected frame, are dead, assign selected frame and window from
-   some arbitrary live frame.  Abort if no such frame can be found.  */
-static void
-restore_selected_window (Lisp_Object window)
-{
-  if (WINDOW_LIVE_P (window))
-    /* If WINDOW is live, make it the selected window and its frame's
-       selected window and set the selected frame to its frame.  */
-    {
-      selected_window = window;
-      selected_frame = XWINDOW (window)->frame;
-      FRAME_SELECTED_WINDOW (XFRAME (selected_frame)) = window;
-    }
-  else if (FRAMEP (selected_frame) && FRAME_LIVE_P (XFRAME (selected_frame)))
-    /* If WINDOW is dead but the selected frame is still live, make the
-       latter's selected window the selected one.  */
-    selected_window = FRAME_SELECTED_WINDOW (XFRAME (selected_frame));
-  else
-    /* If WINDOW and the selected frame are dead, choose some live,
-       non-child and non-tooltip frame as the new selected frame and
-       make its selected window the selected window.  */
-    {
-      Lisp_Object tail;
-      Lisp_Object frame UNINIT;
-
-      FOR_EACH_FRAME (tail, frame)
-	{
-	  struct frame *f = XFRAME (frame);
-
-	  if (!FRAME_PARENT_FRAME (f) && !FRAME_TOOLTIP_P (f))
-	    {
-	      selected_frame = frame;
-	      selected_window = FRAME_SELECTED_WINDOW (f);
-
-	      return;
-	    }
-	}
-
-      /* Abort if we cannot find a live frame.  */
-      emacs_abort ();
-    }
-}
-
-/* Restore WINDOW, if live, as its frame's selected window.  */
-static void
-restore_frame_selected_window (Lisp_Object window)
-{
-  if (WINDOW_LIVE_P (window))
-    /* If WINDOW is live, make it its frame's selected window.  If that
-       frame is the selected frame, make WINDOW the selected window as
-       well.  */
-    {
-      Lisp_Object frame = XWINDOW (window)->frame;
-
-      FRAME_SELECTED_WINDOW (XFRAME (frame)) = window;
-      if (EQ (frame, selected_frame))
-	selected_window = window;
-    }
-}
-
 /* Update the tab-bar item list for frame F.  This has to be done
    before we start to fill in any display lines.  Called from
    prepare_menu_bars.  If SAVE_MATCH_DATA, we must save
@@ -13582,11 +13434,8 @@ update_tab_bar (struct frame *f, bool save_match_data)
 
   if (do_update)
     {
-      Lisp_Object window;
-      struct window *w;
-
-      window = FRAME_SELECTED_WINDOW (f);
-      w = XWINDOW (window);
+      Lisp_Object window = FRAME_SELECTED_WINDOW (f);
+      struct window *w = XWINDOW (window);
 
       /* If the user has switched buffers or windows, we need to
 	 recompute to reflect the new bindings.  But we'll
@@ -13600,16 +13449,10 @@ update_tab_bar (struct frame *f, bool save_match_data)
 	  || update_mode_lines
 	  || window_buffer_changed (w))
 	{
-	  struct buffer *prev = current_buffer;
 	  specpdl_ref count = SPECPDL_INDEX ();
 	  Lisp_Object new_tab_bar;
           int new_n_tab_bar;
 
-	  /* Set current_buffer to the buffer of the selected
-	     window of the frame, so that we get the right local
-	     keymaps.  */
-	  set_buffer_internal_1 (XBUFFER (w->contents));
-
 	  /* Save match data, if we must.  */
 	  if (save_match_data)
 	    record_unwind_save_match_data ();
@@ -13621,20 +13464,8 @@ update_tab_bar (struct frame *f, bool save_match_data)
 	      specbind (Qoverriding_local_map, Qnil);
 	    }
 
-	  /* We must temporarily set the selected frame to this frame
-	     before calling tab_bar_items, because the calculation of
-	     the tab-bar keymap uses the selected frame (see
-	     `tab-bar-make-keymap' in tab-bar.el).  */
-	  eassert (EQ (selected_window,
-		       /* Since we only explicitly preserve selected_frame,
-			  check that selected_window would be redundant.  */
-		       XFRAME (selected_frame)->selected_window));
 #ifdef HAVE_WINDOW_SYSTEM
-	  Lisp_Object frame;
-	  record_unwind_protect (restore_selected_window, selected_window);
-	  XSETFRAME (frame, f);
-	  selected_frame = frame;
-	  selected_window = FRAME_SELECTED_WINDOW (f);
+	  with_window_selected (window);
 #endif
 
 	  /* Build desired tab-bar items from keymaps.  */
@@ -13657,7 +13488,6 @@ update_tab_bar (struct frame *f, bool save_match_data)
             }
 
 	  unbind_to (count, Qnil);
-	  set_buffer_internal_1 (prev);
 	}
     }
 }
@@ -14495,11 +14325,8 @@ update_tool_bar (struct frame *f, bool save_match_data)
 
   if (do_update)
     {
-      Lisp_Object window;
-      struct window *w;
-
-      window = FRAME_SELECTED_WINDOW (f);
-      w = XWINDOW (window);
+      Lisp_Object window = FRAME_SELECTED_WINDOW (f);
+      struct window *w = XWINDOW (window);
 
       /* If the user has switched buffers or windows, we need to
 	 recompute to reflect the new bindings.  But we'll
@@ -14513,16 +14340,10 @@ update_tool_bar (struct frame *f, bool save_match_data)
 	  || update_mode_lines
 	  || window_buffer_changed (w))
 	{
-	  struct buffer *prev = current_buffer;
 	  specpdl_ref count = SPECPDL_INDEX ();
-	  Lisp_Object frame, new_tool_bar;
+	  Lisp_Object new_tool_bar;
           int new_n_tool_bar;
 
-	  /* Set current_buffer to the buffer of the selected
-	     window of the frame, so that we get the right local
-	     keymaps.  */
-	  set_buffer_internal_1 (XBUFFER (w->contents));
-
 	  /* Save match data, if we must.  */
 	  if (save_match_data)
 	    record_unwind_save_match_data ();
@@ -14534,18 +14355,7 @@ update_tool_bar (struct frame *f, bool save_match_data)
 	      specbind (Qoverriding_local_map, Qnil);
 	    }
 
-	  /* We must temporarily set the selected frame to this frame
-	     before calling tool_bar_items, because the calculation of
-	     the tool-bar keymap uses the selected frame (see
-	     `tool-bar-make-keymap' in tool-bar.el).  */
-	  eassert (EQ (selected_window,
-		       /* Since we only explicitly preserve selected_frame,
-			  check that selected_window would be redundant.  */
-		       XFRAME (selected_frame)->selected_window));
-	  record_unwind_protect (restore_selected_window, selected_window);
-	  XSETFRAME (frame, f);
-	  selected_frame = frame;
-	  selected_window = FRAME_SELECTED_WINDOW (f);
+	  with_window_selected (window);
 
 	  /* Build desired tool-bar items from keymaps.  */
           new_tool_bar
@@ -14567,7 +14377,6 @@ update_tool_bar (struct frame *f, bool save_match_data)
             }
 
 	  unbind_to (count, Qnil);
-	  set_buffer_internal_1 (prev);
 	}
     }
 }
@@ -26075,15 +25884,8 @@ redisplay_mode_lines (Lisp_Object window, bool force)
 static int
 display_mode_lines (struct window *w)
 {
-  Lisp_Object old_selected_window = selected_window;
-  Lisp_Object new_frame = w->frame;
-  specpdl_ref count = SPECPDL_INDEX ();
   int n = 0;
 
-  record_unwind_protect (restore_selected_window, selected_window);
-  record_unwind_protect
-    (restore_frame_selected_window, XFRAME (new_frame)->selected_window);
-
   if (window_wants_mode_line (w))
     {
       Lisp_Object window;
@@ -26101,12 +25903,6 @@ display_mode_lines (struct window *w)
 	wset_mode_line_help_echo (w, Qnil);
     }
 
-  selected_frame = new_frame;
-  /* FIXME: If we were to allow the mode-line's computation changing the buffer
-     or window's point, then we'd need select_window_1 here as well.  */
-  XSETWINDOW (selected_window, w);
-  XFRAME (new_frame)->selected_window = selected_window;
-
   /* These will be set while the mode line specs are processed.  */
   line_number_displayed = false;
   w->column_number_displayed = -1;
@@ -26115,7 +25911,7 @@ display_mode_lines (struct window *w)
     {
       Lisp_Object window_mode_line_format
 	= window_parameter (w, Qmode_line_format);
-      struct window *sel_w = XWINDOW (old_selected_window);
+      struct window *sel_w = XWINDOW (selected_window);
 
       /* Select mode line face based on the real selected window.  */
       display_mode_line (w,
@@ -26150,8 +25946,6 @@ display_mode_lines (struct window *w)
       ++n;
     }
 
-  unbind_to (count, Qnil);
-
   if (n > 0)
     w->must_be_updated_p = true;
   return n;
@@ -26167,6 +25961,7 @@ display_mode_lines (struct window *w)
 static int
 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
 {
+  Lisp_Object window;
   struct it it;
   struct face *face;
   specpdl_ref count = SPECPDL_INDEX ();
@@ -26191,9 +25986,11 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
      made up of many separate strings.  */
   it.paragraph_embedding = L2R;
 
+  XSETWINDOW (window, w);
+  with_window_selected (window);
+
   record_unwind_protect (unwind_format_mode_line,
-			 format_mode_line_unwind_data (NULL, NULL,
-						       Qnil, false));
+			 format_mode_line_unwind_data (false));
 
   /* Temporarily make frame's keyboard the current kboard so that
      kboard-local variables in the mode_line_format will get the right
@@ -26931,7 +26728,6 @@ DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
   struct it it;
   int len;
   struct window *w;
-  struct buffer *old_buffer = NULL;
   int face_id;
   bool no_props = FIXNUMP (face);
   specpdl_ref count = SPECPDL_INDEX ();
@@ -26964,17 +26760,15 @@ DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
     : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
     : DEFAULT_FACE_ID;
 
-  old_buffer = current_buffer;
+  with_window_selected (window);
 
   /* Save things including mode_line_proptrans_alist,
      and set that to nil so that we don't alter the outer value.  */
   record_unwind_protect (unwind_format_mode_line,
-			 format_mode_line_unwind_data
-			   (XFRAME (WINDOW_FRAME (w)),
-			    old_buffer, selected_window, true));
+			 format_mode_line_unwind_data (true));
   mode_line_proptrans_alist = Qnil;
 
-  Fselect_window (window, Qt);
+  /* This should be covered by 'unwind_with_window_selected'.  */
   set_buffer_internal_1 (XBUFFER (buffer));
 
   init_iterator (&it, w, -1, -1, NULL, face_id);