[gtk/matthiasc/css-split-states: 1/4] css: Track hover state changes separately



commit fcceac6d118354ac3e73cd80c4dab8d026e49721
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Jan 15 15:10:06 2020 -0500

    css: Track hover state changes separately
    
    The idea is that this reduce the amount of frequently
    changing state that css nodes are sensitive to.
    
    This is going to reduce the amount of style recomputation.

 gtk/gtkcssmatcher.c      |   2 +-
 gtk/gtkcssnode.c         |  14 +++++-
 gtk/gtkcssselector.c     |  17 +++++--
 gtk/gtkcsstypes.c        |  26 +++++++----
 gtk/gtkcsstypesprivate.h | 113 +++++++++++++++++++++++++++--------------------
 5 files changed, 110 insertions(+), 62 deletions(-)
---
diff --git a/gtk/gtkcssmatcher.c b/gtk/gtkcssmatcher.c
index 899a7f74f6..87364177be 100644
--- a/gtk/gtkcssmatcher.c
+++ b/gtk/gtkcssmatcher.c
@@ -529,7 +529,7 @@ _gtk_css_matcher_superset_init (GtkCssMatcher       *matcher,
                                 GtkCssChange         relevant)
 {
   g_return_if_fail (subset != NULL);
-  g_return_if_fail ((relevant & ~(GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_POSITION | 
GTK_CSS_CHANGE_STATE)) == 0);
+  g_return_if_fail ((relevant & ~(GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_POSITION | 
GTK_CSS_CHANGE_STATE | GTK_CSS_CHANGE_HOVER)) == 0);
 
   matcher->superset.klass = &GTK_CSS_MATCHER_SUPERSET;
   matcher->superset.subset = subset;
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 0cce324e05..cdc72d1881 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -1138,9 +1138,21 @@ void
 gtk_css_node_set_state (GtkCssNode    *cssnode,
                         GtkStateFlags  state_flags)
 {
+  GtkStateFlags old_state;
+
+  old_state = gtk_css_node_declaration_get_state (cssnode->decl);
+
   if (gtk_css_node_declaration_set_state (&cssnode->decl, state_flags))
     {
-      gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_STATE);
+      GtkStateFlags states = old_state ^ state_flags;
+      GtkCssChange change = 0;
+
+      if (states & GTK_STATE_FLAG_PRELIGHT)
+        change |= GTK_CSS_CHANGE_HOVER;
+      if (states & ~GTK_STATE_FLAG_PRELIGHT)
+        change |= GTK_CSS_CHANGE_STATE;
+
+      gtk_css_node_invalidate (cssnode, change);
       g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_STATE]);
     }
 }
diff --git a/gtk/gtkcssselector.c b/gtk/gtkcssselector.c
index b6468bd282..16439e5ba7 100644
--- a/gtk/gtkcssselector.c
+++ b/gtk/gtkcssselector.c
@@ -728,6 +728,12 @@ comp_pseudoclass_state (const GtkCssSelector *a,
   return a->state.state - b->state.state;
 }
 
+#define GTK_CSS_CHANGE_PSEUDOCLASS_HOVER GTK_CSS_CHANGE_HOVER
+DEFINE_SIMPLE_SELECTOR(pseudoclass_hover, PSEUDOCLASS_HOVER, print_pseudoclass_state,
+                       match_pseudoclass_state, hash_pseudoclass_state, comp_pseudoclass_state,
+                       FALSE, TRUE, FALSE)
+#undef GTK_CSS_CHANGE_PSEUDOCLASS_HOVER
+
 #define GTK_CSS_CHANGE_PSEUDOCLASS_STATE GTK_CSS_CHANGE_STATE
 DEFINE_SIMPLE_SELECTOR(pseudoclass_state, PSEUDOCLASS_STATE, print_pseudoclass_state,
                        match_pseudoclass_state, hash_pseudoclass_state, comp_pseudoclass_state,
@@ -1288,9 +1294,14 @@ gtk_css_selector_parse_selector_pseudo_class (GtkCssParser   *parser,
             {
               if (pseudo_classes[i].state_flag)
                 {
-                  selector = gtk_css_selector_new (negate ? &GTK_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
-                                                          : &GTK_CSS_SELECTOR_PSEUDOCLASS_STATE,
-                                                   selector);
+                  if (pseudo_classes[i].state_flag == GTK_STATE_FLAG_PRELIGHT)
+                    selector = gtk_css_selector_new (negate ? &GTK_CSS_SELECTOR_NOT_PSEUDOCLASS_HOVER
+                                                            : &GTK_CSS_SELECTOR_PSEUDOCLASS_HOVER,
+                                                     selector);
+                  else
+                    selector = gtk_css_selector_new (negate ? &GTK_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
+                                                            : &GTK_CSS_SELECTOR_PSEUDOCLASS_STATE,
+                                                     selector);
                   selector->state.state = pseudo_classes[i].state_flag;
                 }
               else
diff --git a/gtk/gtkcsstypes.c b/gtk/gtkcsstypes.c
index 8bae7c397c..7f42e1514e 100644
--- a/gtk/gtkcsstypes.c
+++ b/gtk/gtkcsstypes.c
@@ -74,19 +74,17 @@ _gtk_css_change_for_sibling (GtkCssChange match)
                     | GTK_CSS_CHANGE_LAST_CHILD \
                     | GTK_CSS_CHANGE_NTH_CHILD \
                     | GTK_CSS_CHANGE_NTH_LAST_CHILD \
-                    | GTK_CSS_CHANGE_STATE )
+                    | GTK_CSS_CHANGE_STATE \
+                    | GTK_CSS_CHANGE_HOVER)
 
 #define KEEP_STATES ( ~(BASE_STATES|GTK_CSS_CHANGE_SOURCE|GTK_CSS_CHANGE_PARENT_STYLE) \
                     | GTK_CSS_CHANGE_NTH_CHILD \
                     | GTK_CSS_CHANGE_NTH_LAST_CHILD)
 
-#define SIBLING_SHIFT 8
-
-  return (match & KEEP_STATES) | ((match & BASE_STATES) << SIBLING_SHIFT);
+  return (match & KEEP_STATES) | ((match & BASE_STATES) << GTK_CSS_CHANGE_SIBLING_SHIFT);
 
 #undef BASE_STATES
 #undef KEEP_STATES
-#undef SIBLING_SHIFT
 }
 
 GtkCssChange
@@ -100,6 +98,7 @@ _gtk_css_change_for_child (GtkCssChange match)
                     | GTK_CSS_CHANGE_NTH_CHILD \
                     | GTK_CSS_CHANGE_NTH_LAST_CHILD \
                     | GTK_CSS_CHANGE_STATE \
+                    | GTK_CSS_CHANGE_HOVER \
                     | GTK_CSS_CHANGE_SIBLING_CLASS \
                     | GTK_CSS_CHANGE_SIBLING_NAME \
                     | GTK_CSS_CHANGE_SIBLING_ID \
@@ -107,14 +106,15 @@ _gtk_css_change_for_child (GtkCssChange match)
                     | GTK_CSS_CHANGE_SIBLING_LAST_CHILD \
                     | GTK_CSS_CHANGE_SIBLING_NTH_CHILD \
                     | GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD \
-                    | GTK_CSS_CHANGE_SIBLING_STATE )
+                    | GTK_CSS_CHANGE_SIBLING_STATE \
+                    | GTK_CSS_CHANGE_SIBLING_HOVER)
 
-#define PARENT_SHIFT 16
+#define KEEP_STATES (~(BASE_STATES|GTK_CSS_CHANGE_SOURCE|GTK_CSS_CHANGE_PARENT_STYLE))
 
-  return (match & ~(BASE_STATES|GTK_CSS_CHANGE_SOURCE|GTK_CSS_CHANGE_PARENT_STYLE)) | ((match & BASE_STATES) 
<< PARENT_SHIFT);
+  return (match & KEEP_STATES) | ((match & BASE_STATES) << GTK_CSS_CHANGE_PARENT_SHIFT);
 
 #undef BASE_STATES
-#undef PARENT_SHIFT
+#undef KEEP_STATES
 }
 
 void
