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.
This commit is contained in:
tokyo4j 2025-05-19 15:03:41 +09:00 committed by Johan Malm
parent 1eaba4af33
commit 261126fcd0
5 changed files with 1 additions and 121 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
[wrap-git]
url = https://gitlab.freedesktop.org/wlroots/wlroots.git
revision = ceb4fcedca30d323a05836b0872bfe773a047ccc
revision = 1133bc15ceb2c2bcb6df692acda6bfa39a292ab5
[provide]
dependency_names = wlroots-0.19