]> git.mdlowis.com Git - proto/labwc.git/commitdiff
layers: arrange layers on destroy
authorJohan Malm <jgm323@gmail.com>
Tue, 10 Oct 2023 20:51:58 +0000 (21:51 +0100)
committerJohan Malm <johanmalm@users.noreply.github.com>
Mon, 2 Jun 2025 21:00:43 +0000 (22:00 +0100)
...rather than unmap because that is the approach of sway and it also
avoids wshowkeys crashing.

Fixes: #1153
include/layers.h
src/layers.c
src/node.c

index 489bf9e21a011d67b17c944c1b2faf0af087add9..6f98d41dc339aafaf02106ea96f03ffe703fe144 100644 (file)
@@ -11,6 +11,8 @@ struct seat;
 struct lab_layer_surface {
        struct wlr_scene_layer_surface_v1 *scene_layer_surface;
        struct server *server;
+       struct output *output;
+       struct wlr_scene_tree *tree;
 
        bool mapped;
 
index 9583b7f710c106ca18dc3f5c9113d5ec3f6d910b..e52ea3c404eccda67e14f6662c72309c17cdf95a 100644 (file)
@@ -45,6 +45,13 @@ arrange_one_layer(const struct wlr_box *full_area, struct wlr_box *usable_area,
 {
        struct wlr_scene_node *node;
        wl_list_for_each(node, &tree->children, link) {
+               /*
+                * Could be null during destruction when called from
+                * handle_node_destroy()
+                */
+               if (!node->data) {
+                       continue;
+               }
                struct lab_layer_surface *surface = node_layer_surface_from_node(node);
                struct wlr_scene_layer_surface_v1 *scene = surface->scene_layer_surface;
                if (!scene->layer_surface->initialized) {
@@ -119,6 +126,7 @@ handle_output_destroy(struct wl_listener *listener, void *data)
        struct lab_layer_surface *layer =
                wl_container_of(listener, layer, output_destroy);
        layer->scene_layer_surface->layer_surface->output = NULL;
+       layer->output = NULL;
        wlr_layer_surface_v1_destroy(layer->scene_layer_surface->layer_surface);
 }
 
@@ -312,6 +320,16 @@ handle_node_destroy(struct wl_listener *listener, void *data)
         * focus to.
         */
 
+       /*
+        * Nullify node descriptor early to avoid functions such as
+        * arrange_one_layer() trying to dereference it.
+        */
+       layer->tree->node.data = NULL;
+
+       if (layer->output) {
+               output_update_usable_area(layer->output);
+       }
+
        wl_list_remove(&layer->map.link);
        wl_list_remove(&layer->unmap.link);
        wl_list_remove(&layer->surface_commit.link);
@@ -327,9 +345,6 @@ handle_unmap(struct wl_listener *listener, void *data)
        struct lab_layer_surface *layer = wl_container_of(listener, layer, unmap);
        struct wlr_layer_surface_v1 *layer_surface =
                layer->scene_layer_surface->layer_surface;
-       if (layer_surface->output) {
-               output_update_usable_area(layer_surface->output->data);
-       }
        struct seat *seat = &layer->server->seat;
        if (seat->focused_layer == layer_surface) {
                try_to_focus_next_layer_or_toplevel(layer->server);
@@ -552,6 +567,7 @@ handle_new_layer_surface(struct wl_listener *listener, void *data)
        struct lab_layer_surface *surface = znew(*surface);
 
        struct output *output = layer_surface->output->data;
+       surface->output = output;
 
        wlr_fractional_scale_v1_notify_scale(layer_surface->surface,
                output->wlr_output->scale);
@@ -566,6 +582,7 @@ handle_new_layer_surface(struct wl_listener *listener, void *data)
                wlr_log(WLR_ERROR, "could not create layer surface");
                return;
        }
+       surface->tree = surface->scene_layer_surface->tree;
 
        /* In support of IME popup */
        layer_surface->surface->data = surface->scene_layer_surface->tree;
index 328c0eb9d81c8813ae7e92578d5384e82f31786e..e60c13eb039e82b2dfc9078d1f4c5760b29ecec6 100644 (file)
@@ -11,7 +11,7 @@ descriptor_destroy(struct node_descriptor *node_descriptor)
                return;
        }
        wl_list_remove(&node_descriptor->destroy.link);
-       free(node_descriptor);
+       zfree(node_descriptor);
 }
 
 static void