From 2c64b30a6750d5e585c00c4c116f415bac33d18f Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 8 Jul 2025 15:00:57 +0200 Subject: [PATCH] scene: add knob to turn off Xwayland surface restacking This is useful in these cases: - The same surface is added to two different scene-graphs. wlroots can't figure out on its own which scene-graph should drive the Xwayland stacking. - A compositor uses multiple Xwayland servers (e.g. one per app). wlroots will try to restack surfaces from different Xwayland instances and this will not go well. --- include/wlr/types/wlr_scene.h | 2 ++ types/scene/wlr_scene.c | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h index 6fd243477..46635f4bf 100644 --- a/include/wlr/types/wlr_scene.h +++ b/include/wlr/types/wlr_scene.h @@ -105,6 +105,8 @@ struct wlr_scene { struct wlr_gamma_control_manager_v1 *gamma_control_manager_v1; struct wlr_color_manager_v1 *color_manager_v1; + bool restack_xwayland_surfaces; + struct { struct wl_listener linux_dmabuf_v1_destroy; struct wl_listener gamma_control_manager_v1_destroy; diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index 0634f62e2..16a748e79 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -185,6 +185,8 @@ struct wlr_scene *wlr_scene_create(void) { wl_list_init(&scene->gamma_control_manager_v1_destroy.link); wl_list_init(&scene->gamma_control_manager_v1_set_gamma.link); + scene->restack_xwayland_surfaces = true; + const char *debug_damage_options[] = { "none", "rerender", @@ -293,6 +295,7 @@ struct scene_update_data { struct wlr_box update_box; struct wl_list *outputs; bool calculate_visibility; + bool restack_xwayland_surfaces; #if WLR_HAS_XWAYLAND struct wlr_xwayland_surface *restack_above; @@ -609,7 +612,9 @@ static bool scene_node_update_iterator(struct wlr_scene_node *node, update_node_update_outputs(node, data->outputs, NULL, NULL); #if WLR_HAS_XWAYLAND - restack_xwayland_surface(node, &box, data); + if (data->restack_xwayland_surfaces) { + restack_xwayland_surface(node, &box, data); + } #endif return false; @@ -671,6 +676,7 @@ static void scene_update_region(struct wlr_scene *scene, }, .outputs = &scene->outputs, .calculate_visibility = scene->calculate_visibility, + .restack_xwayland_surfaces = scene->restack_xwayland_surfaces, }; // update node visibility and output enter/leave events @@ -686,7 +692,9 @@ static void scene_node_update(struct wlr_scene_node *node, int x, y; if (!wlr_scene_node_coords(node, &x, &y)) { #if WLR_HAS_XWAYLAND - restack_xwayland_surface_below(node); + if (scene->restack_xwayland_surfaces) { + restack_xwayland_surface_below(node); + } #endif if (damage) { scene_update_region(scene, damage);