The `get_child_at_index()` API model comes from AT-SPI, and it's not an
efficient design, especially when coupled with large widgets.
Replace `get_child_at_index()` with `get_first_accessible_child()` and
`get_next_accessible_sibling()`.
That allows efficiently retrieving all the children, simplifies the
implementation of GtkAccessible in GtkWidget and closely resembeles the
GtkWidget API.
Getting the last child and previous sibling for iterating backwards is
not a part of the interface at the moment, but they can be added at a
later date.
Note that this change required tracking the next stack page in
GtkStackPage.
Use the fallback logic to generate the base path for the GtkAtSpiRoot
if the GApplication has no DBus object path to guarantee that
the base path will not stay NULL.
`gtk_at_spi_cache_add_context()` checks if the GtkAtSpiContext's path
is NULL before inserting the context object into the hash table.
Do the same in `gtk_at_spi_cache_remove_context()` to avoid a NULL
pointer dereference in `g_str_hash()` during the hash table lookup
if a context with NULL path is removed. That can happen when the
GtkAtSpiRoot::base_path is NULL, which, in turn, can happen if
`g_application_get_dbus_object_path()` returns NULL.
==394047==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7fd1966f8b84 bp 0x7fff11e3ded0 sp 0x7fff11e3de58 T0)
==394047==The signal is caused by a READ memory access.
==394047==Hint: address points to the zero page.
#0 0x7fd1966f8b84 in g_str_hash (/usr/lib/libglib-2.0.so.0+0x37b84)
#1 0x7fd1966f9c09 in g_hash_table_contains (/usr/lib/libglib-2.0.so.0+0x38c09)
#2 0x7fd196062c10 in gtk_at_spi_cache_remove_context ../gtk/a11y/gtkatspicache.c:447
#3 0x7fd19606e0a9 in gtk_at_spi_root_unregister ../gtk/a11y/gtkatspiroot.c:653
#4 0x7fd196067f58 in gtk_at_spi_context_unrealize ../gtk/a11y/gtkatspicontext.c:1559
#5 0x7fd195ced97f in gtk_at_context_unrealize ../gtk/gtkatcontext.c:668
#6 0x7fd195f5576e in gtk_widget_unroot_at_context ../gtk/gtkwidget.c:2399
#7 0x7fd195f55bd2 in gtk_widget_unroot ../gtk/gtkwidget.c:2499
...
We are caching the bus address as data on the display object when it
exists, but fail to set the data when the bus address doesn't exist.
That causing excessive calls to GetAddress when the accesssbility
bus doesn't exist. Make sure to cache a non-existent accessibility
bus by setting the "" string.
GTK depends on the a11y infrastructure to be in place unless GTK_A11Y is
set to none. It appears that despite that, users attempt to
get around the a11y requirement without setting GTK_A11Y.
This can cause, amongst other issues, performance problems
with gtk applications. Log failure to connect to the a11y
bus.
MinimumIncrement is an AT-SPI-ism that has no counterpart in the ARIA
specification, so it should not live inside public API. Additionally,
it's not really a useful method because it collapses two values on the
adjustment API.
The only method in the GtkAccessibleRange interface should be the
set_current_value(), which allows ATs to control the current position in
a ranged widget.
The AT-SPI implementation can now use all the accessible properties,
including the VALUE_TEXT one, mapped to the Text property on the
AtSpi.Value interface.
For some of the a11y states, calling gtk_accessible_reset_state
can change the type of the state value from boolean or tristate
to undefined.
Handle that, instead of throwing criticals.
Related: !4910
A typo resulted in the tab container widget being retrieved instead of
the tab widget. If an adjacent action widget was present, an infinite
loop occurred when switching tabs while a screen reader was enabled.
We need to free the queued context list in dispose
if we didn't get to register the contexts, and we also
need to free the list properly when we do get to
register them.
This showed up in valgrind as leaked GList structs.
The textbuffer test is calling into a function defined by the AT-SPI
accessibility backend. As of commit 4ddf1b70 we only build and run the
test on Linux, but the function in question isn't really
accessibility-related: it's just a serialization function.
If a context is not realized, calling gtk_at_spi_context_to_ref() will
return a null ref, because its path has not been initialized yet. This
was already done for all other cases in get_parent_context_ref(), but
was missing for the GtkStackPage case.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4944
The enum values are not compatible, and moreover, there is an extra
GTK_WRAP_NONE that PangoWrapMode doesn't have - thus,
pango_wrap_mode_to_string() will assert.
As far as I can tell, Orca does not read the wrap-mode key in the
dictionary for text attributes, anyway.
Fixes: #4869
The root accessible object is registered asynchronously, as it needs to
call a method on the AT-SPI registry daemon. This means we need to defer
registering the GtkAtSpiContext on the accessibility bus and in the
cache until after the registration is complete.
Fixes: #4825
We don't really need a bus-address property
that gets copied for every single object.
We keep the address in object data on the
display anyway. Just use it from there.
This gets rid of a nice amount of strdups
at startup.
Only send selection-changed events when we either
had a non-empty selection before, or have one now.
This should help orca speak the right things, and
not the wrong things.
Related: #3549
Orca relies on these to keep track of the focus location,
ignoring the focused state. With this change, orca can
once again speak text in entries as I type.
Orca ignores events unless the object is inside an object
with role window and states ACTIVE and SHOWING. To arrange
for this, introduce a new ACTIVE platform state, and set it
for windows when they are active.
This gets orca to be a lot more talkative.