diff options
author | Benjamin Otte <otte@redhat.com> | 2012-03-16 05:14:41 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2012-04-17 08:59:07 +0200 |
commit | a2ded8b72a430b388d39718a920bf44413c1836c (patch) | |
tree | 85a736f0c9a884c66b898548de885a4d76525092 | |
parent | 015e3a768f10e01f27adb426f78d76edcad5f89e (diff) | |
download | gtk+-a2ded8b72a430b388d39718a920bf44413c1836c.tar.gz |
styleprovider: Add a custom object for a list of style providers
This way, we don't have to do magic inside GtkStyleContext, but have a
real API.
As a cute bonus, this object implements GtkStyleProvider itself. So we
can just pretend there's only one provider.
-rw-r--r-- | gtk/Makefile.am | 2 | ||||
-rw-r--r-- | gtk/gtkstylecascade.c | 352 | ||||
-rw-r--r-- | gtk/gtkstylecascadeprivate.h | 66 | ||||
-rw-r--r-- | gtk/gtkstylecontext.c | 365 |
4 files changed, 491 insertions, 294 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 1f450284a5..e062c9ad29 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -490,6 +490,7 @@ gtk_private_h_sources = \ gtkshadowprivate.h \ gtksizegroup-private.h \ gtksocketprivate.h \ + gtkstylecascadeprivate.h \ gtkstylecontextprivate.h \ gtkstylepropertiesprivate.h \ gtkstylepropertyprivate.h \ @@ -755,6 +756,7 @@ gtk_base_c_sources = \ gtkstatusbar.c \ gtkstatusicon.c \ gtkstock.c \ + gtkstylecascade.c \ gtkstylecontext.c \ gtkstyleproperties.c \ gtkstyleproperty.c \ diff --git a/gtk/gtkstylecascade.c b/gtk/gtkstylecascade.c new file mode 100644 index 0000000000..0c427ce819 --- /dev/null +++ b/gtk/gtkstylecascade.c @@ -0,0 +1,352 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2012 Benjamin Otte <otte@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "gtkstylecascadeprivate.h" + +#include "gtkstyleprovider.h" +#include "gtkstyleproviderprivate.h" + +typedef struct _GtkStyleCascadeIter GtkStyleCascadeIter; +typedef struct _GtkStyleProviderData GtkStyleProviderData; + +struct _GtkStyleCascadeIter { + int parent_index; /* pointing at last index that was returned, not next one that should be returned */ + int index; /* pointing at last index that was returned, not next one that should be returned */ +}; + +struct _GtkStyleProviderData +{ + GtkStyleProvider *provider; + guint priority; +}; + +static GtkStyleProvider * +gtk_style_cascade_iter_next (GtkStyleCascade *cascade, + GtkStyleCascadeIter *iter) +{ + if (iter->parent_index > 0) + { + if (iter->index > 0) + { + GtkStyleProviderData *data, *parent_data; + + data = &g_array_index (cascade->providers, GtkStyleProviderData, iter->index - 1); + parent_data = &g_array_index (cascade->parent->providers, GtkStyleProviderData, iter->parent_index - 1); + + if (data->priority >= parent_data->priority) + { + iter->index--; + return data->provider; + } + else + { + iter->parent_index--; + return parent_data->provider; + } + } + else + { + iter->parent_index--; + return g_array_index (cascade->parent->providers, GtkStyleProviderData, iter->parent_index).provider; + } + } + else + { + if (iter->index > 0) + { + iter->index--; + return g_array_index (cascade->providers, GtkStyleProviderData, iter->index).provider; + } + else + { + return NULL; + } + } +} + +static GtkStyleProvider * +gtk_style_cascade_iter_init (GtkStyleCascade *cascade, + GtkStyleCascadeIter *iter) +{ + iter->parent_index = cascade->parent ? cascade->parent->providers->len : 0; + iter->index = cascade->providers->len; + + return gtk_style_cascade_iter_next (cascade, iter); +} + +static GtkStyleProperties * +gtk_style_cascade_get_style (GtkStyleProvider *provider, + GtkWidgetPath *path) +{ + /* This function is not used anymore by GTK and nobody + * else is ever supposed to call it */ + g_warn_if_reached (); + return NULL; +} + +static gboolean +gtk_style_cascade_get_style_property (GtkStyleProvider *provider, + GtkWidgetPath *path, + GtkStateFlags state, + GParamSpec *pspec, + GValue *value) +{ + GtkStyleCascade *cascade = GTK_STYLE_CASCADE (provider); + GtkStyleCascadeIter iter; + GtkStyleProvider *item; + + for (item = gtk_style_cascade_iter_init (cascade, &iter); + item; + item = gtk_style_cascade_iter_next (cascade, &iter)) + { + if (gtk_style_provider_get_style_property (item, + path, + state, + pspec, + value)) + return TRUE; + } + + return FALSE; +} + +static GtkIconFactory * +gtk_style_cascade_get_icon_factory (GtkStyleProvider *provider, + GtkWidgetPath *path) +{ + /* If anyone ever implements get_icon_factory(), I'll + * look at this function. Until then I'll just: */ + return NULL; +} + +static void +gtk_style_cascade_provider_iface_init (GtkStyleProviderIface *iface) +{ + iface->get_style = gtk_style_cascade_get_style; + iface->get_style_property = gtk_style_cascade_get_style_property; + iface->get_icon_factory = gtk_style_cascade_get_icon_factory; +} + +static GtkSymbolicColor * +gtk_style_cascade_get_color (GtkStyleProviderPrivate *provider, + const char *name) +{ + GtkStyleCascade *cascade = GTK_STYLE_CASCADE (provider); + GtkStyleCascadeIter iter; + GtkSymbolicColor *symbolic; + GtkStyleProvider *item; + + for (item = gtk_style_cascade_iter_init (cascade, &iter); + item; + item = gtk_style_cascade_iter_next (cascade, &iter)) + { + if (GTK_IS_STYLE_PROVIDER_PRIVATE (item)) + { + symbolic = _gtk_style_provider_private_get_color (GTK_STYLE_PROVIDER_PRIVATE (item), name); + if (symbolic) + return symbolic; + } + else + { + /* If somebody hits this code path, shout at them */ + } + } + + return NULL; +} + +static void +gtk_style_cascade_lookup (GtkStyleProviderPrivate *provider, + GtkWidgetPath *path, + GtkStateFlags state, + GtkCssLookup *lookup) +{ + GtkStyleCascade *cascade = GTK_STYLE_CASCADE (provider); + GtkStyleCascadeIter iter; + GtkStyleProvider *item; + + for (item = gtk_style_cascade_iter_init (cascade, &iter); + item; + item = gtk_style_cascade_iter_next (cascade, &iter)) + { + if (GTK_IS_STYLE_PROVIDER_PRIVATE (item)) + { + _gtk_style_provider_private_lookup (GTK_STYLE_PROVIDER_PRIVATE (item), + path, + state, + lookup); + } + else + { + GtkStyleProperties *provider_style = gtk_style_provider_get_style (item, path); + + if (provider_style) + { + _gtk_style_provider_private_lookup (GTK_STYLE_PROVIDER_PRIVATE (provider_style), + path, + state, + lookup); + g_object_unref (provider_style); + } + } + } +} + +static void +gtk_style_cascade_provider_private_iface_init (GtkStyleProviderPrivateInterface *iface) +{ + iface->get_color = gtk_style_cascade_get_color; + iface->lookup = gtk_style_cascade_lookup; +} + +G_DEFINE_TYPE_EXTENDED (GtkStyleCascade, _gtk_style_cascade, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (GTK_TYPE_STYLE_PROVIDER, + gtk_style_cascade_provider_iface_init) + G_IMPLEMENT_INTERFACE (GTK_TYPE_STYLE_PROVIDER_PRIVATE, + gtk_style_cascade_provider_private_iface_init)); + +static void +gtk_style_cascade_dispose (GObject *object) +{ + GtkStyleCascade *cascade = GTK_STYLE_CASCADE (object); + + _gtk_style_cascade_set_parent (cascade, NULL); + g_array_unref (cascade->providers); + + G_OBJECT_CLASS (_gtk_style_cascade_parent_class)->dispose (object); +} + +static void +_gtk_style_cascade_class_init (GtkStyleCascadeClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gtk_style_cascade_dispose; +} + +static void +style_provider_data_clear (gpointer data_) +{ + GtkStyleProviderData *data = data_; + + g_object_unref (data->provider); +} + +static void +_gtk_style_cascade_init (GtkStyleCascade *cascade) +{ + cascade->providers = g_array_new (FALSE, FALSE, sizeof (GtkStyleProviderData)); + g_array_set_clear_func (cascade->providers, style_provider_data_clear); +} + +GtkStyleCascade * +_gtk_style_cascade_new (void) +{ + return g_object_new (GTK_TYPE_STYLE_CASCADE, NULL); +} + +GtkStyleCascade * +_gtk_style_cascade_get_for_screen (GdkScreen *screen) +{ + GtkStyleCascade *cascade; + static GQuark quark = 0; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("gtk-style-cascade"); + + cascade = g_object_get_qdata (G_OBJECT (screen), quark); + if (cascade == NULL) + { + cascade = _gtk_style_cascade_new (); + g_object_set_qdata_full (G_OBJECT (screen), quark, cascade, g_object_unref); + } + + return cascade; +} + +void +_gtk_style_cascade_set_parent (GtkStyleCascade *cascade, + GtkStyleCascade *parent) +{ + g_return_if_fail (GTK_IS_STYLE_CASCADE (cascade)); + g_return_if_fail (parent == NULL || GTK_IS_STYLE_CASCADE (parent)); + if (parent) + g_return_if_fail (parent->parent == NULL); + + if (cascade->parent == parent) + return; + + if (parent) + g_object_ref (parent); + + if (cascade->parent) + g_object_unref (cascade->parent); + + cascade->parent = parent; +} + +void +_gtk_style_cascade_add_provider (GtkStyleCascade *cascade, + GtkStyleProvider *provider, + guint priority) +{ + GtkStyleProviderData data; + guint i; + + g_return_if_fail (GTK_IS_STYLE_CASCADE (cascade)); + g_return_if_fail (GTK_IS_STYLE_PROVIDER (provider)); + g_return_if_fail (GTK_STYLE_PROVIDER (cascade) != provider); + + data.provider = g_object_ref (provider); + data.priority = priority; + + /* ensure it gets removed first */ + _gtk_style_cascade_remove_provider (cascade, provider); + + for (i = 0; i < cascade->providers->len; i++) + { + if (g_array_index (cascade->providers, GtkStyleProviderData, i).priority > priority) + break; + } + g_array_insert_val (cascade->providers, i, data); +} + +void +_gtk_style_cascade_remove_provider (GtkStyleCascade *cascade, + GtkStyleProvider *provider) +{ + guint i; + + g_return_if_fail (GTK_IS_STYLE_CASCADE (cascade)); + g_return_if_fail (GTK_IS_STYLE_PROVIDER (provider)); + + for (i = 0; i < cascade->providers->len; i++) + { + GtkStyleProviderData *data = &g_array_index (cascade->providers, GtkStyleProviderData, i); + + if (data->provider == provider) + { + g_array_remove_index (cascade->providers, i); + break; + } + } +} + diff --git a/gtk/gtkstylecascadeprivate.h b/gtk/gtkstylecascadeprivate.h new file mode 100644 index 0000000000..cd29025cf8 --- /dev/null +++ b/gtk/gtkstylecascadeprivate.h @@ -0,0 +1,66 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2012 Benjamin Otte <otte@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __GTK_STYLECASCADE_PRIVATE_H__ +#define __GTK_STYLECASCADE_PRIVATE_H__ + +#include <gdk/gdk.h> +#include <gtk/gtkstyleproviderprivate.h> + +G_BEGIN_DECLS + +#define GTK_TYPE_STYLE_CASCADE (_gtk_style_cascade_get_type ()) +#define GTK_STYLE_CASCADE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_STYLE_CASCADE, GtkStyleCascade)) +#define GTK_STYLE_CASCADE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_STYLE_CASCADE, GtkStyleCascadeClass)) +#define GTK_IS_STYLE_CASCADE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_STYLE_CASCADE)) +#define GTK_IS_STYLE_CASCADE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_STYLE_CASCADE)) +#define GTK_STYLE_CASCADE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_STYLE_CASCADE, GtkStyleCascadeClass)) + +typedef struct _GtkStyleCascade GtkStyleCascade; +typedef struct _GtkStyleCascadeClass GtkStyleCascadeClass; + +struct _GtkStyleCascade +{ + GObject object; + + GtkStyleCascade *parent; + GArray *providers; +}; + +struct _GtkStyleCascadeClass +{ + GObjectClass parent_class; +}; + +GType _gtk_style_cascade_get_type (void) G_GNUC_CONST; + +GtkStyleCascade * _gtk_style_cascade_new (void); +GtkStyleCascade * _gtk_style_cascade_get_for_screen (GdkScreen *screen); + +void _gtk_style_cascade_set_parent (GtkStyleCascade *cascade, + GtkStyleCascade *parent); + +void _gtk_style_cascade_add_provider (GtkStyleCascade *cascade, + GtkStyleProvider *provider, + guint priority); +void _gtk_style_cascade_remove_provider (GtkStyleCascade *cascade, + GtkStyleProvider *provider); + + +G_END_DECLS + +#endif /* __GTK_CSS_STYLECASCADE_PRIVATE_H__ */ diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index 6a206563a8..9be3a85a6d 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -36,6 +36,7 @@ #include "gtkiconfactory.h" #include "gtkwidgetpath.h" #include "gtkwidgetprivate.h" +#include "gtkstylecascadeprivate.h" #include "gtkstyleproviderprivate.h" #include "gtksettings.h" @@ -300,7 +301,6 @@ * </refsect2> */ -typedef struct GtkStyleProviderData GtkStyleProviderData; typedef struct GtkStyleInfo GtkStyleInfo; typedef struct GtkRegion GtkRegion; typedef struct PropertyValue PropertyValue; @@ -313,12 +313,6 @@ struct GtkRegion GtkRegionFlags flags; }; -struct GtkStyleProviderData -{ - GtkStyleProvider *provider; - guint priority; -}; - struct PropertyValue { GType widget_type; @@ -364,8 +358,7 @@ struct _GtkStyleContextPrivate { GdkScreen *screen; - GList *providers; - GList *providers_last; + GtkStyleCascade *cascade; GtkStyleContext *parent; GtkWidgetPath *widget_path; @@ -399,8 +392,6 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -static GQuark provider_list_quark = 0; - static void gtk_style_context_finalize (GObject *object); static void gtk_style_context_impl_set_property (GObject *object, @@ -629,32 +620,14 @@ gtk_style_context_init (GtkStyleContext *style_context) priv->direction = GTK_TEXT_DIR_LTR; priv->screen = gdk_screen_get_default (); + priv->cascade = _gtk_style_cascade_get_for_screen (priv->screen); + g_object_ref (priv->cascade); /* Create default info store */ info = style_info_new (); priv->info_stack = g_slist_prepend (priv->info_stack, info); } -static GtkStyleProviderData * -style_provider_data_new (GtkStyleProvider *provider, - guint priority) -{ - GtkStyleProviderData *data; - - data = g_slice_new (GtkStyleProviderData); - data->provider = g_object_ref (provider); - data->priority = priority; - - return data; -} - -static void -style_provider_data_free (GtkStyleProviderData *data) -{ - g_object_unref (data->provider); - g_slice_free (GtkStyleProviderData, data); -} - static void animation_info_free (AnimationInfo *info) { @@ -828,7 +801,7 @@ gtk_style_context_finalize (GObject *object) g_hash_table_destroy (priv->style_data); - g_list_free_full (priv->providers, (GDestroyNotify) style_provider_data_free); + g_object_unref (priv->cascade); g_slist_free_full (priv->info_stack, (GDestroyNotify) style_info_free); @@ -904,30 +877,6 @@ gtk_style_context_impl_get_property (GObject *object, } } -static GList * -find_next_candidate (GList *local, - GList *global) -{ - if (local && global) - { - GtkStyleProviderData *local_data, *global_data; - - local_data = local->data; - global_data = global->data; - - if (local_data->priority < global_data->priority) - return global; - else - return local; - } - else if (local) - return local; - else if (global) - return global; - - return NULL; -} - static void build_properties (GtkStyleContext *context, StyleData *style_data, @@ -935,53 +884,16 @@ build_properties (GtkStyleContext *context, GtkStateFlags state) { GtkStyleContextPrivate *priv; - GList *elem, *list, *global_list = NULL; GtkCssLookup *lookup; priv = context->priv; - 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); - } lookup = _gtk_css_lookup_new (); - while ((elem = find_next_candidate (list, global_list)) != NULL) - { - GtkStyleProviderData *data; - GtkStyleProperties *provider_style; - - data = elem->data; - - if (elem == list) - list = list->prev; - else - global_list = global_list->prev; - - if (GTK_IS_STYLE_PROVIDER_PRIVATE (data->provider)) - { - _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); - } - } - } + _gtk_style_provider_private_lookup (GTK_STYLE_PROVIDER_PRIVATE (priv->cascade), + path, + state, + lookup); style_data->store = _gtk_css_computed_values_new (); _gtk_css_lookup_resolve (lookup, context, style_data->store); @@ -1086,82 +998,6 @@ style_data_lookup (GtkStyleContext *context, return data; } -static void -style_provider_add (GList **list, - GtkStyleProvider *provider, - guint priority) -{ - GtkStyleProviderData *new_data; - gboolean added = FALSE; - GList *l = *list; - - new_data = style_provider_data_new (provider, priority); - - while (l) - { - GtkStyleProviderData *data; - - data = l->data; - - /* Provider was already attached to the style - * context, remove in order to add the new data - */ - if (data->provider == provider) - { - GList *link; - - link = l; - l = l->next; - - /* Remove and free link */ - *list = g_list_remove_link (*list, link); - style_provider_data_free (link->data); - g_list_free_1 (link); - - continue; - } - - if (!added && - data->priority > priority) - { - *list = g_list_insert_before (*list, l, new_data); - added = TRUE; - } - - l = l->next; - } - - if (!added) - *list = g_list_append (*list, new_data); -} - -static gboolean -style_provider_remove (GList **list, - GtkStyleProvider *provider) -{ - GList *l = *list; - - while (l) - { - GtkStyleProviderData *data; - - data = l->data; - - if (data->provider == provider) - { - *list = g_list_remove_link (*list, l); - style_provider_data_free (l->data); - g_list_free_1 (l); - - return TRUE; - } - - l = l->next; - } - - return FALSE; -} - /** * gtk_style_context_new: * @@ -1213,8 +1049,18 @@ gtk_style_context_add_provider (GtkStyleContext *context, g_return_if_fail (GTK_IS_STYLE_PROVIDER (provider)); priv = context->priv; - style_provider_add (&priv->providers, provider, priority); - priv->providers_last = g_list_last (priv->providers); + + if (priv->cascade == _gtk_style_cascade_get_for_screen (priv->screen)) + { + GtkStyleCascade *new_cascade; + + new_cascade = _gtk_style_cascade_new (); + _gtk_style_cascade_set_parent (new_cascade, priv->cascade); + g_object_unref (priv->cascade); + priv->cascade = new_cascade; + } + + _gtk_style_cascade_add_provider (priv->cascade, provider, priority); gtk_style_context_invalidate (context); } @@ -1239,12 +1085,10 @@ gtk_style_context_remove_provider (GtkStyleContext *context, priv = context->priv; - if (style_provider_remove (&priv->providers, provider)) - { - priv->providers_last = g_list_last (priv->providers); + if (priv->cascade == _gtk_style_cascade_get_for_screen (priv->screen)) + return; - gtk_style_context_invalidate (context); - } + _gtk_style_cascade_remove_provider (priv->cascade, provider); } /** @@ -1309,21 +1153,13 @@ gtk_style_context_add_provider_for_screen (GdkScreen *screen, GtkStyleProvider *provider, guint priority) { - GList *providers, *list; + GtkStyleCascade *cascade; g_return_if_fail (GDK_IS_SCREEN (screen)); g_return_if_fail (GTK_IS_STYLE_PROVIDER (provider)); - if (G_UNLIKELY (!provider_list_quark)) - provider_list_quark = g_quark_from_static_string ("gtk-provider-list-quark"); - - list = providers = g_object_get_qdata (G_OBJECT (screen), provider_list_quark); - style_provider_add (&list, provider, priority); - - if (list != providers) - g_object_set_qdata (G_OBJECT (screen), provider_list_quark, list); - - gtk_style_context_reset_widgets (screen); + cascade = _gtk_style_cascade_get_for_screen (screen); + _gtk_style_cascade_add_provider (cascade, provider, priority); } /** @@ -1339,23 +1175,13 @@ void gtk_style_context_remove_provider_for_screen (GdkScreen *screen, GtkStyleProvider *provider) { - GList *providers, *list; + GtkStyleCascade *cascade; g_return_if_fail (GDK_IS_SCREEN (screen)); g_return_if_fail (GTK_IS_STYLE_PROVIDER (provider)); - if (G_UNLIKELY (!provider_list_quark)) - return; - - list = providers = g_object_get_qdata (G_OBJECT (screen), provider_list_quark); - - if (style_provider_remove (&list, provider)) - { - if (list != providers) - g_object_set_qdata (G_OBJECT (screen), provider_list_quark, list); - - gtk_style_context_reset_widgets (screen); - } + cascade = _gtk_style_cascade_get_for_screen (screen); + _gtk_style_cascade_remove_provider (cascade, provider); } /** @@ -2353,7 +2179,6 @@ _gtk_style_context_peek_style_property (GtkStyleContext *context, { GtkStyleContextPrivate *priv; PropertyValue *pcache, key = { 0 }; - GList *global_list = NULL; StyleData *data; guint i; @@ -2388,72 +2213,49 @@ _gtk_style_context_peek_style_property (GtkStyleContext *context, g_param_spec_ref (pcache->pspec); g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - if (priv->screen) - { - global_list = g_object_get_qdata (G_OBJECT (priv->screen), provider_list_quark); - global_list = g_list_last (global_list); - } - if (priv->widget_path) { - GList *list, *global, *elem; - - list = priv->providers_last; - global = global_list; - - while ((elem = find_next_candidate (list, global)) != NULL) + if (gtk_style_provider_get_style_property (GTK_STYLE_PROVIDER (priv->cascade), + priv->widget_path, state, + pspec, &pcache->value)) { - GtkStyleProviderData *provider_data; - - provider_data = elem->data; - - if (elem == list) - list = list->prev; - else - global = global->prev; - - if (gtk_style_provider_get_style_property (provider_data->provider, - priv->widget_path, state, - pspec, &pcache->value)) + /* Resolve symbolic colors to GdkColor/GdkRGBA */ + if (G_VALUE_TYPE (&pcache->value) == GTK_TYPE_SYMBOLIC_COLOR) { - /* Resolve symbolic colors to GdkColor/GdkRGBA */ - if (G_VALUE_TYPE (&pcache->value) == GTK_TYPE_SYMBOLIC_COLOR) - { - GtkSymbolicColor *color; - GdkRGBA rgba; + GtkSymbolicColor *color; + GdkRGBA rgba; + + color = g_value_dup_boxed (&pcache->value); - color = g_value_dup_boxed (&pcache->value); + g_value_unset (&pcache->value); - g_value_unset (&pcache->value); + if (G_PARAM_SPEC_VALUE_TYPE (pspec) == GDK_TYPE_RGBA) + g_value_init (&pcache->value, GDK_TYPE_RGBA); + else + g_value_init (&pcache->value, GDK_TYPE_COLOR); + if (_gtk_style_context_resolve_color (context, color, &rgba)) + { if (G_PARAM_SPEC_VALUE_TYPE (pspec) == GDK_TYPE_RGBA) - g_value_init (&pcache->value, GDK_TYPE_RGBA); + g_value_set_boxed (&pcache->value, &rgba); else - g_value_init (&pcache->value, GDK_TYPE_COLOR); - - if (_gtk_style_context_resolve_color (context, color, &rgba)) { - if (G_PARAM_SPEC_VALUE_TYPE (pspec) == GDK_TYPE_RGBA) - g_value_set_boxed (&pcache->value, &rgba); - else - { - GdkColor rgb; - - rgb.red = rgba.red * 65535. + 0.5; - rgb.green = rgba.green * 65535. + 0.5; - rgb.blue = rgba.blue * 65535. + 0.5; - - g_value_set_boxed (&pcache->value, &rgb); - } - } - else - g_param_value_set_default (pspec, &pcache->value); + GdkColor rgb; - gtk_symbolic_color_unref (color); + rgb.red = rgba.red * 65535. + 0.5; + rgb.green = rgba.green * 65535. + 0.5; + rgb.blue = rgba.blue * 65535. + 0.5; + + g_value_set_boxed (&pcache->value, &rgb); + } } + else + g_param_value_set_default (pspec, &pcache->value); - return &pcache->value; + gtk_symbolic_color_unref (color); } + + return &pcache->value; } } @@ -2689,6 +2491,17 @@ gtk_style_context_set_screen (GtkStyleContext *context, if (priv->screen == screen) return; + if (priv->cascade == _gtk_style_cascade_get_for_screen (priv->screen)) + { + g_object_unref (priv->cascade); + priv->cascade = _gtk_style_cascade_get_for_screen (screen); + g_object_ref (priv->cascade); + } + else + { + _gtk_style_cascade_set_parent (priv->cascade, _gtk_style_cascade_get_for_screen (screen)); + } + priv->screen = screen; g_object_notify (G_OBJECT (context), "screen"); @@ -2822,45 +2635,9 @@ 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)) != 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; + return _gtk_style_provider_private_get_color (GTK_STYLE_PROVIDER_PRIVATE (context->priv->cascade), name); } GtkCssValue * |