]> git.mdlowis.com Git - proto/labwc.git/commitdiff
ssd/ssd-shadow.c: fix memory leak
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Tue, 2 Jul 2024 18:49:53 +0000 (20:49 +0200)
committerJohan Malm <johanmalm@users.noreply.github.com>
Tue, 2 Jul 2024 19:34:25 +0000 (20:34 +0100)
Before this patch, we were leaking memory [0] because the
shadow implementation did not free the ssd_parts on destruction.

There was also no check if shadows were actually enabled via
rc.xml or not so this also impacted people who were not using
shadows but were not setting the shadow size via their theme to 0.

[0] 44 bytes per ssd_part * 8 parts * 2 states == 704 bytes per
view closed. Note that Reconfigure also re-creates the SSD, thus
we were also leaking 704 bytes * nr_views per Reconfigure.

src/ssd/ssd-shadow.c

index cf54f6fa250f412729e570ac922cfe4915243bf6..3e6227aaa06aa64a024b7a0dabc9f4757c6814fe 100644 (file)
@@ -241,7 +241,12 @@ ssd_shadow_create(struct ssd *ssd)
        struct wlr_scene_tree *parent;
 
        FOR_EACH_STATE(ssd, subtree) {
-               if (subtree == &ssd->shadow.active) {
+               wl_list_init(&subtree->parts);
+
+               if (!rc.shadows_enabled) {
+                       /* Shadows are globally disabled */
+                       continue;
+               } else if (subtree == &ssd->shadow.active) {
                        if (theme->window_active_shadow_size == 0) {
                                /* Active window shadows are disabled */
                                continue;
@@ -264,7 +269,6 @@ ssd_shadow_create(struct ssd *ssd)
                        corner_bottom_buffer = &theme->shadow_corner_bottom_inactive->base;
                        edge_buffer = &theme->shadow_edge_inactive->base;
                }
-               wl_list_init(&subtree->parts);
 
                make_shadow(&subtree->parts,
                        LAB_SSD_PART_CORNER_BOTTOM_RIGHT, parent,
@@ -311,6 +315,16 @@ ssd_shadow_destroy(struct ssd *ssd)
        assert(ssd);
        assert(ssd->shadow.tree);
 
+       struct ssd_sub_tree *subtree;
+       FOR_EACH_STATE(ssd, subtree) {
+               ssd_destroy_parts(&subtree->parts);
+               /*
+                * subtree->tree will be destroyed when its
+                * parent (ssd->shadow.tree) is destroyed.
+                */
+               subtree->tree = NULL;
+       } FOR_EACH_END
+
        wlr_scene_node_destroy(&ssd->shadow.tree->node);
        ssd->shadow.tree = NULL;
 }