From 60cd7cd96c89fbfadbe23889b3ba629a71116bcc Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 15 Jan 2020 17:34:03 -0500 Subject: [PATCH 1/6] css: Fix the ANY matcher state list The ANY and matcher was not, in fact, matching any state, since the list of states was not up-to-date. The same fix applies to the superset matcher as well. --- gtk/gtkcssmatcher.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/gtk/gtkcssmatcher.c b/gtk/gtkcssmatcher.c index fb80c3ef80..0b2c5442df 100644 --- a/gtk/gtkcssmatcher.c +++ b/gtk/gtkcssmatcher.c @@ -383,10 +383,20 @@ gtk_css_matcher_any_get_state (const GtkCssMatcher *matcher) { /* XXX: This gets tricky when we implement :not() */ - return GTK_STATE_FLAG_ACTIVE | GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED - | GTK_STATE_FLAG_INSENSITIVE | GTK_STATE_FLAG_INCONSISTENT - | GTK_STATE_FLAG_FOCUSED | GTK_STATE_FLAG_BACKDROP | GTK_STATE_FLAG_LINK - | GTK_STATE_FLAG_VISITED; + return GTK_STATE_FLAG_ACTIVE | + GTK_STATE_FLAG_PRELIGHT | + GTK_STATE_FLAG_SELECTED | + GTK_STATE_FLAG_INSENSITIVE | + GTK_STATE_FLAG_INCONSISTENT | + GTK_STATE_FLAG_FOCUSED | + GTK_STATE_FLAG_BACKDROP | + GTK_STATE_FLAG_DIR_LTR | + GTK_STATE_FLAG_DIR_RTL | + GTK_STATE_FLAG_LINK | + GTK_STATE_FLAG_VISITED | + GTK_STATE_FLAG_CHECKED | + GTK_STATE_FLAG_DROP_ACTIVE | + GTK_STATE_FLAG_FOCUS_VISIBLE; } static gboolean @@ -464,10 +474,20 @@ gtk_css_matcher_superset_get_state (const GtkCssMatcher *matcher) if (matcher->superset.relevant & GTK_CSS_CHANGE_STATE) return _gtk_css_matcher_get_state (matcher->superset.subset); else - return GTK_STATE_FLAG_ACTIVE | GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED - | GTK_STATE_FLAG_INSENSITIVE | GTK_STATE_FLAG_INCONSISTENT - | GTK_STATE_FLAG_FOCUSED | GTK_STATE_FLAG_BACKDROP | GTK_STATE_FLAG_LINK - | GTK_STATE_FLAG_VISITED; + return GTK_STATE_FLAG_ACTIVE | + GTK_STATE_FLAG_PRELIGHT | + GTK_STATE_FLAG_SELECTED | + GTK_STATE_FLAG_INSENSITIVE | + GTK_STATE_FLAG_INCONSISTENT | + GTK_STATE_FLAG_FOCUSED | + GTK_STATE_FLAG_BACKDROP | + GTK_STATE_FLAG_DIR_LTR | + GTK_STATE_FLAG_DIR_RTL | + GTK_STATE_FLAG_LINK | + GTK_STATE_FLAG_VISITED | + GTK_STATE_FLAG_CHECKED | + GTK_STATE_FLAG_DROP_ACTIVE | + GTK_STATE_FLAG_FOCUS_VISIBLE; } static gboolean From 0dba6e5759839a8478fb9fbac707394cd35ed8f0 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 16 Jan 2020 17:47:41 -0500 Subject: [PATCH 2/6] Cosmetic change Update comments for name changes that happened long ago. --- gtk/gtkcssmatcher.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtk/gtkcssmatcher.c b/gtk/gtkcssmatcher.c index 0b2c5442df..cfcaf25db1 100644 --- a/gtk/gtkcssmatcher.c +++ b/gtk/gtkcssmatcher.c @@ -358,7 +358,7 @@ _gtk_css_matcher_node_init (GtkCssMatcher *matcher, &matcher->node.n_classes); } -/* GTK_CSS_MATCHER_WIDGET_ANY */ +/* GTK_CSS_MATCHER_ANY */ static gboolean gtk_css_matcher_any_get_parent (GtkCssMatcher *matcher, @@ -446,7 +446,7 @@ _gtk_css_matcher_any_init (GtkCssMatcher *matcher) matcher->klass = >K_CSS_MATCHER_ANY; } -/* GTK_CSS_MATCHER_WIDGET_SUPERSET */ +/* GTK_CSS_MATCHER_SUPERSET */ static gboolean gtk_css_matcher_superset_get_parent (GtkCssMatcher *matcher, From f0c1c3349f4ce90b2a23331003936fe4b33e320b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 16 Jan 2020 17:50:32 -0500 Subject: [PATCH 3/6] css: Simplify the superset matcher We use the superset matcher in exactly one place, so there is no need for the generality of allowing to ignore different aspects. Just hardcode the one case we need: ignoring everything except for name, id and class. --- gtk/gtkcssmatcher.c | 57 +++++++++++++------------------------- gtk/gtkcssmatcherprivate.h | 4 +-- gtk/gtkcssprovider.c | 2 +- 3 files changed, 21 insertions(+), 42 deletions(-) diff --git a/gtk/gtkcssmatcher.c b/gtk/gtkcssmatcher.c index cfcaf25db1..6329029589 100644 --- a/gtk/gtkcssmatcher.c +++ b/gtk/gtkcssmatcher.c @@ -471,53 +471,41 @@ gtk_css_matcher_superset_get_state (const GtkCssMatcher *matcher) { /* XXX: This gets tricky when we implement :not() */ - if (matcher->superset.relevant & GTK_CSS_CHANGE_STATE) - return _gtk_css_matcher_get_state (matcher->superset.subset); - else - return GTK_STATE_FLAG_ACTIVE | - GTK_STATE_FLAG_PRELIGHT | - GTK_STATE_FLAG_SELECTED | - GTK_STATE_FLAG_INSENSITIVE | - GTK_STATE_FLAG_INCONSISTENT | - GTK_STATE_FLAG_FOCUSED | - GTK_STATE_FLAG_BACKDROP | - GTK_STATE_FLAG_DIR_LTR | - GTK_STATE_FLAG_DIR_RTL | - GTK_STATE_FLAG_LINK | - GTK_STATE_FLAG_VISITED | - GTK_STATE_FLAG_CHECKED | - GTK_STATE_FLAG_DROP_ACTIVE | - GTK_STATE_FLAG_FOCUS_VISIBLE; + return GTK_STATE_FLAG_ACTIVE | + GTK_STATE_FLAG_PRELIGHT | + GTK_STATE_FLAG_SELECTED | + GTK_STATE_FLAG_INSENSITIVE | + GTK_STATE_FLAG_INCONSISTENT | + GTK_STATE_FLAG_FOCUSED | + GTK_STATE_FLAG_BACKDROP | + GTK_STATE_FLAG_DIR_LTR | + GTK_STATE_FLAG_DIR_RTL | + GTK_STATE_FLAG_LINK | + GTK_STATE_FLAG_VISITED | + GTK_STATE_FLAG_CHECKED | + GTK_STATE_FLAG_DROP_ACTIVE | + GTK_STATE_FLAG_FOCUS_VISIBLE; } static gboolean gtk_css_matcher_superset_has_name (const GtkCssMatcher *matcher, /*interned*/ const char *name) { - if (matcher->superset.relevant & GTK_CSS_CHANGE_NAME) - return _gtk_css_matcher_has_name (matcher->superset.subset, name); - else - return TRUE; + return _gtk_css_matcher_has_name (matcher->superset.subset, name); } static gboolean gtk_css_matcher_superset_has_class (const GtkCssMatcher *matcher, GQuark class_name) { - if (matcher->superset.relevant & GTK_CSS_CHANGE_CLASS) - return _gtk_css_matcher_has_class (matcher->superset.subset, class_name); - else - return TRUE; + return _gtk_css_matcher_has_class (matcher->superset.subset, class_name); } static gboolean gtk_css_matcher_superset_has_id (const GtkCssMatcher *matcher, const char *id) { - if (matcher->superset.relevant & GTK_CSS_CHANGE_NAME) - return _gtk_css_matcher_has_id (matcher->superset.subset, id); - else - return TRUE; + return _gtk_css_matcher_has_id (matcher->superset.subset, id); } static gboolean @@ -526,10 +514,7 @@ gtk_css_matcher_superset_has_position (const GtkCssMatcher *matcher, int a, int b) { - if (matcher->superset.relevant & GTK_CSS_CHANGE_POSITION) - return _gtk_css_matcher_has_position (matcher->superset.subset, forward, a, b); - else - return TRUE; + return TRUE; } static const GtkCssMatcherClass GTK_CSS_MATCHER_SUPERSET = { @@ -545,14 +530,10 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_SUPERSET = { void _gtk_css_matcher_superset_init (GtkCssMatcher *matcher, - const GtkCssMatcher *subset, - GtkCssChange relevant) + const GtkCssMatcher *subset) { 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 | GTK_CSS_CHANGE_HOVER | GTK_CSS_CHANGE_DISABLED | GTK_CSS_CHANGE_BACKDROP | GTK_CSS_CHANGE_SELECTED)) == 0); matcher->superset.klass = >K_CSS_MATCHER_SUPERSET; matcher->superset.subset = subset; - matcher->superset.relevant = relevant; } - diff --git a/gtk/gtkcssmatcherprivate.h b/gtk/gtkcssmatcherprivate.h index a78f777abb..4be2b3ff64 100644 --- a/gtk/gtkcssmatcherprivate.h +++ b/gtk/gtkcssmatcherprivate.h @@ -70,7 +70,6 @@ struct _GtkCssMatcherNode { struct _GtkCssMatcherSuperset { const GtkCssMatcherClass *klass; const GtkCssMatcher *subset; - GtkCssChange relevant; }; union _GtkCssMatcher { @@ -87,8 +86,7 @@ void _gtk_css_matcher_node_init (GtkCssMatcher *match GtkCssNode *node); void _gtk_css_matcher_any_init (GtkCssMatcher *matcher); void _gtk_css_matcher_superset_init (GtkCssMatcher *matcher, - const GtkCssMatcher *subset, - GtkCssChange relevant); + const GtkCssMatcher *subset); static inline gboolean diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c index 59573ebb34..76be1f5eb0 100644 --- a/gtk/gtkcssprovider.c +++ b/gtk/gtkcssprovider.c @@ -440,7 +440,7 @@ compute_change (GtkCssProvider *provider, int i; GtkCssMatcher change_matcher; - _gtk_css_matcher_superset_init (&change_matcher, matcher, GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS); + _gtk_css_matcher_superset_init (&change_matcher, matcher); tree_rules = _gtk_css_selector_tree_match_all (priv->tree, &change_matcher); if (tree_rules) From 007713c0ba62ab1d0497f593fc621a271521f53d Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 14 Jan 2020 22:29:56 -0500 Subject: [PATCH 4/6] css: Add a matcher type enum For now, this just replaces the is_any boolean by a type field in the class. It will be used in future commits. --- gtk/gtkcssmatcher.c | 16 ++++++++-------- gtk/gtkcssmatcherprivate.h | 11 +++++++++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/gtk/gtkcssmatcher.c b/gtk/gtkcssmatcher.c index 6329029589..8665d9f2a1 100644 --- a/gtk/gtkcssmatcher.c +++ b/gtk/gtkcssmatcher.c @@ -159,14 +159,14 @@ gtk_css_matcher_widget_path_has_position (const GtkCssMatcher *matcher, } static const GtkCssMatcherClass GTK_CSS_MATCHER_WIDGET_PATH = { + GTK_CSS_MATCHER_TYPE_WIDGET_PATH, gtk_css_matcher_widget_path_get_parent, gtk_css_matcher_widget_path_get_previous, gtk_css_matcher_widget_path_get_state, gtk_css_matcher_widget_path_has_name, gtk_css_matcher_widget_path_has_class, gtk_css_matcher_widget_path_has_id, - gtk_css_matcher_widget_path_has_position, - FALSE + gtk_css_matcher_widget_path_has_position }; gboolean @@ -335,14 +335,14 @@ gtk_css_matcher_node_has_position (const GtkCssMatcher *matcher, } static const GtkCssMatcherClass GTK_CSS_MATCHER_NODE = { + GTK_CSS_MATCHER_TYPE_NODE, gtk_css_matcher_node_get_parent, gtk_css_matcher_node_get_previous, gtk_css_matcher_node_get_state, gtk_css_matcher_node_has_name, gtk_css_matcher_node_has_class, gtk_css_matcher_node_has_id, - gtk_css_matcher_node_has_position, - FALSE + gtk_css_matcher_node_has_position }; void @@ -430,14 +430,14 @@ gtk_css_matcher_any_has_position (const GtkCssMatcher *matcher, } static const GtkCssMatcherClass GTK_CSS_MATCHER_ANY = { + GTK_CSS_MATCHER_TYPE_ANY, gtk_css_matcher_any_get_parent, gtk_css_matcher_any_get_previous, gtk_css_matcher_any_get_state, gtk_css_matcher_any_has_name, gtk_css_matcher_any_has_class, gtk_css_matcher_any_has_id, - gtk_css_matcher_any_has_position, - TRUE + gtk_css_matcher_any_has_position }; void @@ -518,14 +518,14 @@ gtk_css_matcher_superset_has_position (const GtkCssMatcher *matcher, } static const GtkCssMatcherClass GTK_CSS_MATCHER_SUPERSET = { + GTK_CSS_MATCHER_TYPE_SUPERSET, gtk_css_matcher_superset_get_parent, gtk_css_matcher_superset_get_previous, gtk_css_matcher_superset_get_state, gtk_css_matcher_superset_has_name, gtk_css_matcher_superset_has_class, gtk_css_matcher_superset_has_id, - gtk_css_matcher_superset_has_position, - FALSE + gtk_css_matcher_superset_has_position }; void diff --git a/gtk/gtkcssmatcherprivate.h b/gtk/gtkcssmatcherprivate.h index 4be2b3ff64..2a211ec424 100644 --- a/gtk/gtkcssmatcherprivate.h +++ b/gtk/gtkcssmatcherprivate.h @@ -29,7 +29,15 @@ typedef struct _GtkCssMatcherSuperset GtkCssMatcherSuperset; typedef struct _GtkCssMatcherWidgetPath GtkCssMatcherWidgetPath; typedef struct _GtkCssMatcherClass GtkCssMatcherClass; +typedef enum { + GTK_CSS_MATCHER_TYPE_NODE, + GTK_CSS_MATCHER_TYPE_WIDGET_PATH, + GTK_CSS_MATCHER_TYPE_ANY, + GTK_CSS_MATCHER_TYPE_SUPERSET +} GtkCssMatcherType; + struct _GtkCssMatcherClass { + GtkCssMatcherType type; gboolean (* get_parent) (GtkCssMatcher *matcher, const GtkCssMatcher *child); gboolean (* get_previous) (GtkCssMatcher *matcher, @@ -46,7 +54,6 @@ struct _GtkCssMatcherClass { gboolean forward, int a, int b); - gboolean is_any; }; struct _GtkCssMatcherWidgetPath { @@ -142,7 +149,7 @@ _gtk_css_matcher_has_position (const GtkCssMatcher *matcher, static inline gboolean _gtk_css_matcher_matches_any (const GtkCssMatcher *matcher) { - return matcher->klass->is_any; + return matcher->klass->type == GTK_CSS_MATCHER_TYPE_ANY; } From 7588655a42d04f83f2f8819f652c86115701e928 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 15 Jan 2020 02:03:08 -0500 Subject: [PATCH 5/6] Allow printing css matchers This can help in debugging css matching. --- gtk/gtkcssmatcher.c | 59 +++++++++++++++++++++++++++++++++++--- gtk/gtkcssmatcherprivate.h | 7 ++++- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/gtk/gtkcssmatcher.c b/gtk/gtkcssmatcher.c index 8665d9f2a1..1ceffa95da 100644 --- a/gtk/gtkcssmatcher.c +++ b/gtk/gtkcssmatcher.c @@ -23,6 +23,21 @@ #include "gtkcssnodeprivate.h" #include "gtkwidgetpath.h" +void +gtk_css_matcher_print (const GtkCssMatcher *matcher, + GString *string) +{ + matcher->klass->print (matcher, string); +} + +char * +gtk_css_matcher_to_string (const GtkCssMatcher *matcher) +{ + GString *string = g_string_new (""); + gtk_css_matcher_print (matcher, string); + return g_string_free (string, FALSE); +} + /* GTK_CSS_MATCHER_WIDGET_PATH */ static gboolean @@ -158,6 +173,15 @@ gtk_css_matcher_widget_path_has_position (const GtkCssMatcher *matcher, return x / a >= 0; } +static void +gtk_css_matcher_widget_path_print (const GtkCssMatcher *matcher, + GString *string) +{ + char *s = gtk_widget_path_to_string (matcher->path.path); + g_string_append (string, s); + g_free (s); +} + static const GtkCssMatcherClass GTK_CSS_MATCHER_WIDGET_PATH = { GTK_CSS_MATCHER_TYPE_WIDGET_PATH, gtk_css_matcher_widget_path_get_parent, @@ -166,7 +190,8 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_WIDGET_PATH = { gtk_css_matcher_widget_path_has_name, gtk_css_matcher_widget_path_has_class, gtk_css_matcher_widget_path_has_id, - gtk_css_matcher_widget_path_has_position + gtk_css_matcher_widget_path_has_position, + gtk_css_matcher_widget_path_print }; gboolean @@ -334,6 +359,13 @@ gtk_css_matcher_node_has_position (const GtkCssMatcher *matcher, a, b); } +static void +gtk_css_matcher_node_print (const GtkCssMatcher *matcher, + GString *string) +{ + gtk_css_node_print (matcher->node.node, 0, string, 0); +} + static const GtkCssMatcherClass GTK_CSS_MATCHER_NODE = { GTK_CSS_MATCHER_TYPE_NODE, gtk_css_matcher_node_get_parent, @@ -342,7 +374,8 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_NODE = { gtk_css_matcher_node_has_name, gtk_css_matcher_node_has_class, gtk_css_matcher_node_has_id, - gtk_css_matcher_node_has_position + gtk_css_matcher_node_has_position, + gtk_css_matcher_node_print }; void @@ -429,6 +462,13 @@ gtk_css_matcher_any_has_position (const GtkCssMatcher *matcher, return TRUE; } +static void +gtk_css_matcher_any_print (const GtkCssMatcher *matcher, + GString *string) +{ + g_string_append (string, "ANY"); +} + static const GtkCssMatcherClass GTK_CSS_MATCHER_ANY = { GTK_CSS_MATCHER_TYPE_ANY, gtk_css_matcher_any_get_parent, @@ -437,7 +477,8 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_ANY = { gtk_css_matcher_any_has_name, gtk_css_matcher_any_has_class, gtk_css_matcher_any_has_id, - gtk_css_matcher_any_has_position + gtk_css_matcher_any_has_position, + gtk_css_matcher_any_print }; void @@ -517,6 +558,15 @@ gtk_css_matcher_superset_has_position (const GtkCssMatcher *matcher, return TRUE; } +static void +gtk_css_matcher_superset_print (const GtkCssMatcher *matcher, + GString *string) +{ + g_string_append (string, "SUPERSET("); + gtk_css_matcher_print (matcher->superset.subset, string); + g_string_append (string, ")"); +} + static const GtkCssMatcherClass GTK_CSS_MATCHER_SUPERSET = { GTK_CSS_MATCHER_TYPE_SUPERSET, gtk_css_matcher_superset_get_parent, @@ -525,7 +575,8 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_SUPERSET = { gtk_css_matcher_superset_has_name, gtk_css_matcher_superset_has_class, gtk_css_matcher_superset_has_id, - gtk_css_matcher_superset_has_position + gtk_css_matcher_superset_has_position, + gtk_css_matcher_superset_print }; void diff --git a/gtk/gtkcssmatcherprivate.h b/gtk/gtkcssmatcherprivate.h index 2a211ec424..2e7f70a131 100644 --- a/gtk/gtkcssmatcherprivate.h +++ b/gtk/gtkcssmatcherprivate.h @@ -54,6 +54,8 @@ struct _GtkCssMatcherClass { gboolean forward, int a, int b); + void (* print) (const GtkCssMatcher *matcher, + GString *string); }; struct _GtkCssMatcherWidgetPath { @@ -95,6 +97,10 @@ void _gtk_css_matcher_any_init (GtkCssMatcher *match void _gtk_css_matcher_superset_init (GtkCssMatcher *matcher, const GtkCssMatcher *subset); +void gtk_css_matcher_print (const GtkCssMatcher *matcher, + GString *string); +char * gtk_css_matcher_to_string (const GtkCssMatcher *matcher); + static inline gboolean _gtk_css_matcher_get_parent (GtkCssMatcher *matcher, @@ -152,7 +158,6 @@ _gtk_css_matcher_matches_any (const GtkCssMatcher *matcher) return matcher->klass->type == GTK_CSS_MATCHER_TYPE_ANY; } - G_END_DECLS #endif /* __GTK_CSS_MATCHER_PRIVATE_H__ */ From 93b5b487ae42bf75ab234449c7583f8cbd7c2874 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 16 Jan 2020 19:23:45 -0500 Subject: [PATCH 6/6] cssmatcher: Change get_state to has_state This matches all the other vfuncs, and it gets us out of keeping several big state flag enumerations in sync. Update all callers. --- gtk/gtkcssmatcher.c | 84 +++++++++++++++----------------------- gtk/gtkcssmatcherprivate.h | 10 +++-- gtk/gtkcssselector.c | 2 +- 3 files changed, 39 insertions(+), 57 deletions(-) diff --git a/gtk/gtkcssmatcher.c b/gtk/gtkcssmatcher.c index 1ceffa95da..86e5540a47 100644 --- a/gtk/gtkcssmatcher.c +++ b/gtk/gtkcssmatcher.c @@ -72,19 +72,26 @@ gtk_css_matcher_widget_path_get_previous (GtkCssMatcher *matcher, return TRUE; } -static GtkStateFlags -gtk_css_matcher_widget_path_get_state (const GtkCssMatcher *matcher) +static gboolean +gtk_css_matcher_widget_path_has_state (const GtkCssMatcher *matcher, + GtkStateFlags state) { - const GtkWidgetPath *siblings; + GtkStateFlags path_state; if (matcher->path.decl) - return gtk_css_node_declaration_get_state (matcher->path.decl); - - siblings = gtk_widget_path_iter_get_siblings (matcher->path.path, matcher->path.index); - if (siblings && matcher->path.sibling_index != gtk_widget_path_iter_get_sibling_index (matcher->path.path, matcher->path.index)) - return gtk_widget_path_iter_get_state (siblings, matcher->path.sibling_index); + path_state = gtk_css_node_declaration_get_state (matcher->path.decl); else - return gtk_widget_path_iter_get_state (matcher->path.path, matcher->path.index); + { + const GtkWidgetPath *siblings; + + siblings = gtk_widget_path_iter_get_siblings (matcher->path.path, matcher->path.index); + if (siblings && matcher->path.sibling_index != gtk_widget_path_iter_get_sibling_index (matcher->path.path, matcher->path.index)) + path_state = gtk_widget_path_iter_get_state (siblings, matcher->path.sibling_index); + else + path_state = gtk_widget_path_iter_get_state (matcher->path.path, matcher->path.index); + } + + return (path_state & state) == state; } static gboolean @@ -186,7 +193,7 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_WIDGET_PATH = { GTK_CSS_MATCHER_TYPE_WIDGET_PATH, gtk_css_matcher_widget_path_get_parent, gtk_css_matcher_widget_path_get_previous, - gtk_css_matcher_widget_path_get_state, + gtk_css_matcher_widget_path_has_state, gtk_css_matcher_widget_path_has_name, gtk_css_matcher_widget_path_has_class, gtk_css_matcher_widget_path_has_id, @@ -259,10 +266,11 @@ gtk_css_matcher_node_get_previous (GtkCssMatcher *matcher, return gtk_css_node_init_matcher (node, matcher); } -static GtkStateFlags -gtk_css_matcher_node_get_state (const GtkCssMatcher *matcher) +static gboolean +gtk_css_matcher_node_has_state (const GtkCssMatcher *matcher, + GtkStateFlags state) { - return matcher->node.node_state; + return (matcher->node.node_state & state) == state; } static gboolean @@ -370,7 +378,7 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_NODE = { GTK_CSS_MATCHER_TYPE_NODE, gtk_css_matcher_node_get_parent, gtk_css_matcher_node_get_previous, - gtk_css_matcher_node_get_state, + gtk_css_matcher_node_has_state, gtk_css_matcher_node_has_name, gtk_css_matcher_node_has_class, gtk_css_matcher_node_has_id, @@ -411,25 +419,11 @@ gtk_css_matcher_any_get_previous (GtkCssMatcher *matcher, return TRUE; } -static GtkStateFlags -gtk_css_matcher_any_get_state (const GtkCssMatcher *matcher) +static gboolean +gtk_css_matcher_any_has_state (const GtkCssMatcher *matcher, + GtkStateFlags state) { - /* XXX: This gets tricky when we implement :not() */ - - return GTK_STATE_FLAG_ACTIVE | - GTK_STATE_FLAG_PRELIGHT | - GTK_STATE_FLAG_SELECTED | - GTK_STATE_FLAG_INSENSITIVE | - GTK_STATE_FLAG_INCONSISTENT | - GTK_STATE_FLAG_FOCUSED | - GTK_STATE_FLAG_BACKDROP | - GTK_STATE_FLAG_DIR_LTR | - GTK_STATE_FLAG_DIR_RTL | - GTK_STATE_FLAG_LINK | - GTK_STATE_FLAG_VISITED | - GTK_STATE_FLAG_CHECKED | - GTK_STATE_FLAG_DROP_ACTIVE | - GTK_STATE_FLAG_FOCUS_VISIBLE; + return TRUE; } static gboolean @@ -473,7 +467,7 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_ANY = { GTK_CSS_MATCHER_TYPE_ANY, gtk_css_matcher_any_get_parent, gtk_css_matcher_any_get_previous, - gtk_css_matcher_any_get_state, + gtk_css_matcher_any_has_state, gtk_css_matcher_any_has_name, gtk_css_matcher_any_has_class, gtk_css_matcher_any_has_id, @@ -507,25 +501,11 @@ gtk_css_matcher_superset_get_previous (GtkCssMatcher *matcher, return TRUE; } -static GtkStateFlags -gtk_css_matcher_superset_get_state (const GtkCssMatcher *matcher) +static gboolean +gtk_css_matcher_superset_has_state (const GtkCssMatcher *matcher, + GtkStateFlags state) { - /* XXX: This gets tricky when we implement :not() */ - - return GTK_STATE_FLAG_ACTIVE | - GTK_STATE_FLAG_PRELIGHT | - GTK_STATE_FLAG_SELECTED | - GTK_STATE_FLAG_INSENSITIVE | - GTK_STATE_FLAG_INCONSISTENT | - GTK_STATE_FLAG_FOCUSED | - GTK_STATE_FLAG_BACKDROP | - GTK_STATE_FLAG_DIR_LTR | - GTK_STATE_FLAG_DIR_RTL | - GTK_STATE_FLAG_LINK | - GTK_STATE_FLAG_VISITED | - GTK_STATE_FLAG_CHECKED | - GTK_STATE_FLAG_DROP_ACTIVE | - GTK_STATE_FLAG_FOCUS_VISIBLE; + return TRUE; } static gboolean @@ -571,7 +551,7 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_SUPERSET = { GTK_CSS_MATCHER_TYPE_SUPERSET, gtk_css_matcher_superset_get_parent, gtk_css_matcher_superset_get_previous, - gtk_css_matcher_superset_get_state, + gtk_css_matcher_superset_has_state, gtk_css_matcher_superset_has_name, gtk_css_matcher_superset_has_class, gtk_css_matcher_superset_has_id, diff --git a/gtk/gtkcssmatcherprivate.h b/gtk/gtkcssmatcherprivate.h index 2e7f70a131..094957bdaa 100644 --- a/gtk/gtkcssmatcherprivate.h +++ b/gtk/gtkcssmatcherprivate.h @@ -43,7 +43,8 @@ struct _GtkCssMatcherClass { gboolean (* get_previous) (GtkCssMatcher *matcher, const GtkCssMatcher *next); - GtkStateFlags (* get_state) (const GtkCssMatcher *matcher); + gboolean (* has_state) (const GtkCssMatcher *matcher, + GtkStateFlags state); gboolean (* has_name) (const GtkCssMatcher *matcher, /*interned*/const char*name); gboolean (* has_class) (const GtkCssMatcher *matcher, @@ -116,10 +117,11 @@ _gtk_css_matcher_get_previous (GtkCssMatcher *matcher, return next->klass->get_previous (matcher, next); } -static inline GtkStateFlags -_gtk_css_matcher_get_state (const GtkCssMatcher *matcher) +static inline gboolean +_gtk_css_matcher_has_state (const GtkCssMatcher *matcher, + GtkStateFlags state) { - return matcher->klass->get_state (matcher); + return matcher->klass->has_state (matcher, state); } static inline gboolean diff --git a/gtk/gtkcssselector.c b/gtk/gtkcssselector.c index e260cf159c..8957e49413 100644 --- a/gtk/gtkcssselector.c +++ b/gtk/gtkcssselector.c @@ -711,7 +711,7 @@ static gboolean match_pseudoclass_state (const GtkCssSelector *selector, const GtkCssMatcher *matcher) { - return (_gtk_css_matcher_get_state (matcher) & selector->state.state) == selector->state.state; + return _gtk_css_matcher_has_state (matcher, selector->state.state); } static guint