[gtk/matthiasc/css-change-tracking-5: 3/5] Make change computation more precise



commit e022f72ef41767e497c4101f2341c92cf1ea40a3
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jan 17 14:38:31 2020 -0500

    Make change computation more precise
    
    Don't ignore parent name, id, class when matching for change.
    This reduces the amount of parent-state in our change flags.
    The price we pay for this is that we need to treat parent-name,
    parent-id and parent-class as radical change now. But since
    they are less frequent than parent-state changes, it is still
    a win.

 gtk/gtkcssnode.c     |  9 ++++++++-
 gtk/gtkcssselector.c | 57 +++++++++++++++++++++++++++-------------------------
 2 files changed, 38 insertions(+), 28 deletions(-)
---
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 4fe350d5ff..2893eee051 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -86,7 +86,14 @@
 
 /* When these change we do a full restyling. Otherwise we try to figure out
  * if we need to change things. */
-#define GTK_CSS_RADICAL_CHANGE (GTK_CSS_CHANGE_ID | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS | 
GTK_CSS_CHANGE_SOURCE | GTK_CSS_CHANGE_PARENT_STYLE)
+#define GTK_CSS_RADICAL_CHANGE (GTK_CSS_CHANGE_ID | \
+                                GTK_CSS_CHANGE_NAME | \
+                                GTK_CSS_CHANGE_CLASS | \
+                                GTK_CSS_CHANGE_PARENT_ID | \
+                                GTK_CSS_CHANGE_PARENT_NAME | \
+                                GTK_CSS_CHANGE_PARENT_CLASS | \
+                                GTK_CSS_CHANGE_SOURCE | \
+                                GTK_CSS_CHANGE_PARENT_STYLE)
 
 /* When these change, we need to recompute the change flags for the new style
  * since they may have changed.
diff --git a/gtk/gtkcssselector.c b/gtk/gtkcssselector.c
index c83f42f419..5a976a76b0 100644
--- a/gtk/gtkcssselector.c
+++ b/gtk/gtkcssselector.c
@@ -316,7 +316,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_DESCENDANT = {
   gtk_css_selector_default_hash_one,
   gtk_css_selector_default_compare_one,
   FALSE,
-  TRUE
+  FALSE
 };
 
 /* CHILD */
@@ -358,7 +358,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_CHILD = {
   gtk_css_selector_default_hash_one,
   gtk_css_selector_default_compare_one,
   FALSE,
-  TRUE
+  FALSE
 };
 
 /* SIBLING */
@@ -1912,56 +1912,59 @@ gtk_css_selector_tree_collect_change (const GtkCssSelectorTree *tree)
        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;
+  return tree->selector.class->get_change (&tree->selector, change);
 }
 
-static GtkCssChange
-gtk_css_selector_tree_get_change (const GtkCssSelectorTree *tree,
-                                 const GtkCssMatcher      *matcher)
+static gboolean
+gtk_css_selector_tree_change_foreach (const GtkCssSelector *selector,
+                                     const GtkCssMatcher  *matcher,
+                                      gpointer              res)
 {
-  GtkCssChange change = 0;
+  const GtkCssSelectorTree *tree = (const GtkCssSelectorTree *) selector;
   const GtkCssSelectorTree *prev;
+  GtkCssChange *ret = res;
+  GtkCssChange change = 0;
 
   if (!gtk_css_selector_match_for_change (&tree->selector, matcher))
-    return 0;
+    return FALSE;
 
-  if (!tree->selector.class->is_simple)
-    return gtk_css_selector_tree_collect_change (tree) | GTK_CSS_CHANGE_GOT_MATCH;
+  if (!tree->selector.class->is_simple && tree->selector.class->ignore_for_change)
+    {
+      *ret |= gtk_css_selector_tree_collect_change (tree) | GTK_CSS_CHANGE_GOT_MATCH;
+      return FALSE;
+    }
 
   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);
+    gtk_css_selector_foreach (&prev->selector, matcher, gtk_css_selector_tree_change_foreach, &change);
 
   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;
-}
+    {
+      *ret |= tree->selector.class->get_change (&tree->selector, change & ~GTK_CSS_CHANGE_GOT_MATCH) | 
GTK_CSS_CHANGE_GOT_MATCH;
+    }
 
-gboolean
-_gtk_css_selector_tree_is_empty (const GtkCssSelectorTree *tree)
-{
-  return tree == NULL;
+  return FALSE;
 }
 
 GtkCssChange
 _gtk_css_selector_tree_get_change_all (const GtkCssSelectorTree *tree,
                                       const GtkCssMatcher *matcher)
 {
-  GtkCssChange change;
-
-  change = 0;
+  GtkCssChange 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);
+    gtk_css_selector_foreach (&tree->selector, matcher, gtk_css_selector_tree_change_foreach, &change);
 
   /* Never return reserved bit set */
-  return change & ~GTK_CSS_CHANGE_RESERVED_BIT;
+  return change & ~GTK_CSS_CHANGE_GOT_MATCH;
+}
+
+gboolean
+_gtk_css_selector_tree_is_empty (const GtkCssSelectorTree *tree)
+{
+  return tree == NULL;
 }
 
 #ifdef PRINT_TREE


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]