cssnode: Implement refcounting
authorBenjamin Otte <otte@redhat.com>
Mon, 26 Jan 2015 05:13:01 +0000 (06:13 +0100)
committerBenjamin Otte <otte@redhat.com>
Wed, 18 Mar 2015 14:23:29 +0000 (15:23 +0100)
The parent refs the child, so gtk_css_node_set_parent() adds/removes a
reference.

We should probably refactor this so that we name the function
parent.add(node) instead of node.set_parent(parent) - makes the
refcounting more clear.

gtk/gtkcssnode.c
gtk/gtkstylecontext.c

index 4e3301046001cd2802665ef57f17dafdf27c219c..fd4c88feabb38ed5fdc43053b7ffbdc798945eac 100644 (file)
 
 G_DEFINE_TYPE (GtkCssNode, gtk_css_node, G_TYPE_OBJECT)
 
+static void
+gtk_css_node_dispose (GObject *object)
+{
+  GtkCssNode *cssnode = GTK_CSS_NODE (object);
+
+  while (cssnode->first_child)
+    {
+      gtk_css_node_set_parent (cssnode->first_child, NULL);
+    }
+
+  G_OBJECT_CLASS (gtk_css_node_parent_class)->dispose (object);
+}
+
 static void
 gtk_css_node_finalize (GObject *object)
 {
@@ -58,6 +71,7 @@ gtk_css_node_class_init (GtkCssNodeClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  object_class->dispose = gtk_css_node_dispose;
   object_class->finalize = gtk_css_node_finalize;
 
   klass->invalidate = gtk_css_node_real_invalidate;
@@ -78,6 +92,9 @@ gtk_css_node_set_parent (GtkCssNode *node,
   if (node->parent == parent)
     return;
 
+  /* Take a reference here so the whole function has a reference */
+  g_object_ref (node);
+
   if (node->parent != NULL)
     {
       if (!GTK_IS_CSS_TRANSIENT_NODE (node))
@@ -98,6 +115,8 @@ gtk_css_node_set_parent (GtkCssNode *node,
       node->parent = NULL;
       node->next_sibling = NULL;
       node->previous_sibling = NULL;
+
+      g_object_unref (node);
     }
 
   if (parent)
@@ -121,6 +140,9 @@ gtk_css_node_set_parent (GtkCssNode *node,
     }
 
   gtk_css_node_invalidate (node, GTK_CSS_CHANGE_ANY_PARENT | GTK_CSS_CHANGE_ANY_SIBLING);
+
+  if (node->parent == NULL)
+    g_object_unref (node);
 }
 
 GtkCssNode *
index 681d9e3f58a69e254327a72e07dd881fba01cb9e..a25b6f08258f81d0969f2b00dbca9a6815bebc66 100644 (file)
@@ -305,6 +305,8 @@ gtk_style_context_pop_style_node (GtkStyleContext *context)
 
   g_return_if_fail (priv->saved_nodes != NULL);
 
+  if (GTK_IS_CSS_TRANSIENT_NODE (priv->cssnode))
+    gtk_css_node_set_parent (priv->cssnode, NULL);
   g_object_unref (priv->cssnode);
   priv->cssnode = priv->saved_nodes->data;
   priv->saved_nodes = g_slist_remove (priv->saved_nodes, priv->cssnode);