Merge branch 'matthiasc/css-change-tracking-2' into 'master'

Better css change tracking

See merge request GNOME/gtk!1325
This commit is contained in:
Matthias Clasen 2020-01-16 23:00:17 +00:00
commit 2b504201e3
4 changed files with 27 additions and 138 deletions

View File

@ -425,62 +425,41 @@ verify_tree_match_results (GtkCssProvider *provider,
#endif
}
static void
verify_tree_get_change_results (GtkCssProvider *provider,
const GtkCssMatcher *matcher,
GtkCssChange change)
/* Compute the change flags for a given matcher.
* We assume that name, id and classes stay unchanged, and look for all rules
* that can be matched if anything else changes. We collect the change masks
* from the selectors of these rules.
*/
static GtkCssChange
compute_change (GtkCssProvider *provider,
const GtkCssMatcher *matcher)
{
#ifdef VERIFY_TREE
{
GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (provider);
GtkCssChange verify_change = 0;
GPtrArray *tree_rules;
int i;
GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (provider);
GtkCssChange change = 0;
GPtrArray *tree_rules;
int i;
GtkCssMatcher change_matcher;
tree_rules = _gtk_css_selector_tree_match_all (priv->tree, matcher);
if (tree_rules)
{
verify_tree_match_results (provider, matcher, tree_rules);
_gtk_css_matcher_superset_init (&change_matcher, matcher, GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS);
for (i = tree_rules->len - 1; i >= 0; i--)
{
GtkCssRuleset *ruleset;
tree_rules = _gtk_css_selector_tree_match_all (priv->tree, &change_matcher);
if (tree_rules)
{
for (i = tree_rules->len - 1; i >= 0; i--)
{
GtkCssRuleset *ruleset;
ruleset = tree_rules->pdata[i];
ruleset = tree_rules->pdata[i];
verify_change |= _gtk_css_selector_get_change (ruleset->selector);
}
change |= _gtk_css_selector_get_change (ruleset->selector);
}
g_ptr_array_free (tree_rules, TRUE);
}
g_ptr_array_free (tree_rules, TRUE);
}
if (change != verify_change)
{
GString *s;
s = g_string_new ("");
g_string_append (s, "expected change ");
gtk_css_change_print (verify_change, s);
g_string_append (s, ", but it was ");
gtk_css_change_print (change, s);
if ((change & ~verify_change) != 0)
{
g_string_append (s, ", unexpectedly set: ");
gtk_css_change_print (change & ~verify_change, s);
}
if ((~change & verify_change) != 0)
{
g_string_append_printf (s, ", unexpectedly not set: ");
gtk_css_change_print (~change & verify_change, s);
}
g_warning (s->str);
g_string_free (s, TRUE);
}
}
#endif
return change;
}
static GtkCssValue *
gtk_css_style_provider_get_color (GtkStyleProvider *provider,
const char *name)
@ -551,14 +530,7 @@ gtk_css_style_provider_lookup (GtkStyleProvider *provider,
}
if (change)
{
GtkCssMatcher change_matcher;
_gtk_css_matcher_superset_init (&change_matcher, matcher, GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS);
*change = _gtk_css_selector_tree_get_change_all (priv->tree, &change_matcher);
verify_tree_get_change_results (css_provider, &change_matcher, *change);
}
*change = compute_change (css_provider, matcher);
}
static void
@ -1047,18 +1019,6 @@ gtk_css_provider_postprocess (GtkCssProvider *css_provider)
priv->tree = _gtk_css_selector_tree_builder_build (builder);
_gtk_css_selector_tree_builder_free (builder);
#ifndef VERIFY_TREE
for (i = 0; i < priv->rulesets->len; i++)
{
GtkCssRuleset *ruleset;
ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
_gtk_css_selector_free (ruleset->selector);
ruleset->selector = NULL;
}
#endif
}
static void

View File

