css: Track hover state changes separately
authorMatthias Clasen <mclasen@redhat.com>
Wed, 15 Jan 2020 20:10:06 +0000 (15:10 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 16 Jan 2020 16:17:48 +0000 (11:17 -0500)
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
gtk/gtkcssnode.c
gtk/gtkcssselector.c
gtk/gtkcsstypes.c
gtk/gtkcsstypesprivate.h

index 899a7f74f64b89f40cde5ceff2cabafa07485bc1..87364177bee2c6cd2b997f19e1312e6d47d10aca 100644 (file)
@@ -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;
index 0cce324e055f06b3a6a2ec07476533c5ae738330..cdc72d18813c03b93d4b94b69bb38dd1c4c6d571 100644 (file)
@@ -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]);
     }
 }
index b6468bd28266854540477cb092a12b072a0d9d83..16439e5ba7af9d7007caa6ca16ef3579794a37ba 100644 (file)
@@ -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
index 8bae7c397c88ee9e4f6ec09fd2d5569bd22fe059..7f42e1514ea86098bda358e87bb36d15129c763e 100644 (file)
@@ -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" },
index 573a17173f6f413923a7a010bac7e04f7d7cbba5..a4f6dd01d1d32d4ec1722571d2074e2dca9dcf65 100644 (file)
@@ -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: