diff --git a/gtk/gtkcsscomputedvalues.c b/gtk/gtkcsscomputedvalues.c index 608575e38c..ac2718f44a 100644 --- a/gtk/gtkcsscomputedvalues.c +++ b/gtk/gtkcsscomputedvalues.c @@ -227,3 +227,25 @@ _gtk_css_computed_values_get_section (GtkCssComputedValues *values, return g_ptr_array_index (values->sections, id); } +GtkBitmask * +_gtk_css_computed_values_get_difference (GtkCssComputedValues *values, + GtkCssComputedValues *other) +{ + GtkBitmask *result; + guint i, len; + + len = MIN (values->values->len, other->values->len); + result = _gtk_bitmask_new (); + if (values->values->len != other->values->len) + result = _gtk_bitmask_invert_range (result, len, MAX (values->values->len, other->values->len)); + + for (i = 0; i < len; i++) + { + if (!_gtk_css_value_equal (g_ptr_array_index (values->values, i), + g_ptr_array_index (other->values, i))) + result = _gtk_bitmask_set (result, i, TRUE); + } + + return result; +} + diff --git a/gtk/gtkcsscomputedvaluesprivate.h b/gtk/gtkcsscomputedvaluesprivate.h index 81c9cf2519..64234ef371 100644 --- a/gtk/gtkcsscomputedvaluesprivate.h +++ b/gtk/gtkcsscomputedvaluesprivate.h @@ -22,6 +22,7 @@ #include +#include "gtk/gtkbitmaskprivate.h" #include "gtk/gtkcsssection.h" #include "gtk/gtkstylecontext.h" #include "gtk/gtkcssvalueprivate.h" @@ -69,6 +70,8 @@ GtkCssValue * _gtk_css_computed_values_get_value (GtkCssCom guint id); GtkCssSection * _gtk_css_computed_values_get_section (GtkCssComputedValues *values, guint id); +GtkBitmask * _gtk_css_computed_values_get_difference (GtkCssComputedValues *values, + GtkCssComputedValues *other); G_END_DECLS diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index 103f235df4..b50f9d0602 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -2830,12 +2830,31 @@ _gtk_style_context_validate (GtkStyleContext *context, if (priv->relevant_changes & change) { GtkStyleInfo *info = priv->info_stack->data; + GtkCssComputedValues *old, *new; + + old = info->data ? g_object_ref (info->data->store) : NULL; if ((priv->relevant_changes & change) & ~GTK_STYLE_CONTEXT_CACHED_CHANGE) gtk_style_context_clear_cache (context); + else + info->data = NULL; + + if (old) + { + GtkBitmask *bitmask; + + new = style_data_lookup (context)->store; + + bitmask = _gtk_css_computed_values_get_difference (new, old); + if (!_gtk_bitmask_is_empty (bitmask)) + gtk_style_context_do_invalidate (context); + + _gtk_bitmask_free (bitmask); + g_object_unref (old); + } + else + gtk_style_context_do_invalidate (context); - info->data = NULL; - gtk_style_context_do_invalidate (context); } change = _gtk_css_change_for_child (change);