selector: Make :not() selectors not radical

:not() selectors cannot be radical because the bloomfilter only knows if
a value is set in any of the nodes, but cannot determine the opposite
(if a value is not set in at least one node), but that would be required
for:not() selectors.
However, this is very unlikely to happen in the real world, so it's not
worth optimizing.

Unfortunately, change tracking could know this, so by excluding the
:not() selectors from radical changes, the change tracking will now pick
them up. If that turns out to be a performance problem, we need to add a
special category for radical not filters, so change tracking and bloom
filters can deal with them.

The testcase demonstrating the problem in widget-factory has been
extrated and added.
This commit is contained in:
Benjamin Otte 2020-01-27 02:49:36 +01:00
parent 93cf76b068
commit ccdc3ee406
6 changed files with 69 additions and 2 deletions

View File

@ -540,7 +540,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_ ## c = { \
\
static const GtkCssSelectorClass GTK_CSS_SELECTOR_NOT_ ## c = { \
"not_" G_STRINGIFY(n), \
ignore_for_change ? GTK_CSS_SELECTOR_CATEGORY_SIMPLE : GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL, \
GTK_CSS_SELECTOR_CATEGORY_SIMPLE, \
gtk_css_selector_not_ ## n ## _print, \
gtk_css_selector_default_foreach_matcher, \
gtk_css_selector_not_ ## n ## _match_one, \

View File

@ -5,4 +5,4 @@ window.background:dir(ltr)
label.b:dir(ltr) class|name|hover|backdrop
label.c:dir(ltr) class|name|parent-name|parent-hover
label.d:dir(ltr) class|name|parent-name|parent-hover|parent-backdrop
label.e.f:dir(ltr)
label.e.f:dir(ltr) class|name|parent-name|parent-hover|parent-backdrop

View File

@ -0,0 +1 @@
.linked:not(.vertical) > button:dir(ltr):not(:last-child) { color: pink; }

View File

@ -0,0 +1,20 @@
window.background.solid-csd:dir(ltr)
decoration:dir(ltr)
headerbar.titlebar:dir(ltr)
box.horizontal.start:dir(ltr)
stackswitcher.linked:dir(ltr)
button.text-button.toggle:dir(ltr):checked
color: rgb(255,192,203); /* bloomfilter-not.css:1:61-73 */
label:dir(ltr)
button.text-button.toggle:dir(ltr)
color: rgb(255,192,203); /* bloomfilter-not.css:1:61-73 */
label:dir(ltr)
button.text-button.toggle:dir(ltr)
label:dir(ltr)
box.end.horizontal:dir(ltr)
stack:dir(ltr)
box.horizontal:dir(ltr)
box.horizontal:dir(ltr)
box.horizontal:dir(ltr)

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkApplicationWindow" id="window1">
<child type="titlebar">
<object class="GtkHeaderBar">
<child type="title">
<object class="GtkStackSwitcher" id="stack_switcher">
<property name="stack">toplevel_stack</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack" id="toplevel_stack">
<property name="transition-duration">1000</property>
<child>
<object class="GtkStackPage">
<property name="title" translatable="yes">Page 1</property>
<property name="child">
<object class="GtkBox" />
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="title" translatable="yes">Page 2</property>
<property name="child">
<object class="GtkBox" />
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="title" translatable="yes">Page 3</property>
<property name="child">
<object class="GtkBox" />
</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@ -30,6 +30,9 @@ test_data = [
'adjacent-states.css',
'adjacent-states.nodes',
'adjacent-states.ui',
'bloomfilter-not.css',
'bloomfilter-not.nodes',
'bloomfilter-not.ui',
'colornames.css',
'colornames.nodes',
'colornames.ui',