Slightly adjust EWMH frame activation code for child frames

* src/xterm.c (x_get_toplevel_parent): New function.
(x_focus_frame): Do not use EWMH activation in two cases: focus
transfers to child frames (this is not guaranteed to work if the
focus and the child frame do not share the same toplevel) or
focus transfers from child frames to their toplevel parents.
This commit is contained in:
Po Lu 2022-11-11 10:31:14 +08:00
parent 52d9c51816
commit ea8ed105fd

View file

@ -27522,6 +27522,25 @@ x_get_focus_frame (struct frame *f)
return lisp_focus;
}
/* Return the toplevel parent of F, if it is a child frame.
Otherwise, return NULL. */
static struct frame *
x_get_toplevel_parent (struct frame *f)
{
struct frame *parent;
if (!FRAME_PARENT_FRAME (f))
return NULL;
parent = FRAME_PARENT_FRAME (f);
while (FRAME_PARENT_FRAME (parent))
parent = FRAME_PARENT_FRAME (parent);
return parent;
}
/* In certain situations, when the window manager follows a
click-to-focus policy, there seems to be no way around calling
XSetInputFocus to give another frame the input focus.
@ -27547,6 +27566,14 @@ x_focus_frame (struct frame *f, bool noactivate)
else
{
if (!noactivate
/* If F is a child frame, use SetInputFocus instead. This
may not work if its parent is not activated. */
&& !FRAME_PARENT_FRAME (f)
/* If the focus is being transferred from a child frame to
its toplevel parent, also use SetInputFocus. */
&& (!dpyinfo->x_focus_frame
|| (x_get_toplevel_parent (dpyinfo->x_focus_frame)
!= f))
&& x_wm_supports (f, dpyinfo->Xatom_net_active_window))
{
/* When window manager activation is possible, use it