treelistmodel: Fix handling of collapsed nodes
authorMatthias Clasen <mclasen@redhat.com>
Wed, 24 Aug 2022 12:20:33 +0000 (08:20 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 24 Aug 2022 12:23:20 +0000 (08:23 -0400)
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
gtk/gtktreelistmodel.c

index 268aa449ef31e2835e515d0dc4dbc40231a0ba72..ab053b323fce1245d80210a524b09b7334a349b6 100644 (file)
@@ -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);