Set the accessible role for GtkLinkButton to button.
We don't use the 'link' role since ARIA says "if it
behaves like a button, use 'button'".
Update docs and add a test.
This changes should not be neccessary, since
GtkLinkButton derives from GtkButton, see #2965.
It's not a portable API, so remove it. The corresponding backend
specific functions are still available, if they were implemented, e.g.
gdk_macos_monitor_get_workarea() and gdk_x11_monitor_get_workarea().
Make GdkEvents hold a single GdkDevice. This device is closer to
the logical device conceptually, although it must be sufficient for
device checks (i.e. GdkInputSource), which makes it similar to the
physical devices.
Make the logical devices have a more accurate GdkInputSource where
needed, and conflate the event devices altogether.
Use the label accessible role for GtkLabel. ARIA has some
ominous wording about it going way, but while we have it,
GtkLabel is the obvious candidate for carrying it.
Update the documentation and add a test.
Sysprof has moved to a new ABI which removes GLib from the capture library
so that GLib itself can link against sysprof-capture.
This bumps the library ABI so we can keep things coordinated between all
the new tracing layers in the stack.
We don't pay attention to item-type anymore, so
drop the item-type property and the _for_item_type()
constructor, and allow passing NULL to the regular
constructor.
We don't make this constructor transfer-full, since
the selection filter model is not a wrapping model
like the others. It is more like fork than a wrap.
This is for consistency with other wrapping list constructors.
We want them all to be transfer full, allow-none.
Also make the constructor return GtkMultiSelection *.
Update all callers.
Make gtk_tree_list_model_new() take the root model
as first argument, and make it transfer full, for
consistency with other wrapping list constructors.
Update all callers.
Still missing here: Make the model property writable,
and allow passing NULL in the constructor.
Some widgets have different roles after they are constructed, so we need
to allow changing the role defined by the class. We should still avoid
setting a role after the GtkATContext has been created.
To build a better world sometimes means having to tear the old one down.
-- Alexander Pierce, "Captain America: The Winter Soldier"
ATK served us well for nearly 20 years, but the world has changed, and
GTK has changed with it. Now ATK is mostly a hindrance towards improving
the accessibility stack:
- it maps to a very specific implementation, AT-SPI, which is Linux and
Unix specific
- it requires implementing the same functionality in three different
layers of the stack: AT-SPI, ATK, and GTK
- only GTK uses it; every other Linux and Unix toolkit and application
talks to AT-SPI directly, including assistive technologies
Sadly, we cannot incrementally port GTK to a new accessibility stack;
since ATK insulates us entirely from the underlying implementation, we
cannot replace it piecemeal. Instead, we're going to remove everything
and then incrementally build on a clean slate:
- add an "accessible" interface, implemented by GTK objects directly,
which describe the accessible role and state changes for every UI
element
- add an "assistive technology context" to proxy a native accessibility
API, and assign it to every widget
- implement the AT context depending on the platform
For more information, see: https://gitlab.gnome.org/GNOME/gtk/-/issues/2833
We are using floats for rgb, and we don't need more precision
for hsl colors either. We use hsl for computing color expressions
like shade(), lighter() and darker(), which are not precisely
specified anyway.
This commit updates the one test where the output changes a
tiny bit due to this.
Instead of one item keeping the item + its position and sorting that
list, keep the items in 1 array and put the positions into a 2nd array.
This is generally slower while sorting, but allows multiple improvements:
1. We can replace items with keys
This allows avoiding multiple slow lookups when using complex
comparisons
2. We can keep multiple position arrays
This allows doing a sorting in the background without actually
emitting items-changed() until the array is completely sorted.
3. The main list tracks the items in the original model
So only a single memmove() is necessary there, while the old version
had to upgrade the position in every item.
Benchmarks:
sorting a model of simple strings
old new
256,000 items 256ms 268ms
512,000 items 569ms 638ms
sorting a model of file trees, directories first, by size
old new
64,000 items 350ms 364ms
128,000 items 667ms 691ms
removing half the model
old new
512,000 items 24ms 15ms
1,024,000 items 49ms 25ms
This was preventing any sort of building on macOS, even though the quartz
backend is currently non-functional. Fixing this is a pre-requisite to
getting a new macOS backend compiling.
This is a scary idea where you #define a bunch of preprocessor values
and then #include "gdkarrayimpl.c" and end up with a dynamic array for
that data type.
See https://en.wikipedia.org/wiki/X_Macro for what's going on.
What are the advantages over using GArray or GPtrArray?
* It's typesafe
Because it works like C++ templates, we can use the actual type of
the object instead of having to use gpointer.
* It's one less indirection
instead of 2 indirections via self->array->data, this array is
embedded, so self->array is the actual data, and just one indirection
away. This is pretty irrelevant in general, but can be very noticable
in tight loops.
* It's all inline
Because the whole API is defined as static inline functions, the
compiler has full access to everything and can (and does) optimize
out unnecessary calls, thereby speeding up some operations quite
significantly, when full optimizations are enabled.
* It has more features
In particular preallocation allows for avoiding malloc() calls, which
can again speed up tight loops a lot.
But there's also splice(), which is very useful when used with
listmodels.
Instead of an array of arrays, let's use an array of dictionaries; it's
easier to add optional keys without requiring to remember where to put
empty arrays.
char ** arrays are null-terminated everywhere, so make sure they are in
splice(), too.
Also fix the argument to be a const char * const * like in the
constructor.
Simplify all view model APIs and always return G_TYPE_OBJECT as the
item-type for every model.
It turns out nobody uses item-type anyway.
So instead of adding lots of APIs, forcing people to think about it and
trying to figure out how to handle filter or map models that modify item
types, just having an easy life is a better approach.
All the models need to be able to deal with any type of object going
through anyway.
Verify that the selection filter changes mirror
the selection changes of the underlying model,
as expected. These tests verify the fixes in
the previous commit.
One of the widget-factory focus tests is flaky in ci,
perhaps due to font changes causing size computations
to go slightly differently.
Drop this for now.
Always keep the order:
- [value]
- [marks.top]
- [marks.bottom]
- trough
Which makes sense given the rendering order. Slider should be drawn
after the marks.
Makes it possible to simply remove the custom snapshot implementations
in scale and range. And Adwaita does not depend on the node order
anyway.
In particular, track which items remain in ::items-changed
signal emissions.
But the main use case is sorting, which causes items-changed(0, n, n)
to be emitted.
In 99.9% of all cases, these are just NULL, NULL.
So just do away with these arguments, people can
use the setters for the rare cases where they want
the scrolled window to use a different adjustment.
This is a list model holding strings, initialized
from a char **. String lists are buildable as well,
and that replaces the buildable support in GktDropDowns.
This is not just about consistency with other functions.
It is about avoiding reentrancy problems.
GtkListBase first doing an unselect_all() will then force the
SelectionModel to consider a state where all items are unselected
(and potentially deciding to autoselect one) and then cause a
"selection-changed" emission that unselects all items and potentially
updates all the list item widgets in the GtkListBase to the unselected
state.
After this, GtkListBase selects new items, but to the SelectionModel and
the list item widgets this looks like an enitrely new operation and
there is no way to associate it with the previous state, so the
SelectionModel cannot undo any previous actions it took when
unselecting.
And all listitem widgets will now think they were just selected and
start running animations about selecting.
This is a selection model that stores the selection
state in a boolean property of the items, and thus
persists across reordering and similar changes.
Fixes: #2826
The tooltip handling in GtkWidget is "special":
- the string is stored inside the qdata instead of the private
instance data
- the accessors call g_object_set() and g_object_get(), and the
logic is all inside the property implementation, instead of
being the other way around
- the getters return a copy of the string
- the setters don't really notify all the involved properties
The GtkWidgetAccessible uses the (escaped) tooltip text as a source for
the accessible object description, which means it has to store the
tooltip inside the object qdata, and update its copy at construction and
property notification time.
We can simplify this whole circus by making the tooltip properties (text
and markup) more idiomatic:
- notify all side-effect properties
- return a constant string from the getter
- if tooltip-text is set:
- store the text as is
- escape the markup and store it separately for the markup getter
- if tooltip-markup is set:
- store the markup as is
- parse the markup and store it separately for the text getter
The part of the testtooltips interactive test that checks that the
getters are doing the right thing is now part of the gtk testsuite, so
we ensure we don't regress in behaviour.
When exclusive is TRUE, we would not always emit a
::selection-changed signal that covers all the items
that were unselected.
This commit includes a test.
This was done in a weird way where we always call reftest_uninhibit_snapshot()
on paint, and then re-inhibited it if it wasn't inhibited. To make this
work it also started with an extra inhibit.
This is very contorted and based on how this historically worked. This
changes it to just do:
if (inhibit_count > 0)
return;
And keep inhibit_count at its initial zero value unless it is actually
inhibited.
In https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/2027 i was getting
Bail out! ERROR:../testsuite/reftests/reftest-snapshot.c:212:reftest_uninhibit_snapshot: assertion failed: (inhibit_count > 0)
In (for example the box-shadow-changes-modify-clip reftest. I can reproduce this (on master) with:
```
$ xvfb-run -a -s "-screen 0 1024x768x24" meson test --suite gtk:reftest "reftest box-shadow-changes-modify-clip.ui"
...
1/1 gtk:reftest / reftest box-shadow-changes-modify-clip.ui ERROR 0.77s
``
Fix this by re-inhibiting if we didn't draw anything, or we will get an assert the next paint.
We're printing out the file we're testing once we succeed, but it's hard
to know which file caused a failure. Let's add a g_test_message()
directive so we can look in our logs.
This is a somewhat large commit that:
- Adds GtkColumnViewSorter
This is a special-purpose, private sorter implementation which sorts
according to multiple sorters, allowing each individual sorter to be
inverted. This will be used with clickable column view headers.
- Adds a read-only GtkColumnView::sorter property
The GtkColumnView creates a GtkColumnViewSorter at startup that it uses
for this property.
- Adds a writable GtkColumnViewColumn::sorter property
This allows defining per-column sorters. Whenever an application sets a
sorter for a column, the header becomes clickable and whenever
a header is clicked, that column's sorter is prepended to the list of
sorters, unless it is already the first sorter, in which case we invert
its order. No column can be in the list more than once.