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.
This commit is contained in:
@@ -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)
|
||||
|
||||
62
src/frame.c
62
src/frame.c
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user