[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#48674: Frames and minibuffer bug
From: |
Alan Mackenzie |
Subject: |
bug#48674: Frames and minibuffer bug |
Date: |
Sun, 30 May 2021 13:58:30 +0000 |
Hello again, Martin.
On Sat, May 29, 2021 at 17:00:04 +0000, Alan Mackenzie wrote:
> On Sat, May 29, 2021 at 17:12:58 +0200, martin rudalics wrote:
[ .... ]
> > > Maybe the best workaround would be to create a new flag in struct
> > > frame, which when set means "select mini-window if "possible"
> > > when selecting this frame". "Possible" meaning there's an active
> > > MB. (i) This flag would be set, somehow, by with-selected-frame
> > > when moving away from F1.
[ .... ]
> I've been thinking about my proposed mechanism. There is no need for
> with-selected-frame to set that new flag in struct frame. More simply,
> do_switch_frame can set it whenever the old frame has the mini-window
> selected. In the new frame it will check the flag and if appropriate
> select the MW. Functions such as Fselect_window and
> Fset_frame_selected_window which want to select a specific window would
> clear the flag.
> This mechanism could be implemented entirely in the C code, without
> affecting any Lisp interfaces.
[ .... ]
> I think I'm going to discard yesterday's attempted patch, and write
> another patch along the lines sketched above. This will likely take me
> longer than just this evening.
Here is that patch. Please tell me what you think of it. Thanks!
diff --git a/src/frame.c b/src/frame.c
index e3d65dd28f..623e4ba2cd 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -982,6 +982,7 @@ make_frame (bool mini_p)
f->ns_transparent_titlebar = false;
#endif
#endif
+ f->select_mini_window_flag = false;
/* This one should never be zero. */
f->change_stamp = 1;
root_window = make_window ();
@@ -1542,7 +1543,17 @@ do_switch_frame (Lisp_Object frame, int track, int
for_deletion, Lisp_Object nor
tty->top_frame = frame;
}
+ sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window));
+
selected_frame = frame;
+
+ move_minibuffers_onto_frame (sf, for_deletion);
+
+ if (f->select_mini_window_flag
+ && !NILP (Fminibufferp (XWINDOW (f->minibuffer_window)->contents, Qt)))
+ f->selected_window = f->minibuffer_window;
+ f->select_mini_window_flag = false;
+
if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
last_nonminibuf_frame = XFRAME (selected_frame);
@@ -1559,7 +1570,6 @@ do_switch_frame (Lisp_Object frame, int track, int
for_deletion, Lisp_Object nor
#endif
internal_last_event_frame = Qnil;
- move_minibuffers_onto_frame (sf, for_deletion);
return frame;
}
diff --git a/src/frame.h b/src/frame.h
index 75a0b184c1..cad3df5ae1 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -462,6 +462,11 @@ struct frame
in X builds only. */
bool_bf was_invisible : 1;
+ /* True when the frame isn't selected, and selecting it in the
+ future should select the mini-window rather than the currently
+ selected window in the frame, assuming there is still an active
+ minibuffer in that mini-window. */
+ bool_bf select_mini_window_flag : 1;
/* Bitfield area ends here. */
/* This frame's change stamp, set the last time window change
diff --git a/src/window.c b/src/window.c
index 9961c54161..f0451359c1 100644
--- a/src/window.c
+++ b/src/window.c
@@ -468,6 +468,7 @@ Return WINDOW. */)
else
{
fset_selected_window (XFRAME (frame), window);
+ /* Don't clear FRAME's select_mini_window_flag here. */
return window;
}
}
@@ -517,6 +518,9 @@ select_window (Lisp_Object window, Lisp_Object norecord,
/* Do not select a tooltip window (Bug#47207). */
error ("Cannot select a tooltip window");
+ /* We deinitely want to select WINDOW, not the mini-window. */
+ f->select_mini_window_flag = false;
+
/* Make the selected window's buffer current. */
Fset_buffer (w->contents);
@@ -3242,6 +3246,9 @@ window-start value is reasonable when this function is
called. */)
if (EQ (selected_frame, w->frame))
Fselect_window (window, Qnil);
else
+ /* Do not clear f->select_mini_window_flag here. If the
+ last selected window on F was an active minibuffer, we
+ want to return to it on a later Fselect_frame. */
fset_selected_window (f, window);
}
}
@@ -5153,7 +5160,10 @@ Signal an error when WINDOW is the only window on its
frame. */)
if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
Fselect_window (new_selected_window, Qt);
else
- fset_selected_window (f, new_selected_window);
+ /* Do not clear f->select_mini_window_flag here. If the
+ last selected window on F was an active minibuffer, we
+ want to return to it on a later Fselect_frame. */
+ fset_selected_window (f, new_selected_window);
unblock_input ();
> > martin
--
Alan Mackenzie (Nuremberg, Germany).
- bug#48674: Frames and minibuffer bug, (continued)
- bug#48674: Frames and minibuffer bug, Alan Mackenzie, 2021/05/31
- bug#48674: Frames and minibuffer bug, Alan Mackenzie, 2021/05/27
- bug#48674: Frames and minibuffer bug, martin rudalics, 2021/05/28
- bug#48674: Frames and minibuffer bug, Alan Mackenzie, 2021/05/28
- bug#48674: Frames and minibuffer bug, Alan Mackenzie, 2021/05/28
- bug#48674: Frames and minibuffer bug, martin rudalics, 2021/05/29
- bug#48674: Frames and minibuffer bug, Alan Mackenzie, 2021/05/29
- bug#48674: Frames and minibuffer bug, martin rudalics, 2021/05/29
- bug#48674: Frames and minibuffer bug, Eli Zaretskii, 2021/05/29
- bug#48674: Frames and minibuffer bug, Alan Mackenzie, 2021/05/29
- bug#48674: Frames and minibuffer bug,
Alan Mackenzie <=
- bug#48674: Frames and minibuffer bug, martin rudalics, 2021/05/31