From 261126fcd0791bd582c333d7c0775d13ea401aac Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 19 May 2025 15:03:41 +0900 Subject: [PATCH] chase wlroots: let scene restack xwayland surfaces (MR 4756) Ref: 1133bc15ceb2c2bcb6df692acda6bfa39a292ab5 ("Transparently restack xwayland surfaces") In addition, MR 4772 makes sure the hidden windows are stacked at the bottom, just like what we did with XWAYLAND_VIEW_HIDDEN. --- include/xwayland.h | 5 --- src/view.c | 18 -------- src/workspaces.c | 4 -- src/xwayland.c | 93 ---------------------------------------- subprojects/wlroots.wrap | 2 +- 5 files changed, 1 insertion(+), 121 deletions(-) diff --git a/include/xwayland.h b/include/xwayland.h index ad6e6f02..31d923a1 100644 --- a/include/xwayland.h +++ b/include/xwayland.h @@ -59,9 +59,6 @@ struct xwayland_view { struct view base; struct wlr_xwayland_surface *xwayland_surface; - /* Used to detect stacking order updates */ - int stacking_order; - /* Events unique to XWayland views */ struct wl_listener associate; struct wl_listener dissociate; @@ -85,8 +82,6 @@ void xwayland_unmanaged_create(struct server *server, void xwayland_view_create(struct server *server, struct wlr_xwayland_surface *xsurface, bool mapped); -void xwayland_adjust_stacking_order(struct server *server); - struct wlr_xwayland_surface *xwayland_surface_from_view(struct view *view); void xwayland_server_init(struct server *server, diff --git a/src/view.c b/src/view.c index c673a4ef..cf97b860 100644 --- a/src/view.c +++ b/src/view.c @@ -2283,12 +2283,6 @@ view_move_to_front(struct view *view) move_to_front(view); } -#if HAVE_XWAYLAND - if (view->type == LAB_XWAYLAND_VIEW) { - xwayland_adjust_stacking_order(view->server); - } -#endif - cursor_update_focus(view->server); desktop_update_top_layer_visibility(view->server); } @@ -2303,12 +2297,6 @@ view_move_to_back(struct view *view) for_each_subview(root, move_to_back); move_to_back(root); -#if HAVE_XWAYLAND - if (view->type == LAB_XWAYLAND_VIEW) { - xwayland_adjust_stacking_order(view->server); - } -#endif - cursor_update_focus(view->server); desktop_update_top_layer_visibility(view->server); } @@ -2491,12 +2479,6 @@ view_set_shade(struct view *view, bool shaded) view->shaded = shaded; ssd_enable_shade(view->ssd, view->shaded); wlr_scene_node_set_enabled(&view->content_tree->node, !view->shaded); - -#if HAVE_XWAYLAND - if (view->type == LAB_XWAYLAND_VIEW) { - xwayland_adjust_stacking_order(view->server); - } -#endif } void diff --git a/src/workspaces.c b/src/workspaces.c index 14ed51a9..23e86c41 100644 --- a/src/workspaces.c +++ b/src/workspaces.c @@ -395,10 +395,6 @@ workspaces_switch_to(struct workspace *target, bool update_focus) /* And finally show the OSD */ _osd_show(server); -#if HAVE_XWAYLAND - /* Ensure xwayland internal stacking order corresponds to the current workspace */ - xwayland_adjust_stacking_order(server); -#endif /* * Make sure we are not carrying around a * cursor image from the previous desktop diff --git a/src/xwayland.c b/src/xwayland.c index 3462929d..cbe86128 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -932,9 +932,6 @@ xwayland_view_create(struct server *server, view->type = LAB_XWAYLAND_VIEW; view->impl = &xwayland_view_impl; - /* Set to -1 so we always restack the view on map */ - xwayland_view->stacking_order = -1; - /* * Set two-way view <-> xsurface association. Usually the association * remains until the xsurface is destroyed (which also destroys the @@ -1104,96 +1101,6 @@ xwayland_server_init(struct server *server, struct wlr_compositor *compositor) } } -enum xwayland_view_layer { - XWAYLAND_VIEW_HIDDEN, - XWAYLAND_VIEW_BOTTOM, - XWAYLAND_VIEW_NORMAL, - XWAYLAND_VIEW_TOP, -}; - -static enum xwayland_view_layer -get_layer(struct view *view) -{ - if (view->workspace != view->server->workspaces.current) { - /* - * Until we expose the workspaces to xwayland we need a way to - * ensure that xwayland views on the current workspace are - * always stacked above xwayland views on other workspaces. - * - * If we fail to do so, issues arise in scenarios where we - * change the mouse focus but do not change the (xwayland) - * stacking order. - * - * Reproducer: - * - open at least two xwayland windows which allow scrolling - * (e.g. urxvt with 'man man') - * - switch to another workspace, open another xwayland window - * which allows scrolling and maximize it - * - switch back to the previous workspace with the two windows - * - move the mouse to the xwayland window that does *not* have - * focus - * - start scrolling - * - all scroll events should end up on the maximized window on - * the other workspace - */ - return XWAYLAND_VIEW_HIDDEN; - } else if (view->shaded) { - /* - * Ensure that we don't raise a shaded window to the front - * which then steals mouse events. - */ - return XWAYLAND_VIEW_HIDDEN; - } else if (view_is_always_on_bottom(view)) { - return XWAYLAND_VIEW_BOTTOM; - } else if (view_is_always_on_top(view)) { - return XWAYLAND_VIEW_TOP; - } else { - return XWAYLAND_VIEW_NORMAL; - } -} - -void -xwayland_adjust_stacking_order(struct server *server) -{ - if (!server->xwayland) { - /* This happens when windows are unmapped on exit */ - return; - } - - int stacking_order = 0; - bool update = false; - - /* - * Iterate over the windows from bottom to top and notify their - * stacking order to xwayland if we detect updates in it. Note - * that server->views are sorted from top to bottom but doesn't - * consider always-on-{top,bottom} windows. - */ - for (enum xwayland_view_layer layer = XWAYLAND_VIEW_HIDDEN; - layer <= XWAYLAND_VIEW_TOP; layer++) { - struct view *view; - wl_list_for_each_reverse(view, &server->views, link) { - if (view->type != LAB_XWAYLAND_VIEW - || layer != get_layer(view)) { - continue; - } - - struct xwayland_view *xwayland_view = - xwayland_view_from_view(view); - - /* On detecting update, restack all the views above it */ - update |= xwayland_view->stacking_order != stacking_order; - if (update) { - wlr_xwayland_surface_restack( - xwayland_view->xwayland_surface, - NULL, XCB_STACK_MODE_ABOVE); - } - xwayland_view->stacking_order = stacking_order; - stacking_order++; - } - } -} - void xwayland_reset_cursor(struct server *server) { diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index dde55453..cf46d834 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = ceb4fcedca30d323a05836b0872bfe773a047ccc +revision = 1133bc15ceb2c2bcb6df692acda6bfa39a292ab5 [provide] dependency_names = wlroots-0.19 -- 2.52.0