summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2012-03-23 01:52:38 +0100
committerBenjamin Otte <otte@redhat.com>2012-04-17 08:59:10 +0200
commiteb537b60f4d263667e0a9542998e7e7ae0751ccc (patch)
treef8b9d2b5b5ca642204a8f96c9a48a0bf30a7beff
parentece9d2fd92b228503bc450dd2778f8d673dbfa18 (diff)
downloadgtk+-eb537b60f4d263667e0a9542998e7e7ae0751ccc.tar.gz
stylecontext: Optimize the common case of "style didn't change"
-rw-r--r--gtk/gtkstylecontext.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 1ca099d7e9..9828314edc 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -301,6 +301,10 @@
* </refsect2>
*/
+/* When these change we do a full restyling. Otherwise we try to figure out
+ * if we need to change things. */
+#define GTK_STYLE_CONTEXT_RADICAL_CHANGE (GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS)
+
typedef struct GtkStyleInfo GtkStyleInfo;
typedef struct GtkRegion GtkRegion;
typedef struct PropertyValue PropertyValue;
@@ -376,6 +380,8 @@ struct _GtkStyleContextPrivate
GtkTextDirection direction;
+ GtkCssChange relevant_changes;
+
guint animations_invalidated : 1;
guint invalidating_context : 1;
};
@@ -635,6 +641,7 @@ gtk_style_context_init (GtkStyleContext *style_context)
priv->screen = gdk_screen_get_default ();
priv->cascade = _gtk_style_cascade_get_for_screen (priv->screen);
g_object_ref (priv->cascade);
+ priv->relevant_changes = GTK_CSS_CHANGE_ANY;
/* Create default info store */
info = style_info_new ();
@@ -3239,9 +3246,42 @@ void
_gtk_style_context_queue_invalidate (GtkStyleContext *context,
GtkCssChange change)
{
+ GtkStyleContextPrivate *priv;
+
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
g_return_if_fail (change != 0);
+ priv = context->priv;
+
+ if (priv->widget == NULL && priv->widget_path == NULL)
+ return;
+
+ /* Try to avoid invalidating if we can */
+ if (change & GTK_STYLE_CONTEXT_RADICAL_CHANGE)
+ {
+ priv->relevant_changes = GTK_CSS_CHANGE_ANY;
+ }
+ else
+ {
+ if (priv->relevant_changes == GTK_CSS_CHANGE_ANY)
+ {
+ GtkWidgetPath *path;
+ GtkCssMatcher matcher;
+
+ path = create_query_path (context);
+ _gtk_css_matcher_init (&matcher, path, priv->current_state);
+
+ priv->relevant_changes = _gtk_style_provider_private_get_change (GTK_STYLE_PROVIDER_PRIVATE (priv->cascade),
+ &matcher);
+ priv->relevant_changes &= ~GTK_STYLE_CONTEXT_RADICAL_CHANGE;
+
+ gtk_widget_path_unref (path);
+ }
+
+ if ((priv->relevant_changes & change) == 0)
+ return;
+ }
+
gtk_style_context_invalidate (context);
}
@@ -3276,6 +3316,8 @@ gtk_style_context_invalidate (GtkStyleContext *context)
g_hash_table_remove_all (priv->style_data);
priv->current_data = NULL;
+ priv->relevant_changes = GTK_CSS_CHANGE_ANY;
+
g_signal_emit (context, signals[CHANGED], 0);
priv->invalidating_context = FALSE;