@@ -133,6 +133,8 @@ gtk_css_change_print (GtkCssChange  change,
     { GTK_CSS_CHANGE_NTH_CHILD, "nth-child" },
     { GTK_CSS_CHANGE_NTH_LAST_CHILD, "nth-last-child" },
     { GTK_CSS_CHANGE_STATE, "state" },
+    { GTK_CSS_CHANGE_HOVER, "hover" },
+
     { GTK_CSS_CHANGE_SIBLING_CLASS, "sibling-class" },
     { GTK_CSS_CHANGE_SIBLING_NAME, "sibling-name" },
     { GTK_CSS_CHANGE_SIBLING_ID, "sibling-id" },
@@ -141,6 +143,8 @@ gtk_css_change_print (GtkCssChange  change,
     { GTK_CSS_CHANGE_SIBLING_NTH_CHILD, "sibling-nth-child" },
     { GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD, "sibling-nth-last-child" },
     { GTK_CSS_CHANGE_SIBLING_STATE, "sibling-state" },
+    { GTK_CSS_CHANGE_SIBLING_HOVER, "sibling-hover" },
+
     { GTK_CSS_CHANGE_PARENT_CLASS, "parent-class" },
     { GTK_CSS_CHANGE_PARENT_NAME, "parent-name" },
     { GTK_CSS_CHANGE_PARENT_ID, "parent-id" },
@@ -149,6 +153,8 @@ gtk_css_change_print (GtkCssChange  change,
     { GTK_CSS_CHANGE_PARENT_NTH_CHILD, "parent-nth-child" },
     { GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD, "parent-nth-last-child" },
     { GTK_CSS_CHANGE_PARENT_STATE, "parent-state" },
+    { GTK_CSS_CHANGE_PARENT_HOVER, "parent-hover" },
+
     { GTK_CSS_CHANGE_PARENT_SIBLING_CLASS, "parent-sibling-" },
     { GTK_CSS_CHANGE_PARENT_SIBLING_NAME, "parent-sibling-name" },
     { GTK_CSS_CHANGE_PARENT_SIBLING_ID, "parent-sibling-id" },
@@ -157,6 +163,8 @@ gtk_css_change_print (GtkCssChange  change,
     { GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD, "parent-sibling-nth-child" },
     { GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD, "parent-sibling-nth-last-child" },
     { GTK_CSS_CHANGE_PARENT_SIBLING_STATE, "parent-sibling-state" },
+    { GTK_CSS_CHANGE_PARENT_SIBLING_HOVER, "parent-sibling-hover" },
+
     { GTK_CSS_CHANGE_SOURCE, "source" },
     { GTK_CSS_CHANGE_PARENT_STYLE, "parent-style" },
     { GTK_CSS_CHANGE_TIMESTAMP, "timestamp" },
diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h
index 573a17173f..a4f6dd01d1 100644
--- a/gtk/gtkcsstypesprivate.h
+++ b/gtk/gtkcsstypesprivate.h
@@ -36,61 +36,78 @@ typedef struct _GtkCssStyle GtkCssStyle;
 #define GTK_CSS_CHANGE_NTH_CHILD                      (1ULL <<  5)
 #define GTK_CSS_CHANGE_NTH_LAST_CHILD                 (1ULL <<  6)
 #define GTK_CSS_CHANGE_STATE                          (1ULL <<  7)
-#define GTK_CSS_CHANGE_SIBLING_CLASS                  (1ULL <<  8)
-#define GTK_CSS_CHANGE_SIBLING_NAME                   (1ULL <<  9)
-#define GTK_CSS_CHANGE_SIBLING_ID                     (1ULL << 10)
-#define GTK_CSS_CHANGE_SIBLING_FIRST_CHILD            (1ULL << 11)
-#define GTK_CSS_CHANGE_SIBLING_LAST_CHILD             (1ULL << 12)
-#define GTK_CSS_CHANGE_SIBLING_NTH_CHILD              (1ULL << 13)
-#define GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD         (1ULL << 14)
-#define GTK_CSS_CHANGE_SIBLING_STATE                  (1ULL << 15)
-#define GTK_CSS_CHANGE_PARENT_CLASS                   (1ULL << 16)
-#define GTK_CSS_CHANGE_PARENT_NAME                    (1ULL << 17)
-#define GTK_CSS_CHANGE_PARENT_ID                      (1ULL << 18)
-#define GTK_CSS_CHANGE_PARENT_FIRST_CHILD             (1ULL << 19)
-#define GTK_CSS_CHANGE_PARENT_LAST_CHILD              (1ULL << 20)
-#define GTK_CSS_CHANGE_PARENT_NTH_CHILD               (1ULL << 21)
-#define GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD          (1ULL << 22)
-#define GTK_CSS_CHANGE_PARENT_STATE                   (1ULL << 23)
-#define GTK_CSS_CHANGE_PARENT_SIBLING_CLASS           (1ULL << 24)
-#define GTK_CSS_CHANGE_PARENT_SIBLING_ID              (1ULL << 25)
-#define GTK_CSS_CHANGE_PARENT_SIBLING_NAME            (1ULL << 26)
-#define GTK_CSS_CHANGE_PARENT_SIBLING_FIRST_CHILD     (1ULL << 27)
-#define GTK_CSS_CHANGE_PARENT_SIBLING_LAST_CHILD      (1ULL << 28)
-#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD       (1ULL << 29)
-#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD  (1ULL << 30)
-#define GTK_CSS_CHANGE_PARENT_SIBLING_STATE           (1ULL << 31)
+#define GTK_CSS_CHANGE_HOVER                          (1ULL <<  8)
+
+#define GTK_CSS_CHANGE_SIBLING_SHIFT 9
+
+#define GTK_CSS_CHANGE_SIBLING_CLASS                  (1ULL <<  9)
+#define GTK_CSS_CHANGE_SIBLING_NAME                   (1ULL << 10)
+#define GTK_CSS_CHANGE_SIBLING_ID                     (1ULL << 11)
+#define GTK_CSS_CHANGE_SIBLING_FIRST_CHILD            (1ULL << 12)
+#define GTK_CSS_CHANGE_SIBLING_LAST_CHILD             (1ULL << 13)
+#define GTK_CSS_CHANGE_SIBLING_NTH_CHILD              (1ULL << 14)
+#define GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD         (1ULL << 15)
+#define GTK_CSS_CHANGE_SIBLING_STATE                  (1ULL << 16)
+#define GTK_CSS_CHANGE_SIBLING_HOVER                  (1ULL << 17)
+
+#define GTK_CSS_CHANGE_PARENT_SHIFT (GTK_CSS_CHANGE_SIBLING_SHIFT + GTK_CSS_CHANGE_SIBLING_SHIFT)
+
+#define GTK_CSS_CHANGE_PARENT_CLASS                   (1ULL << 18)
+#define GTK_CSS_CHANGE_PARENT_NAME                    (1ULL << 19)
+#define GTK_CSS_CHANGE_PARENT_ID                      (1ULL << 20)
+#define GTK_CSS_CHANGE_PARENT_FIRST_CHILD             (1ULL << 21)
+#define GTK_CSS_CHANGE_PARENT_LAST_CHILD              (1ULL << 22)
+#define GTK_CSS_CHANGE_PARENT_NTH_CHILD               (1ULL << 23)
+#define GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD          (1ULL << 24)
+#define GTK_CSS_CHANGE_PARENT_STATE                   (1ULL << 25)
+#define GTK_CSS_CHANGE_PARENT_HOVER                   (1ULL << 26)
+
+#define GTK_CSS_CHANGE_PARENT_SIBLING_SHIFT (GTK_CSS_CHANGE_PARENT_SHIFT + GTK_CSS_CHANGE_SIBLING_SHIFT)
+
+#define GTK_CSS_CHANGE_PARENT_SIBLING_CLASS           (1ULL << 27)
+#define GTK_CSS_CHANGE_PARENT_SIBLING_ID              (1ULL << 28)
+#define GTK_CSS_CHANGE_PARENT_SIBLING_NAME            (1ULL << 29)
+#define GTK_CSS_CHANGE_PARENT_SIBLING_FIRST_CHILD     (1ULL << 30)
+#define GTK_CSS_CHANGE_PARENT_SIBLING_LAST_CHILD      (1ULL << 31)
+#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD       (1ULL << 32)
+#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD  (1ULL << 33)
+#define GTK_CSS_CHANGE_PARENT_SIBLING_STATE           (1ULL << 34)
+#define GTK_CSS_CHANGE_PARENT_SIBLING_HOVER           (1ULL << 35)
 
 /* add more */
-#define GTK_CSS_CHANGE_SOURCE                         (1ULL << 32)
-#define GTK_CSS_CHANGE_PARENT_STYLE                   (1ULL << 33)
-#define GTK_CSS_CHANGE_TIMESTAMP                      (1ULL << 34)
-#define GTK_CSS_CHANGE_ANIMATIONS                     (1ULL << 35)
+#define GTK_CSS_CHANGE_SOURCE                         (1ULL << 36)
+#define GTK_CSS_CHANGE_PARENT_STYLE                   (1ULL << 37)
+#define GTK_CSS_CHANGE_TIMESTAMP                      (1ULL << 38)
+#define GTK_CSS_CHANGE_ANIMATIONS                     (1ULL << 39)
 
 #define GTK_CSS_CHANGE_RESERVED_BIT                   (1ULL << 62) /* Used internally in gtkcssselector.c */
 
 typedef guint64 GtkCssChange;
 
-#define GTK_CSS_CHANGE_POSITION (GTK_CSS_CHANGE_FIRST_CHILD | GTK_CSS_CHANGE_LAST_CHILD | \
-                                 GTK_CSS_CHANGE_NTH_CHILD | GTK_CSS_CHANGE_NTH_LAST_CHILD)
-#define GTK_CSS_CHANGE_SIBLING_POSITION (GTK_CSS_CHANGE_SIBLING_FIRST_CHILD | 
GTK_CSS_CHANGE_SIBLING_LAST_CHILD | \
-                                         GTK_CSS_CHANGE_SIBLING_NTH_CHILD | 
GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD)
-#define GTK_CSS_CHANGE_PARENT_POSITION (GTK_CSS_CHANGE_PARENT_FIRST_CHILD | GTK_CSS_CHANGE_PARENT_LAST_CHILD 
| \
-                                        GTK_CSS_CHANGE_PARENT_NTH_CHILD | 
GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD)
-#define GTK_CSS_CHANGE_PARENT_SIBLING_POSITION (GTK_CSS_CHANGE_PARENT_SIBLING_FIRST_CHILD | 
GTK_CSS_CHANGE_PARENT_SIBLING_LAST_CHILD | \
-                                                GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD | 
GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD)
-
-
-#define GTK_CSS_CHANGE_ANY ((1 << 19) - 1)
-#define GTK_CSS_CHANGE_ANY_SELF (GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_ID | 
GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_STATE)
-#define GTK_CSS_CHANGE_ANY_SIBLING (GTK_CSS_CHANGE_SIBLING_CLASS | GTK_CSS_CHANGE_SIBLING_NAME | \
-                                    GTK_CSS_CHANGE_SIBLING_ID | \
-                                    GTK_CSS_CHANGE_SIBLING_POSITION | GTK_CSS_CHANGE_SIBLING_STATE)
-#define GTK_CSS_CHANGE_ANY_PARENT (GTK_CSS_CHANGE_PARENT_CLASS | GTK_CSS_CHANGE_PARENT_SIBLING_CLASS | \
-                                   GTK_CSS_CHANGE_PARENT_NAME | GTK_CSS_CHANGE_PARENT_SIBLING_NAME | \
-                                   GTK_CSS_CHANGE_PARENT_ID | GTK_CSS_CHANGE_PARENT_SIBLING_ID | \
-                                   GTK_CSS_CHANGE_PARENT_POSITION | GTK_CSS_CHANGE_PARENT_SIBLING_POSITION | 
\
-                                   GTK_CSS_CHANGE_PARENT_STATE | GTK_CSS_CHANGE_PARENT_SIBLING_STATE)
+#define GTK_CSS_CHANGE_POSITION (GTK_CSS_CHANGE_FIRST_CHILD | \
+                                 GTK_CSS_CHANGE_LAST_CHILD  | \
+                                 GTK_CSS_CHANGE_NTH_CHILD   | \
+                                 GTK_CSS_CHANGE_NTH_LAST_CHILD)
+#define GTK_CSS_CHANGE_SIBLING_POSITION (GTK_CSS_CHANGE_POSITION << GTK_CSS_CHANGE_SIBLING_SHIFT)
+
+#define GTK_CSS_CHANGE_ANY_SELF (GTK_CSS_CHANGE_CLASS    | \
+                                 GTK_CSS_CHANGE_NAME     | \
+                                 GTK_CSS_CHANGE_ID       | \
+                                 GTK_CSS_CHANGE_POSITION | \
+                                 GTK_CSS_CHANGE_STATE    | \
+                                 GTK_CSS_CHANGE_HOVER)
+#define GTK_CSS_CHANGE_ANY_SIBLING (GTK_CSS_CHANGE_ANY_SELF << GTK_CSS_CHANGE_SIBLING_SHIFT)
+#define GTK_CSS_CHANGE_ANY_PARENT (GTK_CSS_CHANGE_ANY_SELF << GTK_CSS_CHANGE_PARENT_SHIFT)
+#define GTK_CSS_CHANGE_ANY_PARENT_SIBLING (GTK_CSS_CHANGE_ANY_SELF << GTK_CSS_CHANGE_PARENT_SIBLING_SHIFT)
+
+#define GTK_CSS_CHANGE_ANY (GTK_CSS_CHANGE_ANY_SELF           | \
+                            GTK_CSS_CHANGE_ANY_SIBLING        | \
+                            GTK_CSS_CHANGE_ANY_PARENT         | \
+                            GTK_CSS_CHANGE_ANY_PARENT_SIBLING | \
+                            GTK_CSS_CHANGE_SOURCE             | \
+                            GTK_CSS_CHANGE_PARENT_STYLE       | \
+                            GTK_CSS_CHANGE_TIMESTAMP          | \
+                            GTK_CSS_CHANGE_ANIMATIONS)
 
 /*
  * GtkCssAffects:


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