]> git.lizzy.rs Git - bspwm.git/commitdiff
Fix memory leak in remove_node
authorBastien Dejean <nihilhill@gmail.com>
Sat, 14 May 2016 15:43:42 +0000 (17:43 +0200)
committerBastien Dejean <nihilhill@gmail.com>
Sat, 14 May 2016 15:43:42 +0000 (17:43 +0200)
desktop.c
desktop.h
tree.c
tree.h

index 69d13f670258f365278e20b53333651cebf84fda..8ea6ff922bc4dbec752e7b5a2867948077999102 100644 (file)
--- a/desktop.c
+++ b/desktop.c
@@ -245,12 +245,6 @@ desktop_t *find_desktop_in(uint32_t id, monitor_t *m)
        return NULL;
 }
 
-void empty_desktop(monitor_t *m, desktop_t *d)
-{
-       destroy_tree(m, d, d->root);
-       d->root = d->focus = NULL;
-}
-
 void unlink_desktop(monitor_t *m, desktop_t *d)
 {
        desktop_t *prev = d->prev;
@@ -285,7 +279,7 @@ void remove_desktop(monitor_t *m, desktop_t *d)
 
        history_remove(d, NULL, false);
        unlink_desktop(m, d);
-       empty_desktop(m, d);
+       remove_node(m, d, d->root);
        free(d);
 
        ewmh_update_current_desktop();
index 40d60bc2fe4b4082237f1669b7ff5c5e6c25f364..6916eada7db7510fc2577ac8ba6a3ab163572987 100644 (file)
--- a/desktop.h
+++ b/desktop.h
@@ -37,7 +37,6 @@ void rename_desktop(monitor_t *m, desktop_t *d, const char *name);
 void insert_desktop(monitor_t *m, desktop_t *d);
 void add_desktop(monitor_t *m, desktop_t *d);
 desktop_t *find_desktop_in(uint32_t id, monitor_t *m);
-void empty_desktop(monitor_t *m, desktop_t *d);
 void unlink_desktop(monitor_t *m, desktop_t *d);
 void remove_desktop(monitor_t *m, desktop_t *d);
 void merge_desktops(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd);
diff --git a/tree.c b/tree.c
index 0184a16739acd6d01049f9deb7051b015eab31eb..dd1d0a5fbe5558a30e899113cf78544b6596618c 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -246,6 +246,16 @@ void cancel_presel(monitor_t *m, desktop_t *d, node_t *n)
        put_status(SBSC_MASK_NODE_PRESEL, "node_presel 0x%08X 0x%08X 0x%08X cancel\n", m->id, d->id, n->id);
 }
 
+void cancel_presel_in(monitor_t *m, desktop_t *d, node_t *n)
+{
+       if (n == NULL) {
+               return;
+       }
+       cancel_presel(m, d, n);
+       cancel_presel_in(m, d, n->first_child);
+       cancel_presel_in(m, d, n->second_child);
+}
+
 node_t *find_public(desktop_t *d)
 {
        unsigned int b_manual_area = 0;
@@ -1200,21 +1210,20 @@ void remove_node(monitor_t *m, desktop_t *d, node_t *n)
        unlink_node(m, d, n);
        history_remove(d, n, true);
        remove_stack_node(n);
-       cancel_presel(m, d, n);
+       cancel_presel_in(m, d, n);
        if (m->sticky_count > 0) {
                m->sticky_count -= sticky_count(n);
        }
        clients_count -= clients_count_in(n);
-       if (grabbed_node == n) {
+       if (is_descendant(grabbed_node, n)) {
                grabbed_node = NULL;
        }
-       free(n->client);
-       free(n);
+       free_node(n);
 
        ewmh_update_client_list(false);
        ewmh_update_client_list(true);
 
-       if (d->focus == NULL) {
+       if (mon != NULL && d->focus == NULL) {
                if (d == mon->desk) {
                        focus_node(m, d, NULL);
                } else {
@@ -1223,28 +1232,17 @@ void remove_node(monitor_t *m, desktop_t *d, node_t *n)
        }
 }
 
-void destroy_tree(monitor_t *m, desktop_t *d, node_t *n)
+void free_node(node_t *n)
 {
        if (n == NULL) {
                return;
        }
        node_t *first_child = n->first_child;
        node_t *second_child = n->second_child;
-       if (n->client != NULL) {
-               remove_stack_node(n);
-               clients_count--;
-       }
-       if (n->sticky) {
-               m->sticky_count--;
-       }
-       cancel_presel(m, d, n);
        free(n->client);
        free(n);
-       if (first_child != NULL && second_child != NULL) {
-               first_child->parent = second_child->parent = NULL;
-               destroy_tree(m, d, first_child);
-               destroy_tree(m, d, second_child);
-       }
+       free_node(first_child);
+       free_node(second_child);
 }
 
 bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop_t *d2, node_t *n2)
diff --git a/tree.h b/tree.h
index 591322d6c7038c1868e8054072540fb4feead407..d2d55671305e9e69585a00265032e00cbf3bd674 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -32,6 +32,7 @@ void set_ratio(node_t *n, double rat);
 void presel_dir(monitor_t *m, desktop_t *d, node_t *n, direction_t dir);
 void presel_ratio(monitor_t *m, desktop_t *d, node_t *n, double ratio);
 void cancel_presel(monitor_t *m, desktop_t *d, node_t *n);
+void cancel_presel_in(monitor_t *m, desktop_t *d, node_t *n);
 node_t *find_public(desktop_t *d);
 node_t *insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f);
 void insert_receptacle(monitor_t *m, desktop_t *d, node_t *n);
@@ -77,7 +78,7 @@ void unlink_node(monitor_t *m, desktop_t *d, node_t *n);
 void close_node(node_t *n);
 void kill_node(monitor_t *m, desktop_t *d, node_t *n);
 void remove_node(monitor_t *m, desktop_t *d, node_t *n);
-void destroy_tree(monitor_t *m, desktop_t *d, node_t *n);
+void free_node(node_t *n);
 bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop_t *d2, node_t *n2);
 bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desktop_t *dd, node_t *nd);
 bool find_closest_node(coordinates_t *ref, coordinates_t *dst, cycle_dir_t dir, node_select_t sel);