summaryrefslogtreecommitdiff
path: root/gtk/gtkstylecontext.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/gtkstylecontext.c')
-rw-r--r--gtk/gtkstylecontext.c147
1 files changed, 109 insertions, 38 deletions
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index d4f909a818..f4bd0d00f7 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -32,11 +32,12 @@
#include "gtkwidget.h"
#include "gtkwindow.h"
#include "gtkprivate.h"
-#include "gtksymboliccolor.h"
+#include "gtksymboliccolorprivate.h"
#include "gtkanimationdescription.h"
#include "gtktimeline.h"
#include "gtkiconfactory.h"
#include "gtkwidgetprivate.h"
+#include "gtkstyleproviderprivate.h"
/**
* SECTION:gtkstylecontext
@@ -371,6 +372,7 @@ struct _GtkStyleContextPrivate
GHashTable *style_data;
GSList *info_stack;
StyleData *current_data;
+ GtkStateFlags current_state;
GSList *animation_regions;
GSList *animations;
@@ -408,6 +410,9 @@ static void gtk_style_context_impl_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
+static GtkSymbolicColor *
+ gtk_style_context_color_lookup_func (gpointer contextp,
+ const char *name);
G_DEFINE_TYPE (GtkStyleContext, gtk_style_context, G_TYPE_OBJECT)
@@ -556,7 +561,6 @@ style_data_new (void)
StyleData *data;
data = g_slice_new0 (StyleData);
- data->store = gtk_style_properties_new ();
return data;
}
@@ -905,18 +909,25 @@ find_next_candidate (GList *local,
static void
build_properties (GtkStyleContext *context,
StyleData *style_data,
- GtkWidgetPath *path)
+ GtkWidgetPath *path,
+ GtkStateFlags state)
{
GtkStyleContextPrivate *priv;
GList *elem, *list, *global_list = NULL;
+ GtkCssLookup *lookup;
priv = context->priv;
- list = priv->providers;
+ list = priv->providers_last;
if (priv->screen)
- global_list = g_object_get_qdata (G_OBJECT (priv->screen), provider_list_quark);
+ {
+ global_list = g_object_get_qdata (G_OBJECT (priv->screen), provider_list_quark);
+ global_list = g_list_last (global_list);
+ }
+
+ lookup = _gtk_css_lookup_new ();
- while ((elem = find_next_candidate (list, global_list, TRUE)) != NULL)
+ while ((elem = find_next_candidate (list, global_list, FALSE)) != NULL)
{
GtkStyleProviderData *data;
GtkStyleProperties *provider_style;
@@ -924,18 +935,37 @@ build_properties (GtkStyleContext *context,
data = elem->data;
if (elem == list)
- list = list->next;
+ list = list->prev;
else
- global_list = global_list->next;
-
- provider_style = gtk_style_provider_get_style (data->provider, path);
+ global_list = global_list->prev;
- if (provider_style)
+ if (GTK_IS_STYLE_PROVIDER_PRIVATE (data->provider))
{
- gtk_style_properties_merge (style_data->store, provider_style, TRUE);
- g_object_unref (provider_style);
+ _gtk_style_provider_private_lookup (GTK_STYLE_PROVIDER_PRIVATE (data->provider),
+ path,
+ state,
+ lookup);
+ }
+ else
+ {
+ provider_style = gtk_style_provider_get_style (data->provider, path);
+
+ if (provider_style)
+ {
+ _gtk_style_provider_private_lookup (GTK_STYLE_PROVIDER_PRIVATE (provider_style),
+ path,
+ state,
+ lookup);
+ g_object_unref (provider_style);
+ }
}
}
+
+ style_data->store = _gtk_css_lookup_resolve (lookup);
+ _gtk_style_properties_set_color_lookup_func (style_data->store,
+ gtk_style_context_color_lookup_func,
+ context);
+ _gtk_css_lookup_free (lookup);
}
static void
@@ -1024,7 +1054,7 @@ style_data_lookup (GtkStyleContext *context,
state_mismatch = ((GtkStyleInfo *) priv->info_stack->data)->state_flags != state;
/* Current data in use is cached, just return it */
- if (priv->current_data && !state_mismatch)
+ if (priv->current_data && priv->current_state == state)
return priv->current_data;
g_assert (priv->widget_path != NULL);
@@ -1044,7 +1074,7 @@ style_data_lookup (GtkStyleContext *context,
data = style_data_new ();
path = create_query_path (context);
- build_properties (context, data, path);
+ build_properties (context, data, path, state);
build_icon_factories (context, data, path);
g_hash_table_insert (priv->style_data,
@@ -1057,12 +1087,9 @@ style_data_lookup (GtkStyleContext *context,
if (G_UNLIKELY (state_mismatch))
{
gtk_style_context_restore (context);
- priv->current_data = NULL;
}
else
{
- priv->current_data = data;
-
if (priv->theming_engine)
g_object_unref (priv->theming_engine);
@@ -1074,6 +1101,9 @@ style_data_lookup (GtkStyleContext *context,
priv->theming_engine = g_object_ref (gtk_theming_engine_load (NULL));
}
+ priv->current_data = data;
+ priv->current_state = state;
+
return data;
}
@@ -1381,7 +1411,7 @@ gtk_style_context_get_property (GtkStyleContext *context,
g_return_if_fail (priv->widget_path != NULL);
data = style_data_lookup (context, state);
- gtk_style_properties_get_property (data->store, property, state, value);
+ gtk_style_properties_get_property (data->store, property, 0, value);
}
void
@@ -1399,7 +1429,7 @@ _gtk_style_context_get_valist (GtkStyleContext *context,
g_return_if_fail (priv->widget_path != NULL);
data = style_data_lookup (context, state);
- _gtk_style_properties_get_valist (data->store, state, property_context, args);
+ _gtk_style_properties_get_valist (data->store, 0, property_context, args);
}
/**
@@ -1426,7 +1456,7 @@ gtk_style_context_get_valist (GtkStyleContext *context,
g_return_if_fail (priv->widget_path != NULL);
data = style_data_lookup (context, state);
- gtk_style_properties_get_valist (data->store, state, args);
+ gtk_style_properties_get_valist (data->store, 0, args);
}
/**
@@ -1457,7 +1487,7 @@ gtk_style_context_get (GtkStyleContext *context,
data = style_data_lookup (context, state);
va_start (args, state);
- gtk_style_properties_get_valist (data->store, state, args);
+ gtk_style_properties_get_valist (data->store, 0, args);
va_end (args);
}
@@ -2688,6 +2718,51 @@ gtk_style_context_get_junction_sides (GtkStyleContext *context)
return info->junction_sides;
}
+static GtkSymbolicColor *
+gtk_style_context_color_lookup_func (gpointer contextp,
+ const char *name)
+{
+ GtkSymbolicColor *sym_color;
+ GtkStyleContext *context = contextp;
+ GtkStyleContextPrivate *priv = context->priv;
+ GList *elem, *list, *global_list = NULL;
+
+ list = priv->providers_last;
+ if (priv->screen)
+ {
+ global_list = g_object_get_qdata (G_OBJECT (priv->screen), provider_list_quark);
+ global_list = g_list_last (global_list);
+ }
+
+ sym_color = NULL;
+
+ while (sym_color == NULL &&
+ (elem = find_next_candidate (list, global_list, FALSE)) != NULL)
+ {
+ GtkStyleProviderData *data;
+
+ data = elem->data;
+
+ if (elem == list)
+ list = list->prev;
+ else
+ global_list = global_list->prev;
+
+ if (GTK_IS_STYLE_PROVIDER_PRIVATE (data->provider))
+ {
+ sym_color = _gtk_style_provider_private_get_color (GTK_STYLE_PROVIDER_PRIVATE (data->provider),
+ name);
+ }
+ else
+ {
+ /* If somebody hits this code path, shout at them */
+ sym_color = NULL;
+ }
+ }
+
+ return sym_color;
+}
+
/**
* gtk_style_context_lookup_color:
* @context: a #GtkStyleContext
@@ -2703,24 +2778,20 @@ gtk_style_context_lookup_color (GtkStyleContext *context,
const gchar *color_name,
GdkRGBA *color)
{
- GtkStyleContextPrivate *priv;
GtkSymbolicColor *sym_color;
- StyleData *data;
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
g_return_val_if_fail (color_name != NULL, FALSE);
g_return_val_if_fail (color != NULL, FALSE);
- priv = context->priv;
- g_return_val_if_fail (priv->widget_path != NULL, FALSE);
-
- data = style_data_lookup (context, 0);
- sym_color = gtk_style_properties_lookup_color (data->store, color_name);
-
- if (!sym_color)
+ sym_color = gtk_style_context_color_lookup_func (context, color_name);
+ if (sym_color == NULL)
return FALSE;
- return gtk_symbolic_color_resolve (sym_color, data->store, color);
+ return _gtk_symbolic_color_resolve_full (sym_color,
+ gtk_style_context_color_lookup_func,
+ context,
+ color);
}
/**
@@ -2827,8 +2898,8 @@ gtk_style_context_notify_state_change (GtkStyleContext *context,
/* Find out if there is any animation description for the given
* state, it will fallback to the normal state as well if necessary.
*/
- data = style_data_lookup (context, state);
- gtk_style_properties_get (data->store, flags,
+ data = style_data_lookup (context, flags);
+ gtk_style_properties_get (data->store, 0,
"transition", &desc,
NULL);
@@ -3374,7 +3445,7 @@ gtk_style_context_get_border (GtkStyleContext *context,
data = style_data_lookup (context, state);
gtk_style_properties_get (data->store,
- state,
+ 0,
"border-style", &border_style,
"border-top-width", &top,
"border-top-width", &top,
@@ -3426,7 +3497,7 @@ gtk_style_context_get_padding (GtkStyleContext *context,
data = style_data_lookup (context, state);
gtk_style_properties_get (data->store,
- state,
+ 0,
"padding-top", &top,
"padding-left", &left,
"padding-bottom", &bottom,
@@ -3467,7 +3538,7 @@ gtk_style_context_get_margin (GtkStyleContext *context,
data = style_data_lookup (context, state);
gtk_style_properties_get (data->store,
- state,
+ 0,
"margin-top", &top,
"margin-left", &left,
"margin-bottom", &bottom,
@@ -3530,7 +3601,7 @@ gtk_style_context_get_font (GtkStyleContext *context,
if (description == NULL)
{
- gtk_style_properties_get (data->store, state, "font", &description, NULL);
+ gtk_style_properties_get (data->store, 0, "font", &description, NULL);
g_hash_table_insert (font_cache, GUINT_TO_POINTER (state), description);
}