From 05b7afd05a32abc6c167dae3d8634853bec78799 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 3 Sep 2022 13:10:33 -0400 Subject: [PATCH] xwayland: Factor out focus_next_surface() from unmanaged_handle_unmap() - Eliminate multiple "return" paths in unmanaged_handle_unmap(), which were a bug waiting to happen. - Use wl_list_for_each_reverse() rather than wl_list_for_each() to find the topmost (most-recently-created) unmanaged surface. - Only call desktop_focus_topmost_mapped_view() if the unmapped surface was actually focused. --- src/xwayland-unmanaged.c | 60 ++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/src/xwayland-unmanaged.c b/src/xwayland-unmanaged.c index 49d535f8..b14760c2 100644 --- a/src/xwayland-unmanaged.c +++ b/src/xwayland-unmanaged.c @@ -51,6 +51,38 @@ unmanaged_handle_map(struct wl_listener *listener, void *data) wlr_scene_node_set_position(unmanaged->node, xsurface->x, xsurface->y); } +static void +focus_next_surface(struct server *server, struct wlr_xwayland_surface *xsurface) +{ + /* + * Try to focus on parent surface + * This seems to fix JetBrains/Intellij window focus issues + */ + if (xsurface->parent && xsurface->parent->surface + && wlr_xwayland_or_surface_wants_focus(xsurface->parent)) { + seat_focus_surface(&server->seat, xsurface->parent->surface); + return; + } + + /* Try to focus on last created unmanaged xwayland surface */ + struct xwayland_unmanaged *u; + struct wl_list *list = &server->unmanaged_surfaces; + wl_list_for_each_reverse (u, list, link) { + struct wlr_xwayland_surface *prev = u->xwayland_surface; + if (wlr_xwayland_or_surface_wants_focus(prev)) { + seat_focus_surface(&server->seat, prev->surface); + return; + } + } + + /* + * If we don't find a surface to focus fall back + * to the topmost mapped view. This fixes dmenu + * not giving focus back when closed with ESC. + */ + desktop_focus_topmost_mapped_view(server); +} + static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) { @@ -72,34 +104,8 @@ unmanaged_handle_unmap(struct wl_listener *listener, void *data) unmanaged->node = NULL; if (seat->seat->keyboard_state.focused_surface == xsurface->surface) { - /* - * Try to focus on parent surface - * This seems to fix JetBrains/Intellij window focus issues - */ - if (xsurface->parent && xsurface->parent->surface - && wlr_xwayland_or_surface_wants_focus(xsurface->parent)) { - seat_focus_surface(seat, xsurface->parent->surface); - return; - } - - /* Try to focus on last created unmanaged xwayland surface */ - struct xwayland_unmanaged *u; - struct wl_list *list = &unmanaged->server->unmanaged_surfaces; - wl_list_for_each (u, list, link) { - struct wlr_xwayland_surface *prev = u->xwayland_surface; - if (!wlr_xwayland_or_surface_wants_focus(prev)) { - continue; - } - seat_focus_surface(seat, prev->surface); - return; - } + focus_next_surface(unmanaged->server, xsurface); } - /* - * If we don't find a surface to focus fall back - * to the topmost mapped view. This fixes dmenu - * not giving focus back when closed with ESC. - */ - desktop_focus_topmost_mapped_view(unmanaged->server); } static void