mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-25 10:47:00 +00:00
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.
This commit is contained in:
parent
e276810dff
commit
7c2ebf6e23
@ -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
|
||||
|
@ -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))
|
||||
|
46
src/fns.c
46
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. */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
294
src/minibuf.c
294
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 `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)
|
||||
/* 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)
|
||||
{
|
||||
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))
|
||||
return this_minibuffer_depth (Fcar (ent1))
|
||||
> this_minibuffer_depth (Fcar (ent2)) ;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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");
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user