diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c index 6e0b9627bd..4e33010460 100644 --- a/gtk/gtkcssnode.c +++ b/gtk/gtkcssnode.c @@ -19,6 +19,8 @@ #include "gtkcssnodeprivate.h" +#include "gtkcsstransientnodeprivate.h" + G_DEFINE_TYPE (GtkCssNode, gtk_css_node, G_TYPE_OBJECT) static void @@ -70,10 +72,55 @@ gtk_css_node_init (GtkCssNode *cssnode) } void -gtk_css_node_set_parent (GtkCssNode *cssnode, +gtk_css_node_set_parent (GtkCssNode *node, GtkCssNode *parent) { - cssnode->parent = parent; + if (node->parent == parent) + return; + + if (node->parent != NULL) + { + 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; + + if (node->next_sibling) + node->next_sibling->previous_sibling = node->previous_sibling; + else + node->parent->last_child = node->previous_sibling; + + node->parent->n_children--; + } + + node->parent = NULL; + node->next_sibling = NULL; + node->previous_sibling = NULL; + } + + if (parent) + { + node->parent = parent; + + if (!GTK_IS_CSS_TRANSIENT_NODE (node)) + { + parent->n_children++; + + 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; + } + } + + gtk_css_node_invalidate (node, GTK_CSS_CHANGE_ANY_PARENT | GTK_CSS_CHANGE_ANY_SIBLING); } GtkCssNode * @@ -82,6 +129,30 @@ gtk_css_node_get_parent (GtkCssNode *cssnode) return cssnode->parent; } +GtkCssNode * +gtk_css_node_get_first_child (GtkCssNode *cssnode) +{ + return cssnode->first_child; +} + +GtkCssNode * +gtk_css_node_get_last_child (GtkCssNode *cssnode) +{ + return cssnode->last_child; +} + +GtkCssNode * +gtk_css_node_get_previous_sibling (GtkCssNode *cssnode) +{ + return cssnode->previous_sibling; +} + +GtkCssNode * +gtk_css_node_get_next_sibling (GtkCssNode *cssnode) +{ + return cssnode->next_sibling; +} + void gtk_css_node_set_style (GtkCssNode *cssnode, GtkCssStyle *style) diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h index 46aafb01a7..c00c8754da 100644 --- a/gtk/gtkcssnodeprivate.h +++ b/gtk/gtkcssnodeprivate.h @@ -37,8 +37,14 @@ struct _GtkCssNode { GObject object; + GtkCssNode *parent; + GtkCssNode *previous_sibling; + GtkCssNode *next_sibling; + GtkCssNode *first_child; + GtkCssNode *last_child; + guint n_children; + GtkCssNodeDeclaration *decl; - GtkCssNode *parent; GtkCssStyle *style; }; @@ -57,6 +63,10 @@ GType gtk_css_node_get_type (void) G_GNUC_CONST; void gtk_css_node_set_parent (GtkCssNode *cssnode, GtkCssNode *parent); GtkCssNode * gtk_css_node_get_parent (GtkCssNode *cssnode); +GtkCssNode * gtk_css_node_get_first_child (GtkCssNode *cssnode); +GtkCssNode * gtk_css_node_get_last_child (GtkCssNode *cssnode); +GtkCssNode * gtk_css_node_get_previous_sibling(GtkCssNode *cssnode); +GtkCssNode * gtk_css_node_get_next_sibling (GtkCssNode *cssnode); void gtk_css_node_set_widget_type (GtkCssNode *cssnode, GType widget_type); diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index 3b5e4cd07c..681d9e3f58 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -288,22 +288,14 @@ static GtkCssStyle * gtk_css_node_get_parent_style (GtkStyleContext *context, GtkCssNode *cssnode) { - GtkStyleContextPrivate *priv; GtkCssNode *parent; parent = gtk_css_node_get_parent (cssnode); - g_assert (parent == NULL || gtk_css_node_get_style (parent) != NULL); - - if (parent) - return gtk_css_node_get_style (parent); - - priv = context->priv; - - if (priv->parent) - return gtk_style_context_lookup_style (priv->parent); - - return NULL; + if (parent == NULL) + return NULL; + + return gtk_css_node_get_style (parent); } static void @@ -1513,6 +1505,12 @@ gtk_style_context_set_parent (GtkStyleContext *context, g_object_ref (parent); if (priv->invalid) gtk_style_context_set_invalid (parent, TRUE); + gtk_css_node_set_parent (gtk_style_context_get_root (context), + gtk_style_context_get_root (parent)); + } + else + { + gtk_css_node_set_parent (gtk_style_context_get_root (context), NULL); } gtk_style_context_clear_parent (context); diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 25ba751bf6..00c8c4b6d6 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -16444,11 +16444,11 @@ gtk_widget_get_style_context (GtkWidget *widget) if (frame_clock) gtk_style_context_set_frame_clock (priv->context, frame_clock); + _gtk_style_context_set_widget (priv->context, widget); + if (priv->parent) gtk_style_context_set_parent (priv->context, gtk_widget_get_style_context (priv->parent)); - - _gtk_style_context_set_widget (priv->context, widget); } return widget->priv->context;