From bfff644518c1214eb5e037c7ff426af1e08628b5 Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Mon, 26 Aug 2013 14:39:08 +0200 Subject: [PATCH] New function check_minibuf_window to fix bug#15183. * frame.c (check_minibuf_window): New function. (delete_frame, Fmake_frame_invisible, Ficonify_frame): Call check_minibuf_window (Bug#15183). --- src/ChangeLog | 6 ++++ src/frame.c | 81 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 6408397c13e..a017eaa62f0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2013-08-26 Martin Rudalics + + * frame.c (check_minibuf_window): New function. + (delete_frame, Fmake_frame_invisible, Ficonify_frame): Call + check_minibuf_window (Bug#15183). + 2013-08-26 Dmitry Antipov * window.h (struct window): Replace last_cursor with last_cursor_vpos diff --git a/src/frame.c b/src/frame.c index 5ee001f4d98..4855734c2fc 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1110,6 +1110,51 @@ other_visible_frames (struct frame *f) return 0; } +/* 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); + + if (WINDOWP (minibuf_window) && EQ (f->minibuffer_window, minibuf_window)) + { + Lisp_Object frames, this, window; + + 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; + } + } + + if (!WINDOWP (window)) + emacs_abort (); + else + { + /* 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. When FORCE equals Qnoelisp, delete FRAME unconditionally. x_connection_closed and delete_terminal use this. Any other value of FORCE implements the semantics @@ -1244,19 +1289,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force) } /* Don't allow minibuf_window to remain on a deleted frame. */ - if (EQ (f->minibuffer_window, minibuf_window)) - { - /* Use set_window_buffer instead of Fset_window_buffer (see - discussion of bug#11984, bug#12025, bug#12026). */ - set_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->contents, 0, 0); - minibuf_window = sf->minibuffer_window; - - /* If the dying minibuffer window was selected, - select the new one. */ - if (minibuffer_selected) - Fselect_window (minibuf_window, Qnil); - } + check_minibuf_window (frame, minibuffer_selected); /* Don't let echo_area_window to remain on a deleted frame. */ if (EQ (f->minibuffer_window, echo_area_window)) @@ -1683,16 +1716,8 @@ displayed in the terminal. */) if (NILP (force) && !other_visible_frames (f)) error ("Attempt to make invisible the sole visible or iconified frame"); - /* Don't allow minibuf_window to remain on a deleted frame. */ - if (EQ (f->minibuffer_window, minibuf_window)) - { - struct frame *sf = XFRAME (selected_frame); - /* Use set_window_buffer instead of Fset_window_buffer (see - discussion of bug#11984, bug#12025, bug#12026). */ - set_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->contents, 0, 0); - minibuf_window = sf->minibuffer_window; - } + /* Don't allow minibuf_window to remain on an invisible frame. */ + check_minibuf_window (frame, EQ (minibuf_window, selected_window)); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -1715,15 +1740,7 @@ If omitted, FRAME defaults to the currently selected frame. */) struct frame *f = decode_live_frame (frame); /* Don't allow minibuf_window to remain on an iconified frame. */ - if (EQ (f->minibuffer_window, minibuf_window)) - { - struct frame *sf = XFRAME (selected_frame); - /* Use set_window_buffer instead of Fset_window_buffer (see - discussion of bug#11984, bug#12025, bug#12026). */ - set_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->contents, 0, 0); - minibuf_window = sf->minibuffer_window; - } + check_minibuf_window (frame, EQ (minibuf_window, selected_window)); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM -- 2.39.2