From f608b4b93c061e10603551a7d189637f49d90a62 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Sat, 8 May 2021 12:10:00 +0000 Subject: [PATCH] Prevent the selected window being a dead mini-window when switching frames This fixes bug #48249 and also a situation where, with recursive minibuffers enabled and minibuffer-follows-selected-frame t, switching frames when a minibuffer was open would leave the mini-window selected on the old frame. * lisp/window.el (record-window-buffer): Add extra parameter DO-MINIBUF, and amend the code such that minibuffers only get processed when that parameter is non-nil. * src/minibuf.c (zip_minibuffer_stacks, read_minibuf): Call Qrecord_window_buffer with the new argument set to Qt. (move_minibuffers_onto_frame): Set the selected window on the old frame when this would otherwise remain the mini-window. --- lisp/window.el | 18 ++++++++++-------- src/minibuf.c | 14 +++++++++++--- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/lisp/window.el b/lisp/window.el index bba4992ca24..db62d3308fb 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -4361,9 +4361,12 @@ This may be a useful alternative binding for \\[delete-other-windows] ;; The following function is called by `set-window-buffer' _before_ it ;; replaces the buffer of the argument window with the new buffer. -(defun record-window-buffer (&optional window) +(defun record-window-buffer (&optional window do-minibuf) "Record WINDOW's buffer. -WINDOW must be a live window and defaults to the selected one." +WINDOW must be a live window and defaults to the selected one. + +If WINDOW is a minibuffer, it will only be recorded if DO-MINIBUF +is non-nil." (let* ((window (window-normalize-window window t)) (buffer (window-buffer window)) (entry (assq buffer (window-prev-buffers window)))) @@ -4371,14 +4374,13 @@ WINDOW must be a live window and defaults to the selected one." ;; `switch-to-prev-buffer' and `switch-to-next-buffer'. (set-window-next-buffers window nil) - (when entry - ;; Remove all entries for BUFFER from WINDOW's previous buffers. - (set-window-prev-buffers - window (assq-delete-all buffer (window-prev-buffers window)))) - ;; Don't record insignificant buffers. (when (or (not (eq (aref (buffer-name buffer) 0) ?\s)) - (minibufferp buffer)) + (and do-minibuf (minibufferp buffer))) + (when entry + ;; Remove all entries for BUFFER from WINDOW's previous buffers. + (set-window-prev-buffers + window (assq-delete-all buffer (window-prev-buffers window)))) ;; Add an entry for buffer to WINDOW's previous buffers. (with-current-buffer buffer (let ((start (window-start window)) diff --git a/src/minibuf.c b/src/minibuf.c index bc7d4393985..167aece973a 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -163,9 +163,9 @@ zip_minibuffer_stacks (Lisp_Object dest_window, Lisp_Object source_window) } if (live_minibuffer_p (dw->contents)) - call1 (Qrecord_window_buffer, dest_window); + call2 (Qrecord_window_buffer, dest_window, Qt); if (live_minibuffer_p (sw->contents)) - call1 (Qrecord_window_buffer, source_window); + call2 (Qrecord_window_buffer, source_window, Qt); acc = merge_c (dw->prev_buffers, sw->prev_buffers, minibuffer_ent_greater); @@ -204,6 +204,14 @@ move_minibuffers_onto_frame (struct frame *of, bool for_deletion) zip_minibuffer_stacks (f->minibuffer_window, of->minibuffer_window); if (for_deletion && XFRAME (MB_frame) != of) MB_frame = selected_frame; + if (!for_deletion + && MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of)))) + { + Lisp_Object old_frame; + XSETFRAME (old_frame, of); + Fset_frame_selected_window (old_frame, + Fframe_first_window (old_frame), Qnil); + } } } @@ -672,7 +680,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, } MB_frame = XWINDOW (XFRAME (selected_frame)->minibuffer_window)->frame; if (live_minibuffer_p (XWINDOW (minibuf_window)->contents)) - call1 (Qrecord_window_buffer, minibuf_window); + call2 (Qrecord_window_buffer, minibuf_window, Qt); record_unwind_protect_void (minibuffer_unwind); record_unwind_protect (restore_window_configuration, -- 2.39.2