[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 7c2ebf6: Prevent open minibuffers getting lost when their frame g
From: |
Alan Mackenzie |
Subject: |
master 7c2ebf6: Prevent open minibuffers getting lost when their frame gets deleted |
Date: |
Sun, 21 Mar 2021 12:57:50 -0400 (EDT) |
branch: master
commit 7c2ebf6e23663fdc7b1880a4d7caeadc8c47c00e
Author: Alan Mackenzie <acm@muc.de>
Commit: Alan Mackenzie <acm@muc.de>
Prevent open minibuffers getting lost when their frame gets deleted
This happened with minibuffer-follows-selected-frame set to t.
* doc/emacs/mini.texi (Basic Minibuffer): State where a command's action
takes
place when a minibuffer's frame has been deleted.
* lisp/window.el (window--before-delete-windows, record-window-buffer): Take
into account that minibuffers are now recorded on w->prev_buffers field.
* src/fns.c (merge_c): New version of `merge' taking a C function, rather
than
a Lisp function as the comparison function.
* src/frame.c (do_switch_frame): Pass arguments sf and for_deletion to
move_minibuffers_onnto_frame.
* src/lisp.h (top level): Declare merge_c and
move_minibuffers_onto_selected_frame.
* src/minibuf.c (MB_frame): New Lisp_Object recording the minibuffer's
frame.
(choose_minibuf_frame): Remove all code except that which sets
minibuf_window
to the current frame's minibuffer.
(minibuffer_ent_greater): New comparison function, passed to merge_c.
(zip_minibuffer_stacks): New function.
(move_minibuffers_onto_frame): Renamed from `move_minibuffer_onto_frame'
given
two arguments, the old frame and for_deletion, and simplified. Minibuffers
are now stacked in the mini-window's ->prev_buffers field.
(read_minibuf): Several detailed amendments.
(exp_MB_frame): New Lisp_Object, the expired minibuffer's frame.
(read_minibuf_unwind): Search for the expired minibuffer's frame, rather
than
taking it from (unreliable) variables. Switch temporarily to this frame for
tidying up operations.
(minibuffer_unwind): New function which pops a stacked minibuffer.
(syms_of_minibuf): Call staticpro for the two new Lisp variables.
* src/window.c (Fset_window_configuration): Don't record minibuffers with
record-window-buffer.
* src/xdisp.c (gui_consider_frame_title): Remove redundant Fselect_window,
which caused an unwanted frame switch. Amend the arguments to
format_mode_line_unwind_data to match.
---
doc/emacs/mini.texi | 4 +-
lisp/window.el | 5 +-
src/fns.c | 46 +++++++++
src/frame.c | 2 +-
src/lisp.h | 3 +-
src/minibuf.c | 292 +++++++++++++++++++++++++++++++++-------------------
src/window.c | 3 +-
src/xdisp.c | 3 +-
8 files changed, 242 insertions(+), 116 deletions(-)
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index 9c1b975..d0865c5 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -82,7 +82,9 @@ after a recursive minibuffer has been opened in the current
command
(@pxref{Recursive Mini,,, elisp}). This option is mainly to retain
(approximately) the behavior prior to Emacs 28.1. Note that the
effect of the command, when you finally finish using the minibuffer,
-always takes place in the frame where you first opened it.
+always takes place in the frame where you first opened it. The sole
+exception is that when that frame no longer exists, the action takes
+place in the currently selected frame.
@node Minibuffer File
@section Minibuffers for File Names
diff --git a/lisp/window.el b/lisp/window.el
index cfd9876..f27631b 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4158,7 +4158,7 @@ returned by `window-start' and `window-point'
respectively.
This function is called only if `switch-to-buffer-preserve-window-point'
evaluates non-nil."
- (dolist (win (window-list))
+ (dolist (win (window-list nil 'no-minibuf))
(let* ((buf (window-buffer (or window win)))
(start (window-start win))
(pos (window-point win))
@@ -4416,7 +4416,8 @@ WINDOW must be a live window and defaults to the selected
one."
window (assq-delete-all buffer (window-prev-buffers window))))
;; Don't record insignificant buffers.
- (unless (eq (aref (buffer-name buffer) 0) ?\s)
+ (when (or (not (eq (aref (buffer-name buffer) 0) ?\s))
+ (minibufferp buffer))
;; Add an entry for buffer to WINDOW's previous buffers.
(with-current-buffer buffer
(let ((start (window-start window))
diff --git a/src/fns.c b/src/fns.c
index 766e767..2cd59c8 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2279,6 +2279,52 @@ merge (Lisp_Object org_l1, Lisp_Object org_l2,
Lisp_Object pred)
}
}
+Lisp_Object
+merge_c (Lisp_Object org_l1, Lisp_Object org_l2, bool (*less) (Lisp_Object,
Lisp_Object))
+{
+ Lisp_Object l1 = org_l1;
+ Lisp_Object l2 = org_l2;
+ Lisp_Object tail = Qnil;
+ Lisp_Object value = Qnil;
+
+ while (1)
+ {
+ if (NILP (l1))
+ {
+ if (NILP (tail))
+ return l2;
+ Fsetcdr (tail, l2);
+ return value;
+ }
+ if (NILP (l2))
+ {
+ if (NILP (tail))
+ return l1;
+ Fsetcdr (tail, l1);
+ return value;
+ }
+
+ Lisp_Object tem;
+ if (less (Fcar (l1), Fcar (l2)))
+ {
+ tem = l1;
+ l1 = Fcdr (l1);
+ org_l1 = l1;
+ }
+ else
+ {
+ tem = l2;
+ l2 = Fcdr (l2);
+ org_l2 = l2;
+ }
+ if (NILP (tail))
+ value = tem;
+ else
+ Fsetcdr (tail, tem);
+ tail = tem;
+ }
+}
+
/* This does not check for quits. That is safe since it must terminate. */
diff --git a/src/frame.c b/src/frame.c
index cfdf3b6..66ae494 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1487,7 +1487,7 @@ do_switch_frame (Lisp_Object frame, int track, int
for_deletion, Lisp_Object nor
#endif
internal_last_event_frame = Qnil;
- move_minibuffer_onto_frame ();
+ move_minibuffers_onto_frame (sf, for_deletion);
return frame;
}
diff --git a/src/lisp.h b/src/lisp.h
index b95f389..c67c8b0 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3610,6 +3610,7 @@ extern void validate_subarray (Lisp_Object, Lisp_Object,
Lisp_Object,
extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t);
extern Lisp_Object merge (Lisp_Object, Lisp_Object, Lisp_Object);
+extern Lisp_Object merge_c (Lisp_Object, Lisp_Object, bool (*) (Lisp_Object,
Lisp_Object));
extern Lisp_Object do_yes_or_no_p (Lisp_Object);
extern int string_version_cmp (Lisp_Object, Lisp_Object);
extern Lisp_Object concat2 (Lisp_Object, Lisp_Object);
@@ -4348,7 +4349,7 @@ extern void clear_regexp_cache (void);
extern Lisp_Object Vminibuffer_list;
extern Lisp_Object last_minibuf_string;
-extern void move_minibuffer_onto_frame (void);
+extern void move_minibuffers_onto_frame (struct frame *, bool);
extern bool is_minibuffer (EMACS_INT, Lisp_Object);
extern EMACS_INT this_minibuffer_depth (Lisp_Object);
extern EMACS_INT minibuf_level;
diff --git a/src/minibuf.c b/src/minibuf.c
index 4b1f4b1..d58924a 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -59,6 +59,12 @@ Lisp_Object last_minibuf_string;
static Lisp_Object minibuf_prompt;
+/* The frame containinug the most recently opened Minibuffer. This is
+ used only when `minibuffer-follows-selected-frame' is neither nil
+ nor t. */
+
+static Lisp_Object MB_frame;
+
/* Width of current mini-buffer prompt. Only set after display_line
of the line that contains the prompt. */
@@ -67,6 +73,7 @@ static ptrdiff_t minibuf_prompt_width;
static Lisp_Object nth_minibuffer (EMACS_INT depth);
static EMACS_INT minibuf_c_loop_level (EMACS_INT depth);
static void set_minibuffer_mode (Lisp_Object buf, EMACS_INT depth);
+static bool live_minibuffer_p (Lisp_Object);
/* Return TRUE when a frame switch causes a minibuffer on the old
@@ -78,6 +85,7 @@ minibuf_follows_frame (void)
Qt);
}
+#if 0
/* Return TRUE when a minibuffer always remains on the frame where it
was first invoked. */
static bool
@@ -85,6 +93,7 @@ minibuf_stays_put (void)
{
return NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame));
}
+#endif
/* Return TRUE when opening a (recursive) minibuffer causes
minibuffers on other frames to move to the selected frame. */
@@ -112,84 +121,85 @@ choose_minibuf_frame (void)
emacs_abort ();
minibuf_window = sf->minibuffer_window;
- /* If we've still got another minibuffer open, use its mini-window
- instead. */
- if (minibuf_level > 1 && minibuf_stays_put ())
- {
- Lisp_Object buffer = get_minibuffer (minibuf_level);
- Lisp_Object tail, frame;
-
- FOR_EACH_FRAME (tail, frame)
- if (EQ (XWINDOW (XFRAME (frame)->minibuffer_window)->contents,
- buffer))
- {
- minibuf_window = XFRAME (frame)->minibuffer_window;
- break;
- }
- }
}
+}
- if (minibuf_moves_frame_when_opened ()
- && FRAMEP (selected_frame)
- && FRAME_LIVE_P (XFRAME (selected_frame)))
- /* Make sure no other frame has a minibuffer as its selected window,
- because the text would not be displayed in it, and that would be
- confusing. Only allow the selected frame to do this,
- and that only if the minibuffer is active. */
- {
- Lisp_Object tail, frame;
- struct frame *of;
-
- FOR_EACH_FRAME (tail, frame)
- if (!EQ (frame, selected_frame)
- && minibuf_level > 1
- /* The frame's minibuffer can be on a different frame. */
- && ! EQ (XWINDOW ((of = XFRAME (frame))->minibuffer_window)->frame,
- selected_frame))
- {
- if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of))))
- Fset_frame_selected_window (frame, Fframe_first_window (frame),
- Qnil);
-
- if (!EQ (XWINDOW (of->minibuffer_window)->contents,
- nth_minibuffer (0)))
- set_window_buffer (of->minibuffer_window,
- nth_minibuffer (0), 0, 0);
- }
- }
+/* If ENT1 has a higher minibuffer index than ENT2, return true. More
+precisely, compare the buffer components of each window->prev_buffers
+entry. */
+static bool
+minibuffer_ent_greater (Lisp_Object ent1, Lisp_Object ent2)
+{
+ return this_minibuffer_depth (Fcar (ent1))
+ > this_minibuffer_depth (Fcar (ent2)) ;
}
-/* If `minibuffer_follows_selected_frame' is t and we have a
- minibuffer, move it from its current frame to the selected frame.
- This function is intended to be called from `do_switch_frame' in
- frame.c. */
-void move_minibuffer_onto_frame (void)
+/* Move the ordered "stack" of minibuffers from SOURCE_WINDOW to
+ DEST_WINDOW, interleaving those minibuffers with any in DEST_WINDOW
+ to produce an ordered combination. The ordering is by minibuffer
+ depth. A stack of minibuffers consists of the minibuffer currently
+ in DEST/SOURCE_WINDOW together with any recorded in the
+ ->prev_buffers field of the struct window. */
+static void
+zip_minibuffer_stacks (Lisp_Object dest_window, Lisp_Object source_window)
{
- if (!minibuf_level)
- return;
- if (!minibuf_follows_frame ())
- return;
- if (FRAMEP (selected_frame)
- && FRAME_LIVE_P (XFRAME (selected_frame))
- && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window))
+ struct window *dw = XWINDOW (dest_window);
+ struct window *sw = XWINDOW (source_window);
+ Lisp_Object acc;
+ Lisp_Object d_ent; /* Entry from dw->prev_buffers */
+
+ if (!live_minibuffer_p (dw->contents)
+ && NILP (dw->prev_buffers))
{
- EMACS_INT i;
- struct frame *sf = XFRAME (selected_frame);
- Lisp_Object old_frame = XWINDOW (minibuf_window)->frame;
- struct frame *of = XFRAME (old_frame);
+ set_window_buffer (dest_window, sw->contents, 0, 0);
+ Fset_window_start (dest_window, Fwindow_start (source_window), Qnil);
+ Fset_window_point (dest_window, Fwindow_point (source_window));
+ dw->prev_buffers = sw->prev_buffers;
+ set_window_buffer (source_window, get_minibuffer (0), 0, 0);
+ sw->prev_buffers = Qnil;
+ return;
+ }
- /* Stack up all the (recursively) open minibuffers on the selected
- mini_window. */
- for (i = 1; i <= minibuf_level; i++)
- set_window_buffer (sf->minibuffer_window, nth_minibuffer (i), 0, 0);
- minibuf_window = sf->minibuffer_window;
- if (of != sf)
- {
- Lisp_Object temp = get_minibuffer (0);
+ if (live_minibuffer_p (dw->contents))
+ call1 (Qrecord_window_buffer, dest_window);
+ if (live_minibuffer_p (sw->contents))
+ call1 (Qrecord_window_buffer, source_window);
- set_window_buffer (of->minibuffer_window, temp, 0, 0);
- set_minibuffer_mode (temp, 0);
- }
+ acc = merge_c (dw->prev_buffers, sw->prev_buffers, minibuffer_ent_greater);
+
+ if (!NILP (acc))
+ {
+ d_ent = Fcar (acc);
+ acc = Fcdr (acc);
+ set_window_buffer (dest_window, Fcar (d_ent), 0, 0);
+ Fset_window_start (dest_window, Fcar (Fcdr (d_ent)), Qnil);
+ Fset_window_point (dest_window, Fcar (Fcdr (Fcdr (d_ent))));
+ }
+ dw->prev_buffers = acc;
+ sw->prev_buffers = Qnil;
+ set_window_buffer (source_window, get_minibuffer (0), 0, 0);
+}
+
+/* If `minibuffer_follows_selected_frame' is t, or we're about to
+ delete a frame which potentially "contains" minibuffers, move them
+ from the old frame to the selected frame. This function is
+ intended to be called from `do_switch_frame' in frame.c. OF is the
+ old frame, FOR_DELETION is true if OF is about to be deleted. */
+void
+move_minibuffers_onto_frame (struct frame *of, bool for_deletion)
+{
+ struct frame *f = XFRAME (selected_frame);
+
+ minibuf_window = f->minibuffer_window;
+ if (!(minibuf_level
+ && (for_deletion || minibuf_follows_frame () || FRAME_INITIAL_P (of))))
+ return;
+ if (FRAME_LIVE_P (f)
+ && !EQ (f->minibuffer_window, of->minibuffer_window))
+ {
+ zip_minibuffer_stacks (f->minibuffer_window, of->minibuffer_window);
+ if (for_deletion && XFRAME (MB_frame) != of)
+ MB_frame = selected_frame;
}
}
@@ -221,6 +231,7 @@ without invoking the usual minibuffer commands. */)
/* Actual minibuffer invocation. */
static void read_minibuf_unwind (void);
+static void minibuffer_unwind (void);
static void run_exit_minibuf_hook (void);
@@ -544,7 +555,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial,
Lisp_Object prompt,
Lisp_Object histval;
Lisp_Object empty_minibuf;
- Lisp_Object dummy, frame;
specbind (Qminibuffer_default, defalt);
specbind (Qinhibit_read_only, Qnil);
@@ -626,17 +636,24 @@ read_minibuf (Lisp_Object map, Lisp_Object initial,
Lisp_Object prompt,
mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
if (minibuf_level > 1
+ && !EQ (XWINDOW (XFRAME (selected_frame)->minibuffer_window)->frame,
+ MB_frame)
&& minibuf_moves_frame_when_opened ()
- && (!minibuf_follows_frame ()
- || (!EQ (mini_frame, selected_frame))))
+ && (!minibuf_follows_frame ()))
{
- EMACS_INT i;
+ struct frame *of = XFRAME (MB_frame);
- /* Stack up the existing minibuffers on the current mini-window */
- for (i = 1; i < minibuf_level; i++)
- set_window_buffer (minibuf_window, nth_minibuffer (i), 0, 0);
+ zip_minibuffer_stacks (minibuf_window, of->minibuffer_window);
+ /* MB_frame's minibuffer can be on a different frame. */
+ if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of))))
+ Fset_frame_selected_window (MB_frame,
+ Fframe_first_window (MB_frame), Qnil);
}
+ MB_frame = XWINDOW (XFRAME (selected_frame)->minibuffer_window)->frame;
+ if (live_minibuffer_p (XWINDOW (minibuf_window)->contents))
+ call1 (Qrecord_window_buffer, minibuf_window);
+ record_unwind_protect_void (minibuffer_unwind);
record_unwind_protect (restore_window_configuration,
Fcons (Qt, Fcurrent_window_configuration (Qnil)));
@@ -771,23 +788,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial,
Lisp_Object prompt,
empty_minibuf = get_minibuffer (0);
set_minibuffer_mode (empty_minibuf, 0);
- FOR_EACH_FRAME (dummy, frame)
- {
- Lisp_Object root_window = Fframe_root_window (frame);
- Lisp_Object mini_window = XWINDOW (root_window)->next;
- Lisp_Object buffer;
-
- if (!NILP (mini_window) && !EQ (mini_window, minibuf_window)
- && !NILP (Fwindow_minibuffer_p (mini_window)))
- {
- buffer = XWINDOW (mini_window)->contents;
- if (!live_minibuffer_p (buffer))
- /* Use set_window_buffer instead of Fset_window_buffer (see
- discussion of bug#11984, bug#12025, bug#12026). */
- set_window_buffer (mini_window, empty_minibuf, 0, 0);
- }
- }
-
/* Display this minibuffer in the proper window. */
/* Use set_window_buffer instead of Fset_window_buffer (see
discussion of bug#11984, bug#12025, bug#12026). */
@@ -908,7 +908,9 @@ read_minibuf (Lisp_Object map, Lisp_Object initial,
Lisp_Object prompt,
unbind_to (count, Qnil);
/* Switch the frame back to the calling frame. */
- if (!EQ (selected_frame, calling_frame)
+ if ((!EQ (selected_frame, calling_frame)
+ || !EQ (XWINDOW (XFRAME (calling_frame)->minibuffer_window)->frame,
+ calling_frame))
&& FRAMEP (calling_frame)
&& FRAME_LIVE_P (XFRAME (calling_frame)))
call2 (intern ("select-frame-set-input-focus"), calling_frame, Qnil);
@@ -1026,6 +1028,14 @@ run_exit_minibuf_hook (void)
safe_run_hooks (Qminibuffer_exit_hook);
}
+/* This variable records the expired minibuffer's frame between the
+ calls of `read_minibuf_unwind' and `minibuffer_unwind'. It should
+ be used only by these two functions. Note that the same search
+ method for the MB's frame won't always work in `minibuffer_unwind'
+ because the intervening `restore-window-configuration' will have
+ changed the buffer in the mini-window. */
+static Lisp_Object exp_MB_frame;
+
/* This function is called on exiting minibuffer, whether normally or
not, and it restores the current window, buffer, etc. */
@@ -1036,6 +1046,28 @@ read_minibuf_unwind (void)
Lisp_Object calling_frame;
Lisp_Object calling_window;
Lisp_Object future_mini_window;
+ Lisp_Object saved_selected_frame = selected_frame;
+ Lisp_Object window, frames;
+ struct window *w;
+ struct frame *f;
+
+ /* Locate the expired minibuffer. */
+ FOR_EACH_FRAME (frames, exp_MB_frame)
+ {
+ f = XFRAME (exp_MB_frame);
+ window = f->minibuffer_window;
+ w = XWINDOW (window);
+ if (EQ (w->frame, exp_MB_frame)
+ && EQ (w->contents, nth_minibuffer (minibuf_level)))
+ goto found;
+ }
+ return; /* expired minibuffer not found. Maybe we should output an
+ error, here. */
+
+ found:
+ if (!EQ (exp_MB_frame, saved_selected_frame))
+ do_switch_frame (exp_MB_frame, 0, 0, Qt); /* This also sets
+ minibuff_window */
/* To keep things predictable, in case it matters, let's be in the
minibuffer when we reset the relevant variables. Don't depend on
@@ -1127,20 +1159,61 @@ read_minibuf_unwind (void)
away from the expired minibuffer window, both in the current
minibuffer's frame and the original calling frame. */
choose_minibuf_frame ();
- if (!EQ (WINDOW_FRAME (XWINDOW (minibuf_window)), calling_frame))
- {
- Lisp_Object prev = Fprevious_window (minibuf_window, Qnil, Qnil);
- /* PREV can be on a different frame when we have a minibuffer only
- frame, the other frame's minibuffer window is MINIBUF_WINDOW,
- and its "focus window" is also MINIBUF_WINDOW. */
- if (!EQ (prev, minibuf_window)
- && EQ (WINDOW_FRAME (XWINDOW (prev)),
- WINDOW_FRAME (XWINDOW (minibuf_window))))
- Fset_frame_selected_window (selected_frame, prev, Qnil);
- }
- else
- Fset_frame_selected_window (calling_frame, calling_window, Qnil);
+ if (NILP (XWINDOW (minibuf_window)->prev_buffers))
+ {
+ if (!EQ (WINDOW_FRAME (XWINDOW (minibuf_window)), calling_frame))
+ {
+ Lisp_Object prev = Fprevious_window (minibuf_window, Qnil, Qnil);
+ /* PREV can be on a different frame when we have a minibuffer only
+ frame, the other frame's minibuffer window is MINIBUF_WINDOW,
+ and its "focus window" is also MINIBUF_WINDOW. */
+ if (!EQ (prev, minibuf_window)
+ && EQ (WINDOW_FRAME (XWINDOW (prev)),
+ WINDOW_FRAME (XWINDOW (minibuf_window))))
+ Fset_frame_selected_window (selected_frame, prev, Qnil);
+ }
+ else
+ Fset_frame_selected_window (calling_frame, calling_window, Qnil);
+ }
+
+ /* Restore the selected frame. */
+ if (!EQ (exp_MB_frame, saved_selected_frame))
+ do_switch_frame (saved_selected_frame, 0, 0, Qt);
+}
+
+/* Replace the expired minibuffer in frame exp_MB_frame with the next less
+ nested minibuffer in that frame, if any. Otherwise, replace it
+ with the null minibuffer. MINIBUF_WINDOW is not changed. */
+static void
+minibuffer_unwind (void)
+{
+ struct frame *f;
+ struct window *w;
+ Lisp_Object window;
+ Lisp_Object entry;
+
+ f = XFRAME (exp_MB_frame);
+ window = f->minibuffer_window;
+ w = XWINDOW (window);
+ if (FRAME_LIVE_P (f))
+ {
+ /* minibuf_window = sf->minibuffer_window; */
+ if (!NILP (w->prev_buffers))
+ {
+ entry = Fcar (w->prev_buffers);
+ w->prev_buffers = Fcdr (w->prev_buffers);
+ set_window_buffer (window, Fcar (entry), 0, 0);
+ Fset_window_start (window, Fcar (Fcdr (entry)), Qnil);
+ Fset_window_point (window, Fcar (Fcdr (Fcdr (entry))));
+ /* set-window-configuration may/will have unselected the
+ mini-window as the selected window. Restore it. */
+ Fset_frame_selected_window (exp_MB_frame, window, Qnil);
+ }
+ else
+ set_window_buffer (window, nth_minibuffer (0), 0, 0);
+ }
}
+
void
@@ -2213,6 +2286,9 @@ syms_of_minibuf (void)
{
staticpro (&minibuf_prompt);
staticpro (&minibuf_save_list);
+ staticpro (&MB_frame);
+ MB_frame = Qnil;
+ staticpro (&exp_MB_frame);
DEFSYM (Qminibuffer_follows_selected_frame,
"minibuffer-follows-selected-frame");
diff --git a/src/window.c b/src/window.c
index eb16e2a..4d5c7e7 100644
--- a/src/window.c
+++ b/src/window.c
@@ -6958,7 +6958,8 @@ the return value is nil. Otherwise the value is t. */)
if (BUFFERP (w->contents)
&& !EQ (w->contents, p->buffer)
- && BUFFER_LIVE_P (XBUFFER (p->buffer)))
+ && BUFFER_LIVE_P (XBUFFER (p->buffer))
+ && (NILP (Fminibufferp (p->buffer, Qnil))))
/* If a window we restore gets another buffer, record the
window's old buffer. */
call1 (Qrecord_window_buffer, window);
diff --git a/src/xdisp.c b/src/xdisp.c
index cc0a689..a405d51 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -12650,9 +12650,8 @@ gui_consider_frame_title (Lisp_Object frame)
mode_line_noprop_buf; then display the title. */
record_unwind_protect (unwind_format_mode_line,
format_mode_line_unwind_data
- (f, current_buffer, selected_window, false));
+ (NULL, current_buffer, Qnil, false));
- Fselect_window (f->selected_window, Qt);
set_buffer_internal_1
(XBUFFER (XWINDOW (f->selected_window)->contents));
fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 7c2ebf6: Prevent open minibuffers getting lost when their frame gets deleted,
Alan Mackenzie <=