]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix wrong handling of minibuffers when frames get iconified/made invisible
authorAlan Mackenzie <acm@muc.de>
Thu, 6 May 2021 10:48:14 +0000 (10:48 +0000)
committerAlan Mackenzie <acm@muc.de>
Thu, 6 May 2021 10:48:14 +0000 (10:48 +0000)
This should fix bug #47766.

* lisp/window.el (window-deletable-p): Add a quote where it was missing from
minibuffer-follows-selected-frame.

* src/frame.c (check_minibuf_window): Delete the function.
(delete_frame): In place of calling check_minibuf_window, call
move_minibuffers_onto_frame, possibly to move minibuffers onto the new current
frame.
(Fmake_frame_invisible, Ficonify_frame): Remove calls to check_minibuf_window.

* src/minibuf.c (Factive_minibuffer_window): Search the frames for the active
minibuffer rather than just assuming minibuf_window has been correctly
updated.

lisp/window.el
src/frame.c
src/minibuf.c

index cf5752113d5667037e3d843c543dcaf6135ecc8c..bba4992ca24cdf73869a143f08f07f2aef41f7f2 100644 (file)
@@ -4117,7 +4117,7 @@ frame can be safely deleted."
                  (let ((minibuf (active-minibuffer-window)))
                    (and minibuf (eq frame (window-frame minibuf))
                          (not (eq (default-toplevel-value
-                                    minibuffer-follows-selected-frame)
+                                    'minibuffer-follows-selected-frame)
                                   t)))))
        'frame))
      ((window-minibuffer-p window)
index 738bfe9a5c8f91e3a35c85e7fab8fb0837eb002e..cb9d4f52109db14f26329642b8ac46d7b3f45995 100644 (file)
@@ -1929,52 +1929,6 @@ other_frames (struct frame *f, bool invisible, bool force)
   return false;
 }
 
-/* Make sure that minibuf_window doesn't refer to FRAME's minibuffer
-   window.  Preferably use the selected frame's minibuffer window
-   instead.  If the selected frame doesn't have one, get some other
-   frame's minibuffer window.  SELECT non-zero means select the new
-   minibuffer window.  */
-static void
-check_minibuf_window (Lisp_Object frame, int select)
-{
-  struct frame *f = decode_live_frame (frame);
-
-  XSETFRAME (frame, f);
-
-  if (WINDOWP (minibuf_window) && EQ (f->minibuffer_window, minibuf_window))
-    {
-      Lisp_Object frames, this, window = make_fixnum (0);
-
-      if (!EQ (frame, selected_frame)
-         && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame)))
-       window = FRAME_MINIBUF_WINDOW (XFRAME (selected_frame));
-      else
-       FOR_EACH_FRAME (frames, this)
-         {
-           if (!EQ (this, frame) && FRAME_HAS_MINIBUF_P (XFRAME (this)))
-             {
-               window = FRAME_MINIBUF_WINDOW (XFRAME (this));
-               break;
-             }
-         }
-
-      /* Don't abort if no window was found (Bug#15247).  */
-      if (WINDOWP (window))
-       {
-         /* Use set_window_buffer instead of Fset_window_buffer (see
-            discussion of bug#11984, bug#12025, bug#12026).  */
-         set_window_buffer (window, XWINDOW (minibuf_window)->contents, 0, 0);
-         minibuf_window = window;
-
-         /* SELECT non-zero usually means that FRAME's minibuffer
-            window was selected; select the new one.  */
-         if (select)
-           Fselect_window (minibuf_window, Qnil);
-       }
-    }
-}
-
-
 /**
  * delete_frame:
  *
@@ -1989,7 +1943,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
   struct frame *sf;
   struct kboard *kb;
   Lisp_Object frames, frame1;
-  int minibuffer_selected, is_tooltip_frame;
+  int is_tooltip_frame;
   bool nochild = !FRAME_PARENT_FRAME (f);
   Lisp_Object minibuffer_child_frame = Qnil;
 
@@ -2097,7 +2051,6 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
 
   /* At this point, we are committed to deleting the frame.
      There is no more chance for errors to prevent it.  */
-  minibuffer_selected = EQ (minibuf_window, selected_window);
   sf = SELECTED_FRAME ();
   /* Don't let the frame remain selected.  */
   if (f == sf)
@@ -2155,9 +2108,10 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
       do_switch_frame (frame1, 0, 1, Qnil);
       sf = SELECTED_FRAME ();
     }
-
-  /* Don't allow minibuf_window to remain on a deleted frame.  */
-  check_minibuf_window (frame, minibuffer_selected);
+  else
+    /* Ensure any minibuffers on FRAME are moved onto the selected
+       frame.  */
+    move_minibuffers_onto_frame (f, true);
 
   /* Don't let echo_area_window to remain on a deleted frame.  */
   if (EQ (f->minibuffer_window, echo_area_window))
@@ -2788,9 +2742,6 @@ displayed in the terminal.  */)
   if (NILP (force) && !other_frames (f, true, false))
     error ("Attempt to make invisible the sole visible or iconified frame");
 
-  /* Don't allow minibuf_window to remain on an invisible frame.  */
-  check_minibuf_window (frame, EQ (minibuf_window, selected_window));
-
   if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook)
     FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false);
 
@@ -2833,9 +2784,6 @@ for how to proceed.  */)
     }
 #endif /* HAVE_WINDOW_SYSTEM */
 
-  /* Don't allow minibuf_window to remain on an iconified frame.  */
-  check_minibuf_window (frame, EQ (minibuf_window, selected_window));
-
   if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->iconify_frame_hook)
     FRAME_TERMINAL (f)->iconify_frame_hook (f);
 
index c4482d7f1ee1ead2c1c80307b1b9d6f4e5024aaa..bc7d43939854bd24b886cecd0dadd2e9eb9e58ed 100644 (file)
@@ -212,7 +212,23 @@ DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
        doc: /* Return the currently active minibuffer window, or nil if none.  */)
      (void)
 {
-  return minibuf_level ? minibuf_window : Qnil;
+  Lisp_Object frames, frame;
+  struct frame *f;
+  Lisp_Object innermost_MB;
+
+  if (!minibuf_level)
+    return Qnil;
+
+  innermost_MB = nth_minibuffer (minibuf_level);
+  FOR_EACH_FRAME (frames, frame)
+    {
+      f = XFRAME (frame);
+      if (FRAME_LIVE_P (f)
+         && WINDOW_LIVE_P (f->minibuffer_window)
+         && EQ (XWINDOW (f->minibuffer_window)->contents, innermost_MB))
+       return f->minibuffer_window;
+    }
+  return minibuf_window;       /* "Can't happen." */
 }
 
 DEFUN ("set-minibuffer-window", Fset_minibuffer_window,