diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 726a08da2..f3ffe04a9 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -164,6 +164,10 @@ static void unmanaged_handle_override_redirect(struct wl_listener *listener, voi wl_container_of(listener, surface, override_redirect); struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; + sway_log(SWAY_INFO, "unmanaged surface %d changed override_redirect to %d", + xsurface->window_id, xsurface->override_redirect); + xsurface->override_redirect = true; + return; bool mapped = xsurface->mapped; if (mapped) { unmanaged_handle_unmap(&surface->unmap, NULL); @@ -366,12 +370,8 @@ static void xwayland_surface_iterator(struct wlr_surface *surface, iter_data->user_data); } -static void for_each_popup_surface(struct sway_view *view, +static void xwayland_surface_for_each_popup_surface(struct wlr_xwayland_surface *xsurface, wlr_surface_iterator_func_t iterator, void *user_data) { - if (xwayland_view_from_view(view) == NULL) { - return; - } - struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; struct wlr_xwayland_surface *child; sway_log(SWAY_INFO, "iterating popups for %d", xsurface->window_id); wl_list_for_each(child, &xsurface->children, parent_link) { @@ -385,9 +385,19 @@ static void for_each_popup_surface(struct sway_view *view, .x = child->x - xsurface->x, .y = child->y - xsurface->y, }; wlr_surface_for_each_surface(child->surface, xwayland_surface_iterator, &data); + xwayland_surface_for_each_popup_surface(child, iterator, user_data); } } +static void for_each_popup_surface(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data) { + if (xwayland_view_from_view(view) == NULL) { + return; + } + struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; + xwayland_surface_for_each_popup_surface(xsurface, iterator, user_data); +} + static bool is_transient_for(struct sway_view *child, struct sway_view *ancestor) { if (xwayland_view_from_view(child) == NULL) { diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 15687993b..939ccc227 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -121,6 +121,28 @@ struct sway_node *node_at_coords( // check for unmanaged views #if HAVE_XWAYLAND + struct sway_container *focus = seat_get_focused_container(seat); + if (focus && focus->view && focus->view->type == SWAY_VIEW_XWAYLAND) { + struct wlr_xwayland_surface *xsurface = focus->view->wlr_xwayland_surface; + struct wlr_xwayland_surface *child; + sway_log(SWAY_INFO, "iterating popups for %d", xsurface->window_id); + wl_list_for_each_reverse(child, &xsurface->children, parent_link) { + if (!child->override_redirect || !child->mapped) { + continue; + } + sway_log(SWAY_INFO, "found popup %d", child->window_id); + double _sx = lx - child->x; + double _sy = ly - child->y; + if (wlr_surface_point_accepts_input(child->surface, _sx, _sy)) { + *surface = xsurface->surface; + *sx = lx - xsurface->x; + *sy = ly - xsurface->y; + wlr_xwayland_surface_restack(child, NULL, XCB_STACK_MODE_ABOVE); + return NULL; + } + } + } + struct wl_list *unmanaged = &root->xwayland_unmanaged; struct sway_xwayland_unmanaged *unmanaged_surface; wl_list_for_each_reverse(unmanaged_surface, unmanaged, link) {