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.
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.
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
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 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.
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.
The accessibility bus might not be available, and if it isn't the case,
it means something has failed at a level where the user can't do much
about it. There's no need to emit a critical warning.
The AT-SPI cache interface is used to quickly populate the accessible
objects tree.
The tricky bit is ensuring that we emit change notifications on the
cache only when the cache is available, which means waiting until the
root is asynchronously registered.
The root path is shared by all AtSpiContext instances, so we should
compute it once, instead of every time we instantiate a new context.
This allows us to defer the path creation at realization time and ensure
that we have a registered application.
There's no need to do a lot of work on construction, if we're delaying
all remote work after the GtkATContext is realized.
The GtkAtSpiContext should also keep a reference on the root, and drop
it at unrealize time.
We are doing too much work during the construction phase of the
AT-SPI backend for GtkATContext. Instead of having the AtSpiContext
register itself at construction time, let's add explicit realize
and unrealize operations, and connect the ATContext realization to the
rooting operation of a GtkWidget.
Instead of monitoring the list of toplevels, rely
on GtkWindow updating the HIDDEN state before windows
get removed. This is better, since we still have the
object available when it happens, so we can pass it
to the ATs.
When a toplevel window gets hidden (and not destroyed),
the frontend code set the HIDDEN state, and we need to
emit child notification when that happens.
We need to use gtk_accessible_should_present() whenever we
calculate accessible tree positions, to avoid inconsistencies.
While we are at it, make these helpers usable for finding
the position of accesibles that are now ignored, by not
looking at should_present for the object itself. This will
be relevant when we calculate the position of objects whose
HIDDEN state changes.
Hidden elements are not presented in the accessible
tree, so when then HIDDEN state changes, we should
emit child-added or -removed signals.
This commit does not yet handle all cases (HIDDEN
toplevels or hidden stack pages are not handled),
but it should cover the common case.