[gtk+/wip/cssvalue: 3/142] styleprovider: Add a custom object for a list of style providers
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/cssvalue: 3/142] styleprovider: Add a custom object for a list of style providers
- Date: Sat, 7 Apr 2012 19:46:36 +0000 (UTC)
commit 023a45348615a28d3827b016cfdf2c46d715f332
Author: Benjamin Otte <otte redhat com>
Date: Fri Mar 16 05:14:41 2012 +0100
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.
gtk/Makefile.am | 2 +
gtk/gtkstylecascade.c | 352 ++++++++++++++++++++++++++++++++++++++++
gtk/gtkstylecascadeprivate.h | 66 ++++++++
gtk/gtkstylecontext.c | 367 ++++++++---------------------------------
4 files changed, 492 insertions(+), 295 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 1f45028..e062c9a 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 0000000..a0cdfe5
--- /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;
+ 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 0000000..cd29025
--- /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 6a20656..21dfdc4 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)
+ if (priv->widget || priv->widget_path)
{
- 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 *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]