diff --git a/gtk/gtkcssshorthandpropertyimpl.c b/gtk/gtkcssshorthandpropertyimpl.c index 02ff992000..467f34f332 100644 --- a/gtk/gtkcssshorthandpropertyimpl.c +++ b/gtk/gtkcssshorthandpropertyimpl.c @@ -30,6 +30,7 @@ #include "gtkcsstypesprivate.h" #include "gtkprivatetypebuiltins.h" #include "gtkstylepropertiesprivate.h" +#include "gtksymboliccolorprivate.h" #include "gtktypebuiltins.h" /* this is in case round() is not provided by the compiler, @@ -161,19 +162,18 @@ parse_border_color (GtkCssShorthandProperty *shorthand, { if (_gtk_css_parser_try (parser, "currentcolor", TRUE)) { - g_value_init (&values[i], GTK_TYPE_CSS_SPECIAL_VALUE); - g_value_set_enum (&values[i], GTK_CSS_CURRENT_COLOR); + symbolic = gtk_symbolic_color_ref (_gtk_symbolic_color_get_current_color ()); } else { symbolic = _gtk_css_parser_read_symbolic_color (parser); if (symbolic == NULL) return FALSE; - - g_value_init (&values[i], GTK_TYPE_SYMBOLIC_COLOR); - g_value_set_boxed (&values[i], symbolic); } + g_value_init (&values[i], GTK_TYPE_SYMBOLIC_COLOR); + g_value_set_boxed (&values[i], symbolic); + if (value_is_done_parsing (parser)) break; } diff --git a/gtk/gtkcssstylefuncs.c b/gtk/gtkcssstylefuncs.c index 6078d76427..b46b9b0c99 100644 --- a/gtk/gtkcssstylefuncs.c +++ b/gtk/gtkcssstylefuncs.c @@ -37,6 +37,7 @@ #include "gtkprivatetypebuiltins.h" #include "gtkshadowprivate.h" #include "gtkstylecontextprivate.h" +#include "gtksymboliccolorprivate.h" #include "gtkthemingengine.h" #include "gtktypebuiltins.h" #include "gtkwin32themeprivate.h" @@ -173,15 +174,14 @@ rgba_value_parse (GtkCssParser *parser, if (_gtk_css_parser_try (parser, "currentcolor", TRUE)) { - g_value_unset (value); - g_value_init (value, GTK_TYPE_CSS_SPECIAL_VALUE); - g_value_set_enum (value, GTK_CSS_CURRENT_COLOR); - return TRUE; + symbolic = gtk_symbolic_color_ref (_gtk_symbolic_color_get_current_color ()); + } + else + { + symbolic = _gtk_css_parser_read_symbolic_color (parser); + if (symbolic == NULL) + return FALSE; } - - symbolic = _gtk_css_parser_read_symbolic_color (parser); - if (symbolic == NULL) - return FALSE; if (gtk_symbolic_color_resolve (symbolic, NULL, &rgba)) { @@ -223,14 +223,16 @@ rgba_value_compute (GValue *computed, if (G_VALUE_HOLDS (specified, GTK_TYPE_CSS_SPECIAL_VALUE)) { - g_assert (g_value_get_enum (specified) == GTK_CSS_CURRENT_COLOR); - g_value_copy (_gtk_style_context_peek_property (context, "color"), computed); } else if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR)) { - if (_gtk_style_context_resolve_color (context, - g_value_get_boxed (specified), - &rgba)) + GtkSymbolicColor *symbolic = g_value_get_boxed (specified); + + if (symbolic == _gtk_symbolic_color_get_current_color ()) + g_value_copy (_gtk_style_context_peek_property (context, "color"), computed); + else if (_gtk_style_context_resolve_color (context, + symbolic, + &rgba)) g_value_set_boxed (computed, &rgba); else g_value_set_boxed (computed, &white); diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c index fbc0fc211d..f4b95fbef4 100644 --- a/gtk/gtkcssstylepropertyimpl.c +++ b/gtk/gtkcssstylepropertyimpl.c @@ -39,6 +39,7 @@ #include "gtkcssimageprivate.h" #include "gtkgradient.h" #include "gtkshadowprivate.h" +#include "gtksymboliccolorprivate.h" #include "gtkthemingengine.h" #include "gtktypebuiltins.h" #include "gtkwin32themeprivate.h" @@ -56,43 +57,45 @@ color_compute (GtkCssStyleProperty *property, /* for when resolvage fails */ restart: - if (G_VALUE_HOLDS (specified, GTK_TYPE_CSS_SPECIAL_VALUE)) - { - g_assert (g_value_get_enum (specified) == GTK_CSS_CURRENT_COLOR); - - /* The computed value of the ‘currentColor’ keyword is the computed - * value of the ‘color’ property. If the ‘currentColor’ keyword is - * set on the ‘color’ property itself, it is treated as ‘color: inherit’. - */ - if (g_str_equal (_gtk_style_property_get_name (GTK_STYLE_PROPERTY (property)), "color")) - { - GtkStyleContext *parent = gtk_style_context_get_parent (context); - - if (parent) - g_value_copy (_gtk_style_context_peek_property (parent, "color"), computed); - else - _gtk_css_style_compute_value (computed, - context, - _gtk_css_style_property_get_initial_value (property)); - } - else - { - g_value_copy (_gtk_style_context_peek_property (context, "color"), computed); - } - } - else if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR)) + if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR)) { + GtkSymbolicColor *symbolic = g_value_get_boxed (specified); GdkRGBA rgba; - if (!_gtk_style_context_resolve_color (context, - g_value_get_boxed (specified), - &rgba)) + if (symbolic == _gtk_symbolic_color_get_current_color ()) + { + /* The computed value of the ‘currentColor’ keyword is the computed + * value of the ‘color’ property. If the ‘currentColor’ keyword is + * set on the ‘color’ property itself, it is treated as ‘color: inherit’. + */ + if (g_str_equal (_gtk_style_property_get_name (GTK_STYLE_PROPERTY (property)), "color")) + { + GtkStyleContext *parent = gtk_style_context_get_parent (context); + + if (parent) + g_value_copy (_gtk_style_context_peek_property (parent, "color"), computed); + else + _gtk_css_style_compute_value (computed, + context, + _gtk_css_style_property_get_initial_value (property)); + } + else + { + g_value_copy (_gtk_style_context_peek_property (context, "color"), computed); + } + } + else if (_gtk_style_context_resolve_color (context, + symbolic, + &rgba)) + { + g_value_set_boxed (computed, &rgba); + } + else { specified = _gtk_css_style_property_get_initial_value (property); goto restart; } - g_value_set_boxed (computed, &rgba); } else g_value_copy (specified, computed); @@ -819,8 +822,8 @@ _gtk_css_style_property_init_properties (void) NULL, GTK_CSS_AREA_PADDING_BOX); - g_value_init (&value, GTK_TYPE_CSS_SPECIAL_VALUE); - g_value_set_enum (&value, GTK_CSS_CURRENT_COLOR); + g_value_init (&value, GTK_TYPE_SYMBOLIC_COLOR); + g_value_set_boxed (&value, _gtk_symbolic_color_get_current_color ()); _gtk_style_property_register ("border-top-color", GDK_TYPE_RGBA, 0, diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h index d36d41c268..6754d05aa5 100644 --- a/gtk/gtkcsstypesprivate.h +++ b/gtk/gtkcsstypesprivate.h @@ -26,8 +26,7 @@ G_BEGIN_DECLS typedef enum { GTK_CSS_INHERIT, - GTK_CSS_INITIAL, - GTK_CSS_CURRENT_COLOR /*< nick=currentColor >*/ + GTK_CSS_INITIAL } GtkCssSpecialValue; /* We encode horizontal and vertical repeat in one enum value. diff --git a/gtk/gtksymboliccolor.c b/gtk/gtksymboliccolor.c index 992b7a96fa..c99b9bc1e6 100644 --- a/gtk/gtksymboliccolor.c +++ b/gtk/gtksymboliccolor.c @@ -52,7 +52,8 @@ typedef enum { COLOR_TYPE_SHADE, COLOR_TYPE_ALPHA, COLOR_TYPE_MIX, - COLOR_TYPE_WIN32 + COLOR_TYPE_WIN32, + COLOR_TYPE_CURRENT_COLOR } ColorType; struct _GtkSymbolicColor @@ -267,6 +268,30 @@ gtk_symbolic_color_new_win32 (const gchar *theme_class, return symbolic_color; } +/** + * _gtk_symbolic_color_get_current_color: + * + * Gets the color representing the CSS 'currentColor' keyword. + * This color will resolve to the color set for the color property. + * + * Returns: (transfer none): The singleton representing the + * 'currentColor' keyword + **/ +GtkSymbolicColor * +_gtk_symbolic_color_get_current_color (void) +{ + static GtkSymbolicColor *current_color = NULL; + + if (G_UNLIKELY (current_color == NULL)) + { + current_color = g_slice_new0 (GtkSymbolicColor); + current_color->type = COLOR_TYPE_CURRENT_COLOR; + current_color->ref_count = 1; + } + + return current_color; +} + /** * gtk_symbolic_color_ref: * @color: a #GtkSymbolicColor @@ -628,6 +653,9 @@ _gtk_symbolic_color_resolve_full (GtkSymbolicColor *color, color->win32.id, resolved_color); + break; + case COLOR_TYPE_CURRENT_COLOR: + return FALSE; break; default: g_assert_not_reached (); @@ -701,6 +729,9 @@ gtk_symbolic_color_to_string (GtkSymbolicColor *color) color->win32.theme_class, color->win32.id); } break; + case COLOR_TYPE_CURRENT_COLOR: + s = g_strdup ("currentColor"); + break; default: g_assert_not_reached (); } diff --git a/gtk/gtksymboliccolorprivate.h b/gtk/gtksymboliccolorprivate.h index 1216a49317..78880d0dbd 100644 --- a/gtk/gtksymboliccolorprivate.h +++ b/gtk/gtksymboliccolorprivate.h @@ -31,6 +31,8 @@ gboolean _gtk_symbolic_color_resolve_full (GtkSymbolicColor gpointer data, GdkRGBA *resolved_color); +GtkSymbolicColor * _gtk_symbolic_color_get_current_color (void); + G_END_DECLS #endif /* __GTK_SYMBOLIC_COLOR_PRIVATE_H__ */