From d6b112c85741d7a9ac3de4b022573307ed130e73 Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Thu, 14 Jul 2022 15:19:50 -0500 Subject: [PATCH] xwayland: Only prevent focus change to inactive toplevels Commit b18f788e2e76 broke motif applications by ensuring they could never focus their menus - since then any attempt by an application to focus any window would be met by the window manager immediately refocusing the currently active toplevel window. Later we loosened the restriction in 9e07d25a1b to allow clients that received focus from a grab to do so - but motif applications like nedit don't set focus in this way, and remain broken. This patch further loosens our restrictions, now only reverting a focus change to an inactive top level. This will hopefully prevent any confusing input routing without breaking reasonable clients. This restores functionality to motif menus. Fixes #636 Fixes b18f788e2e74 Signed-off-by: Derek Foreman --- xwayland/window-manager.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c index 73453e0b1..c39e6a026 100644 --- a/xwayland/window-manager.c +++ b/xwayland/window-manager.c @@ -2314,6 +2314,7 @@ weston_wm_handle_leave(struct weston_wm *wm, xcb_generic_event_t *event) static void weston_wm_handle_focus_in(struct weston_wm *wm, xcb_generic_event_t *event) { + struct weston_wm_window *window; xcb_focus_in_event_t *focus = (xcb_focus_in_event_t *) event; /* Do not interfere with grabs */ @@ -2321,6 +2322,17 @@ weston_wm_handle_focus_in(struct weston_wm *wm, xcb_generic_event_t *event) focus->mode == XCB_NOTIFY_MODE_UNGRAB) return; + if (!wm_lookup_window(wm, focus->event, &window)) + return; + + /* Sometimes apps like to focus their own windows, and we don't + * want to prevent that - but we'd like to at least prevent any + * attempt to focus a toplevel that isn't the currently activated + * toplevel. + */ + if (!window->frame) + return; + /* Do not let X clients change the focus behind the compositor's * back. Reset the focus to the old one if it changed. */ if (!wm->focus_window || focus->event != wm->focus_window->id)