diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c index 86c0a07992..6e0b9627bd 100644 --- a/gtk/gtkcssnode.c +++ b/gtk/gtkcssnode.c @@ -33,6 +33,12 @@ gtk_css_node_finalize (GObject *object) G_OBJECT_CLASS (gtk_css_node_parent_class)->finalize (object); } +static void +gtk_css_node_real_invalidate (GtkCssNode *cssnode, + GtkCssChange change) +{ +} + static GtkWidgetPath * gtk_css_node_real_create_widget_path (GtkCssNode *cssnode) { @@ -52,6 +58,7 @@ gtk_css_node_class_init (GtkCssNodeClass *klass) object_class->finalize = gtk_css_node_finalize; + klass->invalidate = gtk_css_node_real_invalidate; klass->create_widget_path = gtk_css_node_real_create_widget_path; klass->get_widget_path = gtk_css_node_real_get_widget_path; } @@ -101,7 +108,8 @@ void gtk_css_node_set_widget_type (GtkCssNode *cssnode, GType widget_type) { - gtk_css_node_declaration_set_type (&cssnode->decl, widget_type); + if (gtk_css_node_declaration_set_type (&cssnode->decl, widget_type)) + gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_NAME); } GType @@ -110,11 +118,12 @@ gtk_css_node_get_widget_type (GtkCssNode *cssnode) return gtk_css_node_declaration_get_type (cssnode->decl); } -gboolean +void gtk_css_node_set_id (GtkCssNode *cssnode, const char *id) { - return gtk_css_node_declaration_set_id (&cssnode->decl, id); + if (gtk_css_node_declaration_set_id (&cssnode->decl, id)) + gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_ID); } const char * @@ -123,11 +132,12 @@ gtk_css_node_get_id (GtkCssNode *cssnode) return gtk_css_node_declaration_get_id (cssnode->decl); } -gboolean +void gtk_css_node_set_state (GtkCssNode *cssnode, GtkStateFlags state_flags) { - return gtk_css_node_declaration_set_state (&cssnode->decl, state_flags); + if (gtk_css_node_declaration_set_state (&cssnode->decl, state_flags)) + gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_STATE); } GtkStateFlags @@ -149,18 +159,20 @@ gtk_css_node_get_junction_sides (GtkCssNode *cssnode) return gtk_css_node_declaration_get_junction_sides (cssnode->decl); } -gboolean +void gtk_css_node_add_class (GtkCssNode *cssnode, GQuark style_class) { - return gtk_css_node_declaration_add_class (&cssnode->decl, style_class); + if (gtk_css_node_declaration_add_class (&cssnode->decl, style_class)) + gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_CLASS); } -gboolean +void gtk_css_node_remove_class (GtkCssNode *cssnode, GQuark style_class) { - return gtk_css_node_declaration_remove_class (&cssnode->decl, style_class); + if (gtk_css_node_declaration_remove_class (&cssnode->decl, style_class)) + gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_CLASS); } gboolean @@ -176,19 +188,21 @@ gtk_css_node_list_classes (GtkCssNode *cssnode) return gtk_css_node_declaration_list_classes (cssnode->decl); } -gboolean +void gtk_css_node_add_region (GtkCssNode *cssnode, GQuark region, GtkRegionFlags flags) { - return gtk_css_node_declaration_add_region (&cssnode->decl, region, flags); + if (gtk_css_node_declaration_add_region (&cssnode->decl, region, flags)) + gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_REGION); } -gboolean +void gtk_css_node_remove_region (GtkCssNode *cssnode, GQuark region) { - return gtk_css_node_declaration_remove_region (&cssnode->decl, region); + if (gtk_css_node_declaration_remove_region (&cssnode->decl, region)) + gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_REGION); } gboolean @@ -218,6 +232,13 @@ gtk_css_node_dup_declaration (GtkCssNode *cssnode) return gtk_css_node_declaration_ref (cssnode->decl); } +void +gtk_css_node_invalidate (GtkCssNode *cssnode, + GtkCssChange change) +{ + GTK_CSS_NODE_GET_CLASS (cssnode)->invalidate (cssnode, change); +} + GtkWidgetPath * gtk_css_node_create_widget_path (GtkCssNode *cssnode) { diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h index fb8bb4de4e..46aafb01a7 100644 --- a/gtk/gtkcssnodeprivate.h +++ b/gtk/gtkcssnodeprivate.h @@ -48,6 +48,8 @@ struct _GtkCssNodeClass GtkWidgetPath * (* create_widget_path) (GtkCssNode *cssnode); const GtkWidgetPath * (* get_widget_path) (GtkCssNode *cssnode); + void (* invalidate) (GtkCssNode *cssnode, + GtkCssChange change); }; GType gtk_css_node_get_type (void) G_GNUC_CONST; @@ -59,26 +61,26 @@ GtkCssNode * gtk_css_node_get_parent (GtkCssNode * void gtk_css_node_set_widget_type (GtkCssNode *cssnode, GType widget_type); GType gtk_css_node_get_widget_type (GtkCssNode *cssnode); -gboolean gtk_css_node_set_id (GtkCssNode *cssnode, +void gtk_css_node_set_id (GtkCssNode *cssnode, const char *id); const char * gtk_css_node_get_id (GtkCssNode *cssnode); -gboolean gtk_css_node_set_state (GtkCssNode *cssnode, +void gtk_css_node_set_state (GtkCssNode *cssnode, GtkStateFlags state_flags); GtkStateFlags gtk_css_node_get_state (GtkCssNode *cssnode); void gtk_css_node_set_junction_sides (GtkCssNode *cssnode, GtkJunctionSides junction_sides); GtkJunctionSides gtk_css_node_get_junction_sides (GtkCssNode *cssnode); -gboolean gtk_css_node_add_class (GtkCssNode *cssnode, +void gtk_css_node_add_class (GtkCssNode *cssnode, GQuark style_class); -gboolean gtk_css_node_remove_class (GtkCssNode *cssnode, +void gtk_css_node_remove_class (GtkCssNode *cssnode, GQuark style_class); gboolean gtk_css_node_has_class (GtkCssNode *cssnode, GQuark style_class); GList * gtk_css_node_list_classes (GtkCssNode *cssnode); -gboolean gtk_css_node_add_region (GtkCssNode *cssnode, +void gtk_css_node_add_region (GtkCssNode *cssnode, GQuark region, GtkRegionFlags flags); -gboolean gtk_css_node_remove_region (GtkCssNode *cssnode, +void gtk_css_node_remove_region (GtkCssNode *cssnode, GQuark region); gboolean gtk_css_node_has_region (GtkCssNode *cssnode, GQuark region, @@ -94,6 +96,8 @@ GtkCssStyle * gtk_css_node_get_style (GtkCssNode * void gtk_css_node_set_style (GtkCssNode *cssnode, GtkCssStyle *style); +void gtk_css_node_invalidate (GtkCssNode *cssnode, + GtkCssChange change); GtkWidgetPath * gtk_css_node_create_widget_path (GtkCssNode *cssnode); const GtkWidgetPath * gtk_css_node_get_widget_path (GtkCssNode *cssnode); diff --git a/gtk/gtkcsspathnode.c b/gtk/gtkcsspathnode.c index 39a2f073a1..2463dc0913 100644 --- a/gtk/gtkcsspathnode.c +++ b/gtk/gtkcsspathnode.c @@ -19,9 +19,26 @@ #include "gtkcsspathnodeprivate.h" #include "gtkprivate.h" +#include "gtkstylecontextprivate.h" G_DEFINE_TYPE (GtkCssPathNode, gtk_css_path_node, GTK_TYPE_CSS_NODE) +static void +gtk_css_path_node_invalidate (GtkCssNode *node, + GtkCssChange change) +{ + GtkCssPathNode *path_node = GTK_CSS_PATH_NODE (node); + + gtk_css_node_set_style (node, NULL); + + if (path_node->context) + { + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + gtk_style_context_invalidate (path_node->context); + G_GNUC_END_IGNORE_DEPRECATIONS; + } +} + static GtkWidgetPath * gtk_css_path_node_real_create_widget_path (GtkCssNode *node) { @@ -58,6 +75,7 @@ gtk_css_path_node_class_init (GtkCssPathNodeClass *klass) { GtkCssNodeClass *node_class = GTK_CSS_NODE_CLASS (klass); + node_class->invalidate = gtk_css_path_node_invalidate; node_class->create_widget_path = gtk_css_path_node_real_create_widget_path; node_class->get_widget_path = gtk_css_path_node_real_get_widget_path; } @@ -68,9 +86,16 @@ gtk_css_path_node_init (GtkCssPathNode *cssnode) } GtkCssNode * -gtk_css_path_node_new (void) +gtk_css_path_node_new (GtkStyleContext *context) { - return g_object_new (GTK_TYPE_CSS_PATH_NODE, NULL); + GtkCssPathNode *node; + + g_return_val_if_fail (context == NULL || GTK_IS_STYLE_CONTEXT (context), NULL); + + node = g_object_new (GTK_TYPE_CSS_PATH_NODE, NULL); + node->context = context; + + return GTK_CSS_NODE (node); } void @@ -89,6 +114,8 @@ gtk_css_path_node_set_widget_path (GtkCssPathNode *node, gtk_widget_path_ref (path); node->path = path; + + gtk_css_node_invalidate (GTK_CSS_NODE (node), GTK_CSS_CHANGE_ANY); } GtkWidgetPath * diff --git a/gtk/gtkcsspathnodeprivate.h b/gtk/gtkcsspathnodeprivate.h index 0ff89e701a..dd3831cc5b 100644 --- a/gtk/gtkcsspathnodeprivate.h +++ b/gtk/gtkcsspathnodeprivate.h @@ -37,6 +37,7 @@ struct _GtkCssPathNode { GtkCssNode node; + GtkStyleContext *context; GtkWidgetPath *path; }; @@ -47,7 +48,7 @@ struct _GtkCssPathNodeClass GType gtk_css_path_node_get_type (void) G_GNUC_CONST; -GtkCssNode * gtk_css_path_node_new (void); +GtkCssNode * gtk_css_path_node_new (GtkStyleContext *context); void gtk_css_path_node_set_widget_path (GtkCssPathNode *node, GtkWidgetPath *path); diff --git a/gtk/gtkcsstransientnode.c b/gtk/gtkcsstransientnode.c index 723c97a426..726a4854b5 100644 --- a/gtk/gtkcsstransientnode.c +++ b/gtk/gtkcsstransientnode.c @@ -22,6 +22,13 @@ G_DEFINE_TYPE (GtkCssTransientNode, gtk_css_transient_node, GTK_TYPE_CSS_NODE) +static void +gtk_css_transient_node_invalidate (GtkCssNode *node, + GtkCssChange change) +{ + gtk_css_node_set_style (node, NULL); +} + static GtkWidgetPath * gtk_css_transient_node_create_widget_path (GtkCssNode *node) { @@ -57,6 +64,7 @@ gtk_css_transient_node_class_init (GtkCssTransientNodeClass *klass) { GtkCssNodeClass *node_class = GTK_CSS_NODE_CLASS (klass); + node_class->invalidate = gtk_css_transient_node_invalidate; node_class->create_widget_path = gtk_css_transient_node_create_widget_path; node_class->get_widget_path = gtk_css_transient_node_get_widget_path; } diff --git a/gtk/gtkcsswidgetnode.c b/gtk/gtkcsswidgetnode.c index c9e156e619..0a4b17bbcc 100644 --- a/gtk/gtkcsswidgetnode.c +++ b/gtk/gtkcsswidgetnode.c @@ -19,10 +19,25 @@ #include "gtkcsswidgetnodeprivate.h" #include "gtkprivate.h" +#include "gtkstylecontextprivate.h" #include "gtkwidgetprivate.h" G_DEFINE_TYPE (GtkCssWidgetNode, gtk_css_widget_node, GTK_TYPE_CSS_NODE) +static void +gtk_css_widget_node_invalidate (GtkCssNode *node, + GtkCssChange change) +{ + GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node); + GtkStyleContext *context; + + if (widget_node->widget == NULL) + return; + + context = gtk_widget_get_style_context (widget_node->widget); + _gtk_style_context_invalidate_root_node (context, change); +} + static GtkWidgetPath * gtk_css_widget_node_create_widget_path (GtkCssNode *node) { @@ -62,6 +77,7 @@ gtk_css_widget_node_class_init (GtkCssWidgetNodeClass *klass) { GtkCssNodeClass *node_class = GTK_CSS_NODE_CLASS (klass); + node_class->invalidate = gtk_css_widget_node_invalidate; node_class->create_widget_path = gtk_css_widget_node_create_widget_path; node_class->get_widget_path = gtk_css_widget_node_get_widget_path; } diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index 0ff387e664..04591121ef 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -356,7 +356,7 @@ gtk_style_context_set_cascade (GtkStyleContext *context, priv->cascade = cascade; - if (cascade) + if (cascade && priv->cssnode != NULL) gtk_style_context_cascade_changed (cascade, context); } @@ -370,14 +370,14 @@ gtk_style_context_init (GtkStyleContext *style_context) priv->screen = gdk_screen_get_default (); - /* Create default info store */ - priv->cssnode = gtk_css_path_node_new (); - gtk_css_node_set_state (priv->cssnode, GTK_STATE_FLAG_DIR_LTR); - priv->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue)); gtk_style_context_set_cascade (style_context, _gtk_settings_get_style_cascade (gtk_settings_get_for_screen (priv->screen), 1)); + + /* Create default info store */ + priv->cssnode = gtk_css_path_node_new (style_context); + gtk_css_node_set_state (priv->cssnode, GTK_STATE_FLAG_DIR_LTR); } static void @@ -873,24 +873,6 @@ gtk_style_context_set_invalid (GtkStyleContext *context, } } -static void -gtk_style_context_queue_invalidate_internal (GtkStyleContext *context, - GtkCssChange change) -{ - GtkStyleContextPrivate *priv = context->priv; - GtkCssNode *cssnode = priv->cssnode; - - if (gtk_style_context_is_saved (context)) - { - gtk_css_node_set_style (cssnode, NULL); - } - else - { - _gtk_style_context_queue_invalidate (context, change); - /* XXX: We need to invalidate siblings here somehow */ - } -} - /** * gtk_style_context_new: * @@ -1291,10 +1273,7 @@ gtk_style_context_set_id (GtkStyleContext *context, { g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); - if (!gtk_css_node_set_id (context->priv->cssnode, id)) - return; - - gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_ID); + gtk_css_node_set_id (context->priv->cssnode, id); } /* @@ -1332,14 +1311,11 @@ gtk_style_context_set_state (GtkStyleContext *context, old_flags = gtk_css_node_get_state (context->priv->cssnode); - if (!gtk_css_node_set_state (context->priv->cssnode, flags)) - return; + gtk_css_node_set_state (context->priv->cssnode, flags); if (((old_flags ^ flags) & (GTK_STATE_FLAG_DIR_LTR | GTK_STATE_FLAG_DIR_RTL)) && !gtk_style_context_is_saved (context)) g_object_notify (G_OBJECT (context), "direction"); - - gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_STATE); } /** @@ -1486,8 +1462,6 @@ gtk_style_context_set_path (GtkStyleContext *context, gtk_css_path_node_set_widget_path (GTK_CSS_PATH_NODE (root), NULL); gtk_css_node_set_widget_type (root, G_TYPE_NONE); } - - _gtk_style_context_queue_invalidate (context, GTK_CSS_CHANGE_ANY); } /** @@ -1668,8 +1642,7 @@ gtk_style_context_add_class (GtkStyleContext *context, priv = context->priv; class_quark = g_quark_from_string (class_name); - if (gtk_css_node_add_class (priv->cssnode, class_quark)) - gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_CLASS); + gtk_css_node_add_class (priv->cssnode, class_quark); } /** @@ -1698,8 +1671,7 @@ gtk_style_context_remove_class (GtkStyleContext *context, priv = context->priv; - if (gtk_css_node_remove_class (priv->cssnode, class_quark)) - gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_CLASS); + gtk_css_node_remove_class (priv->cssnode, class_quark); } /** @@ -1873,8 +1845,7 @@ gtk_style_context_add_region (GtkStyleContext *context, priv = context->priv; region_quark = g_quark_from_string (region_name); - if (gtk_css_node_add_region (priv->cssnode, region_quark, flags)) - gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_REGION); + gtk_css_node_add_region (priv->cssnode, region_quark, flags); } /** @@ -1905,8 +1876,7 @@ gtk_style_context_remove_region (GtkStyleContext *context, priv = context->priv; - if (gtk_css_node_remove_region (priv->cssnode, region_quark)) - gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_REGION); + gtk_css_node_remove_region (priv->cssnode, region_quark); } /** @@ -3007,28 +2977,24 @@ _gtk_style_context_validate (GtkStyleContext *context, _gtk_bitmask_free (changes); } +void +_gtk_style_context_invalidate_root_node (GtkStyleContext *context, + GtkCssChange change) +{ + GtkStyleContextPrivate *priv = context->priv; + + priv->pending_changes |= change; + gtk_style_context_set_invalid (context, TRUE); +} + void _gtk_style_context_queue_invalidate (GtkStyleContext *context, GtkCssChange change) { - GtkStyleContextPrivate *priv; - g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (change != 0); - priv = context->priv; - - if (GTK_IS_CSS_WIDGET_NODE (priv->cssnode)) - { - priv->pending_changes |= change; - gtk_style_context_set_invalid (context, TRUE); - } - else if (GTK_IS_CSS_PATH_NODE (priv->cssnode)) - { - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - gtk_style_context_invalidate (context); - G_GNUC_END_IGNORE_DEPRECATIONS; - } + gtk_css_node_invalidate (gtk_style_context_get_root (context), change); } /** diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h index a520bf73b2..59abbc673c 100644 --- a/gtk/gtkstylecontextprivate.h +++ b/gtk/gtkstylecontextprivate.h @@ -48,6 +48,8 @@ void _gtk_style_context_validate (GtkStyleContext *c const GtkBitmask*parent_changes); void _gtk_style_context_queue_invalidate (GtkStyleContext *context, GtkCssChange change); +void _gtk_style_context_invalidate_root_node (GtkStyleContext *context, + GtkCssChange change); gboolean _gtk_style_context_check_region_name (const gchar *str); gboolean _gtk_style_context_resolve_color (GtkStyleContext *context,