@ -1877,80 +1877,12 @@ _gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
return array;
}
/* When checking for changes via the tree we need to know if a rule further
down the tree matched, because if so we need to add "our bit" to the
Change. For instance in a match like *.class:active we'll
get a tree that first checks :active, if that matches we continue down
to the tree, and if we get a match we add CHANGE_CLASS. However, the
end of the tree where we have a match is an ANY which doesn't actually
modify the change, so we don't know if we have a match or not. We fix
this by setting GTK_CSS_CHANGE_GOT_MATCH which lets us guarantee
that change != 0 on any match. */
#define GTK_CSS_CHANGE_GOT_MATCH GTK_CSS_CHANGE_RESERVED_BIT
static GtkCssChange
gtk_css_selector_tree_collect_change (const GtkCssSelectorTree *tree)
{
GtkCssChange change = 0;
const GtkCssSelectorTree *prev;
for (prev = gtk_css_selector_tree_get_previous (tree);
prev != NULL;
prev = gtk_css_selector_tree_get_sibling (prev))
change |= gtk_css_selector_tree_collect_change (prev);
change = tree->selector.class->get_change (&tree->selector, change);
return change;
}
static GtkCssChange
gtk_css_selector_tree_get_change (const GtkCssSelectorTree *tree,
const GtkCssMatcher *matcher)
{
GtkCssChange change = 0;
const GtkCssSelectorTree *prev;
if (!gtk_css_selector_match (&tree->selector, matcher))
return 0;
if (!tree->selector.class->is_simple)
return gtk_css_selector_tree_collect_change (tree) | GTK_CSS_CHANGE_GOT_MATCH;
for (prev = gtk_css_selector_tree_get_previous (tree);
prev != NULL;
prev = gtk_css_selector_tree_get_sibling (prev))
change |= gtk_css_selector_tree_get_change (prev, matcher);
if (change || gtk_css_selector_tree_get_matches (tree))
change = tree->selector.class->get_change (&tree->selector, change & ~GTK_CSS_CHANGE_GOT_MATCH) | GTK_CSS_CHANGE_GOT_MATCH;
return change;
}
gboolean
_gtk_css_selector_tree_is_empty (const GtkCssSelectorTree *tree)
{
return tree == NULL;
}
GtkCssChange
_gtk_css_selector_tree_get_change_all (const GtkCssSelectorTree *tree,
const GtkCssMatcher *matcher)
{
GtkCssChange change;
change = 0;
/* no need to foreach here because we abort for non-simple selectors */
for (; tree != NULL;
tree = gtk_css_selector_tree_get_sibling (tree))
change |= gtk_css_selector_tree_get_change (tree, matcher);
/* Never return reserved bit set */
return change & ~GTK_CSS_CHANGE_RESERVED_BIT;
}
#ifdef PRINT_TREE
static void
_gtk_css_selector_tree_print (const GtkCssSelectorTree *tree, GString *str, char *prefix)

View File

@ -43,8 +43,6 @@ int _gtk_css_selector_compare (const GtkCssSelector *a,
void _gtk_css_selector_tree_free (GtkCssSelectorTree *tree);
GPtrArray * _gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
const GtkCssMatcher *matcher);
GtkCssChange _gtk_css_selector_tree_get_change_all (const GtkCssSelectorTree *tree,
const GtkCssMatcher *matcher);
void _gtk_css_selector_tree_match_print (const GtkCssSelectorTree *tree,
GString *str);
gboolean _gtk_css_selector_tree_is_empty (const GtkCssSelectorTree *tree) G_GNUC_CONST;

View File

@ -93,7 +93,6 @@ typedef struct _GtkCssStaticStyle GtkCssStaticStyle;
#define GTK_CSS_CHANGE_TIMESTAMP (1ULL << 50)
#define GTK_CSS_CHANGE_ANIMATIONS (1ULL << 51)
#define GTK_CSS_CHANGE_RESERVED_BIT (1ULL << 62) /* Used internally in gtkcssselector.c */
typedef guint64 GtkCssChange;