aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mackenzie2021-05-06 10:48:14 +0000
committerAlan Mackenzie2021-05-06 10:48:14 +0000
commitc873d16af61ae9b956c6dd6d9e50ebad2bb7666e (patch)
treeaf1641eab3b416ccd8c6ce00d645fb9ad9399ea6 /src
parent9e0fc5321b6be3b9242f2668a37a95057b4d1e0b (diff)
downloademacs-c873d16af61ae9b956c6dd6d9e50ebad2bb7666e.tar.gz
emacs-c873d16af61ae9b956c6dd6d9e50ebad2bb7666e.zip
Fix wrong handling of minibuffers when frames get iconified/made invisible
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.
Diffstat (limited to 'src')
-rw-r--r--src/frame.c62
-rw-r--r--src/minibuf.c18
2 files changed, 22 insertions, 58 deletions
diff --git a/src/frame.c b/src/frame.c
index 738bfe9a5c8..cb9d4f52109 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1929,52 +1929,6 @@ other_frames (struct frame *f, bool invisible, bool force)
1929 return false; 1929 return false;
1930} 1930}
1931 1931
1932/* Make sure that minibuf_window doesn't refer to FRAME's minibuffer
1933 window. Preferably use the selected frame's minibuffer window
1934 instead. If the selected frame doesn't have one, get some other
1935 frame's minibuffer window. SELECT non-zero means select the new
1936 minibuffer window. */
1937static void
1938check_minibuf_window (Lisp_Object frame, int select)
1939{
1940 struct frame *f = decode_live_frame (frame);
1941
1942 XSETFRAME (frame, f);
1943
1944 if (WINDOWP (minibuf_window) && EQ (f->minibuffer_window, minibuf_window))
1945 {
1946 Lisp_Object frames, this, window = make_fixnum (0);
1947
1948 if (!EQ (frame, selected_frame)
1949 && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame)))
1950 window = FRAME_MINIBUF_WINDOW (XFRAME (selected_frame));
1951 else
1952 FOR_EACH_FRAME (frames, this)
1953 {
1954 if (!EQ (this, frame) && FRAME_HAS_MINIBUF_P (XFRAME (this)))
1955 {
1956 window = FRAME_MINIBUF_WINDOW (XFRAME (this));
1957 break;
1958 }
1959 }
1960
1961 /* Don't abort if no window was found (Bug#15247). */
1962 if (WINDOWP (window))
1963 {
1964 /* Use set_window_buffer instead of Fset_window_buffer (see
1965 discussion of bug#11984, bug#12025, bug#12026). */
1966 set_window_buffer (window, XWINDOW (minibuf_window)->contents, 0, 0);
1967 minibuf_window = window;
1968
1969 /* SELECT non-zero usually means that FRAME's minibuffer
1970 window was selected; select the new one. */
1971 if (select)
1972 Fselect_window (minibuf_window, Qnil);
1973 }
1974 }
1975}
1976
1977
1978/** 1932/**
1979 * delete_frame: 1933 * delete_frame:
1980 * 1934 *
@@ -1989,7 +1943,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1989 struct frame *sf; 1943 struct frame *sf;
1990 struct kboard *kb; 1944 struct kboard *kb;
1991 Lisp_Object frames, frame1; 1945 Lisp_Object frames, frame1;
1992 int minibuffer_selected, is_tooltip_frame; 1946 int is_tooltip_frame;
1993 bool nochild = !FRAME_PARENT_FRAME (f); 1947 bool nochild = !FRAME_PARENT_FRAME (f);
1994 Lisp_Object minibuffer_child_frame = Qnil; 1948 Lisp_Object minibuffer_child_frame = Qnil;
1995 1949
@@ -2097,7 +2051,6 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
2097 2051
2098 /* At this point, we are committed to deleting the frame. 2052 /* At this point, we are committed to deleting the frame.
2099 There is no more chance for errors to prevent it. */ 2053 There is no more chance for errors to prevent it. */
2100 minibuffer_selected = EQ (minibuf_window, selected_window);
2101 sf = SELECTED_FRAME (); 2054 sf = SELECTED_FRAME ();
2102 /* Don't let the frame remain selected. */ 2055 /* Don't let the frame remain selected. */
2103 if (f == sf) 2056 if (f == sf)
@@ -2155,9 +2108,10 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
2155 do_switch_frame (frame1, 0, 1, Qnil); 2108 do_switch_frame (frame1, 0, 1, Qnil);
2156 sf = SELECTED_FRAME (); 2109 sf = SELECTED_FRAME ();
2157 } 2110 }
2158 2111 else
2159 /* Don't allow minibuf_window to remain on a deleted frame. */ 2112 /* Ensure any minibuffers on FRAME are moved onto the selected
2160 check_minibuf_window (frame, minibuffer_selected); 2113 frame. */
2114 move_minibuffers_onto_frame (f, true);
2161 2115
2162 /* Don't let echo_area_window to remain on a deleted frame. */ 2116 /* Don't let echo_area_window to remain on a deleted frame. */
2163 if (EQ (f->minibuffer_window, echo_area_window)) 2117 if (EQ (f->minibuffer_window, echo_area_window))
@@ -2788,9 +2742,6 @@ displayed in the terminal. */)
2788 if (NILP (force) && !other_frames (f, true, false)) 2742 if (NILP (force) && !other_frames (f, true, false))
2789 error ("Attempt to make invisible the sole visible or iconified frame"); 2743 error ("Attempt to make invisible the sole visible or iconified frame");
2790 2744
2791 /* Don't allow minibuf_window to remain on an invisible frame. */
2792 check_minibuf_window (frame, EQ (minibuf_window, selected_window));
2793
2794 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook) 2745 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook)
2795 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false); 2746 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false);
2796 2747
@@ -2833,9 +2784,6 @@ for how to proceed. */)
2833 } 2784 }
2834#endif /* HAVE_WINDOW_SYSTEM */ 2785#endif /* HAVE_WINDOW_SYSTEM */
2835 2786
2836 /* Don't allow minibuf_window to remain on an iconified frame. */
2837 check_minibuf_window (frame, EQ (minibuf_window, selected_window));
2838
2839 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->iconify_frame_hook) 2787 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->iconify_frame_hook)
2840 FRAME_TERMINAL (f)->iconify_frame_hook (f); 2788 FRAME_TERMINAL (f)->iconify_frame_hook (f);
2841 2789
diff --git a/src/minibuf.c b/src/minibuf.c
index c4482d7f1ee..bc7d4393985 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -212,7 +212,23 @@ DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
212 doc: /* Return the currently active minibuffer window, or nil if none. */) 212 doc: /* Return the currently active minibuffer window, or nil if none. */)
213 (void) 213 (void)
214{ 214{
215 return minibuf_level ? minibuf_window : Qnil; 215 Lisp_Object frames, frame;
216 struct frame *f;
217 Lisp_Object innermost_MB;
218
219 if (!minibuf_level)
220 return Qnil;
221
222 innermost_MB = nth_minibuffer (minibuf_level);
223 FOR_EACH_FRAME (frames, frame)
224 {
225 f = XFRAME (frame);
226 if (FRAME_LIVE_P (f)
227 && WINDOW_LIVE_P (f->minibuffer_window)
228 && EQ (XWINDOW (f->minibuffer_window)->contents, innermost_MB))
229 return f->minibuffer_window;
230 }
231 return minibuf_window; /* "Can't happen." */
216} 232}
217 233
218DEFUN ("set-minibuffer-window", Fset_minibuffer_window, 234DEFUN ("set-minibuffer-window", Fset_minibuffer_window,