GTK_CSS_NODE_GET_CLASS (node)->dequeue_validate (node);
}
-void
-gtk_css_node_set_parent (GtkCssNode *node,
- GtkCssNode *parent)
+static void
+gtk_css_node_unlink_from_siblings (GtkCssNode *node)
{
- if (node->parent == parent)
+ if (GTK_IS_CSS_TRANSIENT_NODE (node))
return;
- /* Take a reference here so the whole function has a reference */
- g_object_ref (node);
+ if (node->previous_sibling)
+ node->previous_sibling->next_sibling = node->next_sibling;
+ else
+ node->parent->first_child = node->next_sibling;
- if (node->parent != NULL)
+ if (node->next_sibling)
+ node->next_sibling->previous_sibling = node->previous_sibling;
+ else
+ node->parent->last_child = node->previous_sibling;
+
+ node->previous_sibling = NULL;
+ node->next_sibling = NULL;
+}
+
+static void
+gtk_css_node_link_to_siblings (GtkCssNode *node,
+ GtkCssNode *new_previous)
+{
+ if (GTK_IS_CSS_TRANSIENT_NODE (node))
+ return;
+
+ if (new_previous)
{
- if (!GTK_IS_CSS_TRANSIENT_NODE (node))
- {
- if (node->previous_sibling)
- node->previous_sibling->next_sibling = node->next_sibling;
- else
- node->parent->first_child = node->next_sibling;
+ node->previous_sibling = new_previous;
+ node->next_sibling = new_previous->next_sibling;
+ new_previous->next_sibling = node;
+ }
+ else
+ {
+ node->next_sibling = node->parent->first_child;
+ node->parent->first_child = node;
+ }
+
+ if (node->next_sibling)
+ node->next_sibling->previous_sibling = node;
+ else
+ node->parent->last_child = node;
+}
- if (node->next_sibling)
- node->next_sibling->previous_sibling = node->previous_sibling;
- else
- node->parent->last_child = node->previous_sibling;
+static void
+gtk_css_node_set_children_changed (GtkCssNode *node)
+{
+ if (node->children_changed)
+ return;
- node->parent->n_children--;
- }
+ node->children_changed = TRUE;
+ gtk_css_node_set_invalid (node, TRUE);
+}
- node->parent = NULL;
- node->next_sibling = NULL;
- node->previous_sibling = NULL;
+static void
+gtk_css_node_reposition (GtkCssNode *node,
+ GtkCssNode *parent,
+ GtkCssNode *previous)
+{
+ g_assert (! (parent == NULL && previous != NULL));
- g_object_unref (node);
+ /* Take a reference here so the whole function has a reference */
+ g_object_ref (node);
- if (parent == NULL)
- gtk_css_node_parent_was_unset (node);
- }
+ if (node->parent != NULL)
+ gtk_css_node_unlink_from_siblings (node);
- if (parent)
+ if (node->parent != parent)
{
if (node->parent == NULL)
- gtk_css_node_parent_will_be_set (node);
+ {
+ gtk_css_node_parent_will_be_set (node);
+ }
+ else
+ {
+ g_object_unref (node);
+ gtk_css_node_set_children_changed (node->parent);
+ }
node->parent = parent;
- if (!GTK_IS_CSS_TRANSIENT_NODE (node))
+ if (parent)
{
- parent->n_children++;
+ gtk_css_node_set_children_changed (parent);
+ g_object_ref (node);
- if (parent->last_child)
- {
- parent->last_child->next_sibling = node;
- node->previous_sibling = parent->last_child;
- }
- parent->last_child = node;
-
- if (parent->first_child == NULL)
- parent->first_child = node;
+ if (node->invalid)
+ gtk_css_node_set_invalid (parent, TRUE);
+ }
+ else
+ {
+ gtk_css_node_parent_was_unset (node);
}
-
- if (node->invalid)
- gtk_css_node_set_invalid (parent, TRUE);
}
+ if (parent)
+ gtk_css_node_link_to_siblings (node, previous);
+
gtk_css_node_invalidate (node, GTK_CSS_CHANGE_ANY_PARENT | GTK_CSS_CHANGE_ANY_SIBLING);
- if (node->parent == NULL)
- g_object_unref (node);
+ g_object_unref (node);
+}
+
+void
+gtk_css_node_set_parent (GtkCssNode *node,
+ GtkCssNode *parent)
+{
+ if (node->parent == parent)
+ return;
+
+ gtk_css_node_reposition (node, parent, parent ? parent->last_child : NULL);
}
GtkCssNode *
return;
change = _gtk_css_change_for_child (cssnode->pending_changes);
+ if (cssnode->children_changed)
+ {
+ change |= GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_ANY_SIBLING;
+ cssnode->children_changed = FALSE;
+ }
for (child = gtk_css_node_get_first_child (cssnode);
child;
if (G_UNLIKELY (gtk_get_debug_flags () & GTK_DEBUG_NO_CSS_CACHE))
change = GTK_CSS_CHANGE_ANY;
+ gtk_css_node_propagate_pending_changes (cssnode);
+
if (!cssnode->invalid && change == 0 && _gtk_bitmask_is_empty (parent_changes))
return;
- gtk_css_node_propagate_pending_changes (cssnode);
-
gtk_css_node_set_invalid (cssnode, FALSE);
change = cssnode->pending_changes;