From ea8ed105fdbb7b14ac7f507483f19373738f2941 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 11 Nov 2022 10:31:14 +0800 Subject: [PATCH] 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. --- src/xterm.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/xterm.c b/src/xterm.c index a175a4a6bbb..0a25d7de05a 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -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 -- 2.39.5