diff options
author | Matthias Clasen <mclasen@redhat.com> | 2022-08-24 08:20:33 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2022-08-24 08:23:20 -0400 |
commit | f1c1c979c2ddc5a73a1859edbd74b261735bd531 (patch) | |
tree | b371c78ea8731218593b65bf3907ecc8852e4197 | |
parent | e68925a932ad3d5c1228aaeb6ed89dbe2e30225d (diff) | |
download | gtk+-f1c1c979c2ddc5a73a1859edbd74b261735bd531.tar.gz |
treelistmodel: Fix handling of collapsed nodes
When we collapse a node, we clear out the children,
but we were not disconnecting the signal handler on
the child listmodel, leading to bad outcomes when
that model is persistent and changing.
Fixes: #4595
-rw-r--r-- | gtk/gtktreelistmodel.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/gtk/gtktreelistmodel.c b/gtk/gtktreelistmodel.c index 268aa449ef..ab053b323f 100644 --- a/gtk/gtktreelistmodel.c +++ b/gtk/gtktreelistmodel.c @@ -441,22 +441,28 @@ gtk_tree_list_model_items_changed_cb (GListModel *model, static void gtk_tree_list_row_destroy (GtkTreeListRow *row); static void -gtk_tree_list_model_clear_node (gpointer data) +gtk_tree_list_model_clear_node_children (TreeNode *node) { - TreeNode *node = data; - - if (node->row) - gtk_tree_list_row_destroy (node->row); - if (node->model) { g_signal_handlers_disconnect_by_func (node->model, gtk_tree_list_model_items_changed_cb, node); - g_object_unref (node->model); + g_clear_object (&node->model); } - if (node->children) - gtk_rb_tree_unref (node->children); + + g_clear_pointer (&node->children, gtk_rb_tree_unref); +} + +static void +gtk_tree_list_model_clear_node (gpointer data) +{ + TreeNode *node = data; + + if (node->row) + gtk_tree_list_row_destroy (node->row); + + gtk_tree_list_model_clear_node_children (node); } static void @@ -551,8 +557,7 @@ gtk_tree_list_model_collapse_node (GtkTreeListModel *self, n_items = tree_node_get_n_children (node); - g_clear_pointer (&node->children, gtk_rb_tree_unref); - g_clear_object (&node->model); + gtk_tree_list_model_clear_node_children (node); tree_node_mark_dirty (node); |