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 b18f788e2e

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
Derek Foreman 2022-07-14 15:19:50 -05:00
parent 8a610ffe41
commit d6b112c857

View File

@ -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)