From f3910746bad7d059d1600913a633f4f425497768 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Thu, 26 Jun 2025 17:31:55 +0200 Subject: [PATCH] layers: ignore destroyed layers Fixes: #2858 --- src/debug.c | 3 +++ src/desktop.c | 10 +++++++--- src/layers.c | 26 ++++++++++++++++++++++++-- src/output.c | 1 + 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/debug.c b/src/debug.c index 4123187b..382301c4 100644 --- a/src/debug.c +++ b/src/debug.c @@ -124,6 +124,9 @@ get_special(struct server *server, struct wlr_scene_node *node) return "output->layer_popup_tree"; } for (int i = 0; i < 4; i++) { + if (!output->layer_tree[i]) { + continue; + } if (node == &output->layer_tree[i]->node) { return get_layer_name(i); } diff --git a/src/desktop.c b/src/desktop.c index 28af6cc6..504aa134 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -215,7 +215,9 @@ desktop_update_top_layer_visibility(struct server *server) if (!output_is_usable(output)) { continue; } - wlr_scene_node_set_enabled(&output->layer_tree[top]->node, true); + if (output->layer_tree[top]) { + wlr_scene_node_set_enabled(&output->layer_tree[top]->node, true); + } } /* @@ -231,8 +233,10 @@ desktop_update_top_layer_visibility(struct server *server) continue; } if (view->fullscreen && !(view->outputs & outputs_covered)) { - wlr_scene_node_set_enabled( - &view->output->layer_tree[top]->node, false); + if (output->layer_tree[top]) { + wlr_scene_node_set_enabled( + &view->output->layer_tree[top]->node, false); + } } outputs_covered |= view->outputs; } diff --git a/src/layers.c b/src/layers.c index c702b4df..6e44b89e 100644 --- a/src/layers.c +++ b/src/layers.c @@ -43,6 +43,8 @@ static void arrange_one_layer(const struct wlr_box *full_area, struct wlr_box *usable_area, struct wlr_scene_tree *tree, bool exclusive) { + assert(tree); + struct wlr_scene_node *node; wl_list_for_each(node, &tree->children, link) { /* @@ -90,6 +92,10 @@ layers_arrange(struct output *output) for (int i = ARRAY_SIZE(output->layer_tree) - 1; i >= 0; i--) { struct wlr_scene_tree *layer = output->layer_tree[i]; + if (!layer) { + /* Might happen on output destroy */ + continue; + } /* * Process exclusive-zone clients before non-exclusive-zone @@ -110,6 +116,10 @@ layers_arrange(struct output *output) for (size_t i = 0; i < ARRAY_SIZE(output->layer_tree); i++) { struct wlr_scene_tree *layer = output->layer_tree[i]; + if (!layer) { + /* Might happen on output destroy */ + continue; + } arrange_one_layer(&full_area, &usable_area, layer, /* exclusive */ false); /* Set node position to account for output layout change */ @@ -156,6 +166,10 @@ try_to_focus_next_layer_or_toplevel(struct server *server) enum zwlr_layer_shell_v1_layer top = ZWLR_LAYER_SHELL_V1_LAYER_TOP; for (size_t i = overlay; i >= top; i--) { struct wlr_scene_tree *tree = output->layer_tree[i]; + if (!tree) { + /* Might happen on output destroy */ + continue; + } struct wlr_scene_node *node; /* * In wlr_scene.c they were added at end of list so we @@ -270,8 +284,11 @@ handle_surface_commit(struct wl_listener *listener, void *data) /* Process layer change */ if (committed & WLR_LAYER_SURFACE_V1_STATE_LAYER) { - wlr_scene_node_reparent(&layer->scene_layer_surface->tree->node, - output->layer_tree[layer_surface->current.layer]); + if (output->layer_tree[layer_surface->current.layer]) { + /* Might happen on output destroy */ + wlr_scene_node_reparent(&layer->scene_layer_surface->tree->node, + output->layer_tree[layer_surface->current.layer]); + } } /* Process keyboard-interactivity change */ if (committed & WLR_LAYER_SURFACE_V1_STATE_KEYBOARD_INTERACTIVITY) { @@ -597,6 +614,11 @@ handle_new_layer_surface(struct wl_listener *listener, void *data) struct wlr_scene_tree *selected_layer = output->layer_tree[layer_surface->current.layer]; + if (!selected_layer) { + wlr_layer_surface_v1_destroy(layer_surface); + wlr_log(WLR_ERROR, "Targeted output by layer surface destroyed"); + return; + } surface->scene_layer_surface = wlr_scene_layer_surface_v1_create( selected_layer, layer_surface); diff --git a/src/output.c b/src/output.c index e72d14cf..e743b212 100644 --- a/src/output.c +++ b/src/output.c @@ -175,6 +175,7 @@ output_destroy_notify(struct wl_listener *listener, void *data) for (size_t i = 0; i < ARRAY_SIZE(output->layer_tree); i++) { wlr_scene_node_destroy(&output->layer_tree[i]->node); + output->layer_tree[i] = NULL; } wlr_scene_node_destroy(&output->layer_popup_tree->node); wlr_scene_node_destroy(&output->osd_tree->node);