summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-01-15 15:10:06 -0500
committerMatthias Clasen <mclasen@redhat.com>2020-01-16 11:17:48 -0500
commitfcceac6d118354ac3e73cd80c4dab8d026e49721 (patch)
treeba812fcdebf2e94c9cdce8c2b62fd693c03121c3
parente8eb1df29f15361697d7f6062d0466f61d072f2e (diff)
downloadgtk+-fcceac6d118354ac3e73cd80c4dab8d026e49721.tar.gz
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.
-rw-r--r--gtk/gtkcssmatcher.c2
-rw-r--r--gtk/gtkcssnode.c14
-rw-r--r--gtk/gtkcssselector.c17
-rw-r--r--gtk/gtkcsstypes.c26
-rw-r--r--gtk/gtkcsstypesprivate.h113
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: