summaryrefslogtreecommitdiff
path: root/src/frame.c
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-06-25 08:16:34 +0800
committerPo Lu <luangruo@yahoo.com>2023-06-25 08:16:34 +0800
commit7b5d32fa871b0ef5c0860612b9c1ac9382c62672 (patch)
treeb8e8bd5e3af422eefb2ca831ebb23f5f30c3694e /src/frame.c
parentf5d142f66370b29af58360faeea90d1112756bc5 (diff)
parent188c90c7c111dbbdc3edd29c23b59ade26f97bfd (diff)
downloademacs-7b5d32fa871b0ef5c0860612b9c1ac9382c62672.tar.gz
Merge remote-tracking branch 'origin/master' into feature/android
Diffstat (limited to 'src/frame.c')
-rw-r--r--src/frame.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/src/frame.c b/src/frame.c
index a2b04a9d99b..eee72954ac1 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1464,6 +1464,10 @@ affects all frames on the same terminal device. */)
If FRAME is a switch-frame event `(switch-frame FRAME1)', use
FRAME1 as frame.
+ If TRACK is non-zero and the frame that currently has the focus
+ redirects its focus to the selected frame, redirect that focused
+ frame's focus to FRAME instead.
+
FOR_DELETION non-zero means that the selected frame is being
deleted, which includes the possibility that the frame's terminal
is dead.
@@ -1471,7 +1475,7 @@ affects all frames on the same terminal device. */)
The value of NORECORD is passed as argument to Fselect_window. */
Lisp_Object
-do_switch_frame (Lisp_Object frame, int for_deletion, Lisp_Object norecord)
+do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object norecord)
{
struct frame *sf = SELECTED_FRAME (), *f;
@@ -1493,6 +1497,44 @@ do_switch_frame (Lisp_Object frame, int for_deletion, Lisp_Object norecord)
else if (f == sf)
return frame;
+ /* If the frame with GUI focus has had it's Emacs focus redirected
+ toward the currently selected frame, we should change the
+ redirection to point to the newly selected frame. This means
+ that if the focus is redirected from a minibufferless frame to a
+ surrogate minibuffer frame, we can use `other-window' to switch
+ between all the frames using that minibuffer frame, and the focus
+ redirection will follow us around. This code is necessary when
+ we have a minibufferless frame using the MB in another (normal)
+ frame (bug#64152) (ACM, 2023-06-20). */
+#ifdef HAVE_WINDOW_SYSTEM
+ if (track && FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->get_focus_frame)
+ {
+ Lisp_Object gfocus; /* The frame which still has focus on the
+ current terminal, according to the GUI
+ system. */
+ Lisp_Object focus; /* The frame to which Emacs has redirected
+ the focus from `gfocus'. This might be a
+ frame with a minibuffer when `gfocus'
+ doesn't have a MB. */
+
+ gfocus = FRAME_TERMINAL (f)->get_focus_frame (f);
+ if (FRAMEP (gfocus))
+ {
+ focus = FRAME_FOCUS_FRAME (XFRAME (gfocus));
+ if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
+ /* Redirect frame focus also when FRAME has its minibuffer
+ window on the selected frame (see Bug#24500).
+
+ Don't do that: It causes redirection problem with a
+ separate minibuffer frame (Bug#24803) and problems
+ when updating the cursor on such frames.
+ || (NILP (focus)
+ && EQ (FRAME_MINIBUF_WINDOW (f), sf->selected_window))) */
+ Fredirect_frame_focus (gfocus, frame);
+ }
+ }
+#endif /* HAVE_X_WINDOWS */
+
if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
@@ -1594,7 +1636,7 @@ This function returns FRAME, or nil if FRAME has been deleted. */)
/* Do not select a tooltip frame (Bug#47207). */
error ("Cannot select a tooltip frame");
else
- return do_switch_frame (frame, 0, norecord);
+ return do_switch_frame (frame, 1, 0, norecord);
}
DEFUN ("handle-switch-frame", Fhandle_switch_frame,
@@ -1610,7 +1652,7 @@ necessarily represent user-visible input focus. */)
kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
run_hook (Qmouse_leave_buffer_hook);
- return do_switch_frame (event, 0, Qnil);
+ return do_switch_frame (event, 0, 0, Qnil);
}
DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
@@ -2177,7 +2219,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
Fraise_frame (frame1);
#endif
- do_switch_frame (frame1, 1, Qnil);
+ do_switch_frame (frame1, 0, 1, Qnil);
sf = SELECTED_FRAME ();
}
else