diff --git a/include/labwc.h b/include/labwc.h index 9abe32b2..d6bd36c1 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -374,6 +374,7 @@ void foreign_toplevel_update_outputs(struct view *view); void desktop_focus_and_activate_view(struct seat *seat, struct view *view); void desktop_arrange_all_views(struct server *server); void desktop_focus_output(struct output *output); +struct view *desktop_topmost_mapped_view(struct server *server); enum lab_cycle_dir { LAB_CYCLE_DIR_NONE, diff --git a/src/desktop.c b/src/desktop.c index 5a4acffa..bab5d725 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -200,8 +200,8 @@ desktop_cycle_view(struct server *server, struct view *start_view, return NULL; } -static struct view * -topmost_mapped_view(struct server *server) +struct view * +desktop_topmost_mapped_view(struct server *server) { struct view *view; struct wl_list *node_list; @@ -242,7 +242,7 @@ desktop_focused_view(struct server *server) void desktop_focus_topmost_mapped_view(struct server *server) { - struct view *view = topmost_mapped_view(server); + struct view *view = desktop_topmost_mapped_view(server); desktop_focus_and_activate_view(&server->seat, view); if (view) { view_move_to_front(view); diff --git a/src/xwayland-unmanaged.c b/src/xwayland-unmanaged.c index a26a8f7d..9aaf42d6 100644 --- a/src/xwayland-unmanaged.c +++ b/src/xwayland-unmanaged.c @@ -166,6 +166,20 @@ unmanaged_handle_request_activate(struct wl_listener *listener, void *data) struct xwayland_unmanaged *unmanaged = xsurface->data; struct server *server = unmanaged->server; struct seat *seat = &server->seat; + + /* + * Validate that the unmanaged surface trying to grab focus is actually + * a child of the topmost mapped view before granting the request. + */ + struct view *view = desktop_topmost_mapped_view(server); + if (view && view->type == LAB_XWAYLAND_VIEW) { + struct wlr_xwayland_surface *surf = + wlr_xwayland_surface_from_wlr_surface(view->surface); + if (surf && surf->pid != xsurface->pid) { + return; + } + } + seat_focus_surface(seat, xsurface->surface); }