From dbb8d1dd07a91171ba4a32119713c05e0483de91 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 20 Jan 2015 00:33:34 +0100 Subject: [PATCH] stylecontext: Keep track of the CSS ID This is necessary since we do the new caching and need to distinguish between styles with different IDs. Fixes various test cases. --- gtk/gtkcssnodedeclaration.c | 27 ++++++++++++++++++++++ gtk/gtkcssnodedeclarationprivate.h | 3 +++ gtk/gtkstylecontext.c | 36 ++++++++++++++++++++++++++++++ gtk/gtkstylecontextprivate.h | 4 ++++ gtk/gtkwidget.c | 4 +++- 5 files changed, 73 insertions(+), 1 deletion(-) diff --git a/gtk/gtkcssnodedeclaration.c b/gtk/gtkcssnodedeclaration.c index e5c718708a..989ad94fd4 100644 --- a/gtk/gtkcssnodedeclaration.c +++ b/gtk/gtkcssnodedeclaration.c @@ -33,6 +33,7 @@ struct _GtkCssNodeDeclaration { guint refcount; GtkJunctionSides junction_sides; GType type; + const /* interened */ char *id; GtkStateFlags state; guint n_classes; guint n_regions; @@ -180,6 +181,27 @@ gtk_css_node_declaration_get_type (const GtkCssNodeDeclaration *decl) return decl->type; } +gboolean +gtk_css_node_declaration_set_id (GtkCssNodeDeclaration **decl, + const char *id) +{ + id = g_intern_string (id); + + if ((*decl)->id == id) + return FALSE; + + gtk_css_node_declaration_make_writable (decl); + (*decl)->id = id; + + return TRUE; +} + +const char * +gtk_css_node_declaration_get_id (const GtkCssNodeDeclaration *decl) +{ + return decl->id; +} + gboolean gtk_css_node_declaration_set_state (GtkCssNodeDeclaration **decl, GtkStateFlags state) @@ -447,6 +469,8 @@ gtk_css_node_declaration_hash (gconstpointer elem) guint hash, i; hash = (guint) decl->type; + hash <<= 5; + hash ^= GPOINTER_TO_UINT (decl->id); classes = get_classes (decl); for (i = 0; i < decl->n_classes; i++) @@ -488,6 +512,9 @@ gtk_css_node_declaration_equal (gconstpointer elem1, if (decl1->state != decl2->state) return FALSE; + if (decl1->id != decl2->id) + return FALSE; + if (decl1->n_classes != decl2->n_classes) return FALSE; diff --git a/gtk/gtkcssnodedeclarationprivate.h b/gtk/gtkcssnodedeclarationprivate.h index 56323ac506..f2679748c8 100644 --- a/gtk/gtkcssnodedeclarationprivate.h +++ b/gtk/gtkcssnodedeclarationprivate.h @@ -36,6 +36,9 @@ GtkJunctionSides gtk_css_node_declaration_get_junction_sides (const G gboolean gtk_css_node_declaration_set_type (GtkCssNodeDeclaration **decl, GType type); GType gtk_css_node_declaration_get_type (const GtkCssNodeDeclaration *decl); +gboolean gtk_css_node_declaration_set_id (GtkCssNodeDeclaration **decl, + const char *id); +const char * gtk_css_node_declaration_get_id (const GtkCssNodeDeclaration *decl); gboolean gtk_css_node_declaration_set_state (GtkCssNodeDeclaration **decl, GtkStateFlags flags); GtkStateFlags gtk_css_node_declaration_get_state (const GtkCssNodeDeclaration *decl); diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index f107a73c50..dc185bfb81 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -1338,6 +1338,42 @@ gtk_style_context_get (GtkStyleContext *context, va_end (args); } +/* + * gtk_style_context_set_id: + * @context: a #GtkStyleContext + * @id: (allow-none): the id to use or %NULL for none. + * + * Sets the CSS ID to be used when rendering with any + * of the gtk_render_*() functions. + **/ +void +gtk_style_context_set_id (GtkStyleContext *context, + const char *id) +{ + g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); + + if (!gtk_css_node_declaration_set_id (&context->priv->cssnode->decl, id)) + return; + + gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_ID); +} + +/* + * gtk_style_context_get_id: + * @context: a #GtkStyleContext + * + * Returns the CSS ID used when rendering. + * + * Returns: the ID or %NULL if no ID is set. + **/ +const char * +gtk_style_context_get_id (GtkStyleContext *context) +{ + g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL); + + return gtk_css_node_declaration_get_id (context->priv->cssnode->decl); +} + /** * gtk_style_context_set_state: * @context: a #GtkStyleContext diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h index 4b9486693b..45f8ad27c3 100644 --- a/gtk/gtkstylecontextprivate.h +++ b/gtk/gtkstylecontextprivate.h @@ -29,6 +29,10 @@ G_BEGIN_DECLS void _gtk_style_context_set_widget (GtkStyleContext *context, GtkWidget *widget); +void gtk_style_context_set_id (GtkStyleContext *context, + const char *id); +const char * gtk_style_context_get_id (GtkStyleContext *context); + const GtkBitmask * _gtk_style_context_get_changes (GtkStyleContext *context); diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 65fd0959ff..66ad052db5 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -8712,7 +8712,8 @@ gtk_widget_set_name (GtkWidget *widget, g_free (priv->name); priv->name = new_name; - _gtk_widget_invalidate_style_context (widget, GTK_CSS_CHANGE_NAME); + if (priv->context) + gtk_style_context_set_id (priv->context, priv->name); g_object_notify (G_OBJECT (widget), "name"); } @@ -16370,6 +16371,7 @@ gtk_widget_get_style_context (GtkWidget *widget) priv->context = gtk_style_context_new (); + gtk_style_context_set_id (priv->context, priv->name); gtk_style_context_set_state (priv->context, priv->state_flags); gtk_style_context_set_scale (priv->context, gtk_widget_get_scale_factor (widget));