diff options
| author | Alan Mackenzie | 2021-05-31 16:24:11 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2021-05-31 16:24:11 +0000 |
| commit | 2ee5ce208f212ed658cf2125ef6bc24a435dda50 (patch) | |
| tree | 964ca4a5906240e7c731595f7fdf90a7cfcb5307 /src | |
| parent | 63e9a4b1e1fe99462ec97b2145b91898fa5b4085 (diff) | |
| download | emacs-2ee5ce208f212ed658cf2125ef6bc24a435dda50.tar.gz emacs-2ee5ce208f212ed658cf2125ef6bc24a435dda50.zip | |
Make frames record when their selected window was the mini-window
When a frame in this state is selected again by Fselect_frame (but not by
Fselect_window), the mini-window rather than the frame's currently selected
window, is chosen for selection, should there still be an active minibuffer in
it.
This fixes bug #48674.
* src/frame.h (struct frame): Add new boolean field select_mini_window_flag.
* src/frame.c (make_frame): Initialize select_mini_window_flag to false.
(do_switch_frame): Set the new flag appropriately for the old frame, and
process the new frame's setting of this flag, before setting it to false.
* src/window.c (select_window): Set f->select_mini_window_flag to false.
(Fset_frame_selected_window, Fdelete_other_windows_internal)
(Fdelete_window_internal): Add comments clarifying that there is no clearing
of f->select_mini_window_flag in these functions.
Diffstat (limited to 'src')
| -rw-r--r-- | src/frame.c | 12 | ||||
| -rw-r--r-- | src/frame.h | 5 | ||||
| -rw-r--r-- | src/window.c | 10 |
3 files changed, 26 insertions, 1 deletions
diff --git a/src/frame.c b/src/frame.c index e3d65dd28f3..623e4ba2cde 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -982,6 +982,7 @@ make_frame (bool mini_p) | |||
| 982 | f->ns_transparent_titlebar = false; | 982 | f->ns_transparent_titlebar = false; |
| 983 | #endif | 983 | #endif |
| 984 | #endif | 984 | #endif |
| 985 | f->select_mini_window_flag = false; | ||
| 985 | /* This one should never be zero. */ | 986 | /* This one should never be zero. */ |
| 986 | f->change_stamp = 1; | 987 | f->change_stamp = 1; |
| 987 | root_window = make_window (); | 988 | root_window = make_window (); |
| @@ -1542,7 +1543,17 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor | |||
| 1542 | tty->top_frame = frame; | 1543 | tty->top_frame = frame; |
| 1543 | } | 1544 | } |
| 1544 | 1545 | ||
| 1546 | sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window)); | ||
| 1547 | |||
| 1545 | selected_frame = frame; | 1548 | selected_frame = frame; |
| 1549 | |||
| 1550 | move_minibuffers_onto_frame (sf, for_deletion); | ||
| 1551 | |||
| 1552 | if (f->select_mini_window_flag | ||
| 1553 | && !NILP (Fminibufferp (XWINDOW (f->minibuffer_window)->contents, Qt))) | ||
| 1554 | f->selected_window = f->minibuffer_window; | ||
| 1555 | f->select_mini_window_flag = false; | ||
| 1556 | |||
| 1546 | if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame))) | 1557 | if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame))) |
| 1547 | last_nonminibuf_frame = XFRAME (selected_frame); | 1558 | last_nonminibuf_frame = XFRAME (selected_frame); |
| 1548 | 1559 | ||
| @@ -1559,7 +1570,6 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor | |||
| 1559 | #endif | 1570 | #endif |
| 1560 | internal_last_event_frame = Qnil; | 1571 | internal_last_event_frame = Qnil; |
| 1561 | 1572 | ||
| 1562 | move_minibuffers_onto_frame (sf, for_deletion); | ||
| 1563 | return frame; | 1573 | return frame; |
| 1564 | } | 1574 | } |
| 1565 | 1575 | ||
diff --git a/src/frame.h b/src/frame.h index 75a0b184c19..cad3df5ae10 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -462,6 +462,11 @@ struct frame | |||
| 462 | in X builds only. */ | 462 | in X builds only. */ |
| 463 | bool_bf was_invisible : 1; | 463 | bool_bf was_invisible : 1; |
| 464 | 464 | ||
| 465 | /* True when the frame isn't selected, and selecting it in the | ||
| 466 | future should select the mini-window rather than the currently | ||
| 467 | selected window in the frame, assuming there is still an active | ||
| 468 | minibuffer in that mini-window. */ | ||
| 469 | bool_bf select_mini_window_flag : 1; | ||
| 465 | /* Bitfield area ends here. */ | 470 | /* Bitfield area ends here. */ |
| 466 | 471 | ||
| 467 | /* This frame's change stamp, set the last time window change | 472 | /* This frame's change stamp, set the last time window change |
diff --git a/src/window.c b/src/window.c index 9961c54161d..2d98ae5f156 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -468,6 +468,7 @@ Return WINDOW. */) | |||
| 468 | else | 468 | else |
| 469 | { | 469 | { |
| 470 | fset_selected_window (XFRAME (frame), window); | 470 | fset_selected_window (XFRAME (frame), window); |
| 471 | /* Don't clear FRAME's select_mini_window_flag here. */ | ||
| 471 | return window; | 472 | return window; |
| 472 | } | 473 | } |
| 473 | } | 474 | } |
| @@ -517,6 +518,9 @@ select_window (Lisp_Object window, Lisp_Object norecord, | |||
| 517 | /* Do not select a tooltip window (Bug#47207). */ | 518 | /* Do not select a tooltip window (Bug#47207). */ |
| 518 | error ("Cannot select a tooltip window"); | 519 | error ("Cannot select a tooltip window"); |
| 519 | 520 | ||
| 521 | /* We deinitely want to select WINDOW, not the mini-window. */ | ||
| 522 | f->select_mini_window_flag = false; | ||
| 523 | |||
| 520 | /* Make the selected window's buffer current. */ | 524 | /* Make the selected window's buffer current. */ |
| 521 | Fset_buffer (w->contents); | 525 | Fset_buffer (w->contents); |
| 522 | 526 | ||
| @@ -3242,6 +3246,9 @@ window-start value is reasonable when this function is called. */) | |||
| 3242 | if (EQ (selected_frame, w->frame)) | 3246 | if (EQ (selected_frame, w->frame)) |
| 3243 | Fselect_window (window, Qnil); | 3247 | Fselect_window (window, Qnil); |
| 3244 | else | 3248 | else |
| 3249 | /* Do not clear f->select_mini_window_flag here. If the | ||
| 3250 | last selected window on F was an active minibuffer, we | ||
| 3251 | want to return to it on a later Fselect_frame. */ | ||
| 3245 | fset_selected_window (f, window); | 3252 | fset_selected_window (f, window); |
| 3246 | } | 3253 | } |
| 3247 | } | 3254 | } |
| @@ -5153,6 +5160,9 @@ Signal an error when WINDOW is the only window on its frame. */) | |||
| 5153 | if (EQ (FRAME_SELECTED_WINDOW (f), selected_window)) | 5160 | if (EQ (FRAME_SELECTED_WINDOW (f), selected_window)) |
| 5154 | Fselect_window (new_selected_window, Qt); | 5161 | Fselect_window (new_selected_window, Qt); |
| 5155 | else | 5162 | else |
| 5163 | /* Do not clear f->select_mini_window_flag here. If the | ||
| 5164 | last selected window on F was an active minibuffer, we | ||
| 5165 | want to return to it on a later Fselect_frame. */ | ||
| 5156 | fset_selected_window (f, new_selected_window); | 5166 | fset_selected_window (f, new_selected_window); |
| 5157 | 5167 | ||
| 5158 | unblock_input (); | 5168 | unblock_input (); |