Add GtkWidget API for adding and removing style classes, as well as
checking whether a widget has a style class applied.
Everyone has to go through GtkStyleContext for this these days but with
GtkStyleContext eventually going away, it makse sense for GtkWidget to
have API for this.
Instead of foreaching through all the previous selectors every time we
bloom-filter, just bloom-filter the current element and return a special
value if that filter fails (FALSE). If that happens, don't try
filter-matching more nodes in the caller as we know it's an abort.
We have so many properties that it is basically impossible that all of
them are set and the time spent checking is higher than the time saved
if it does indeed happen.
This was a good idea back in GTK3 when popovers were toplevels, but now
they're regular child widgets, so they should behave that way.
Also, with the introduction of the bloom filter, gtk_css_node_validate()
now assumes it's only called on root nodes, so assert that that is the
case.
Instead of a foreach() function, introduce an iterator, so that the
caller can drive the iteration.
This allows doing stuff inbetween callbacks and avoids closures when
more than one data object should be passed.
As a side effect I even get a small, but noticeable performance
improvement in the 2-10% range depending on benchmark, I guess that's
because there's no function pointer passing going on anymore.
The FileChooser ToolKit (fctk) had its own machinery to handle default
sizes which was completely busted and trying to marshal random numbers
through the widget hierarchy that maybe made sense in 2012 but don't do
now.
Get rid of it, just keep the dialog's GSetting - which funnily enough
used to be written by the dialog but written by the widget.
But that's fctk for you.
Instead of just doing radical change matching on the node itself, also
consider the parent nodes via the bloom filter.
This means a radical change is now also one where the parent
name/id/classes change, but since that's considered a radical change on
the parent already, those things are slow anyway.
Improves the benchmark times for CSS validation during backdrop
transitions in widget-factory from 45ms to 35ms on my machine.
: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.
Add a fast path for parent selector matching that uses a bloom filter to
quickly discard selectors that can't possibly match.
Keep in mind that we match using a bloom filter, so we might
accidentally include too many selectors when hash/bucket collisions
occur.
That's not a correctness problem though, because we'll do a real check
afterwards.
The idea for this change is taken from browsers, in particular WebKit.
The reason for this is simply that I want to get hash functions that
have their values close together, so they can fit in a smaller range
(the goal here is 12 bits). By using GQuark, we get consecutive numbers
starting with 1 (and applications have <1000 quarks usually), whereas
interned strings can be all over the place.
As a side effect we also save 64 bytes per declaration.
The function was not selector-specific, so putting it with all the other
utility functions makes more sense.
Also use the utility function in the node declaration printing.
This is not meant to be a full GtkCalendar conversion to use widgets
instead of custom drawing, but we lost the arrows in the calendar header
when builtin icons were removed. Using proper button for the year/month
buttons brings them back.
Use the new gtk_css_dimension_value_is_zero() to check if we really need
to e.g. apply a border radius at all.
We compute css boxes a lot so this makes sense here, it especially shows
up during pick(), where we need the border box.