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.
We need to translate the list model position into
an accessible tree position, since hidden toplevels
will be skipped.
While we are at it, add an api for this notification
that will be used in the next commit.
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.
GtkModelButton is no longer derived from GtkButton,
but can still treat it like a button for the purposes
of having a click action. This lets ATs activate
menu items again.
GtkAtSpiRoot is not a context, which means it needs to emit
ChildrenChanged events by itself whenever a toplevel is added to, or
removed from, the list of toplevels.
The stack page objects were not properly integrated
in the accessible tree - they were appearing as parent
of the pages when navigating up, but not as children
of the stack when navigating down.
The ARIA spec determines the name and description of accessible elements
in a more complex way that simply mapping to a single property; instead,
it will chain up multiple definitions (if it finds them). For instance,
let's assume we have a button that saves a file selected from a file
selection widget; the widgets have the following attributes:
- the file selection widget has a "label" attribute set to the
selected file, e.g. "Final paper.pdf"
- the "download" button has a "label" attribute set to the
"Download" string
- the "download" button has a "labelled-by" attribute set to
reference the file selection widget
The ARIA spec says that the accessible name of the "Download" button
should be computed as "Download Final paper.pdf".
The algorithm defined in section 4.3 of the WAI-ARIA specification
applies to both accessible names (using the "label" and "labelled-by"
attributes), and to accessible descriptions (using the "description" and
"described-by" attributes).
Our Text implementation requires that we have
a GtkEditable with a delegate that is a GtkText
widget.
This change make the Text implementation work for
the custom widget in the tagged entry demo.
Implement the non-questionable parts of the Component interface
for accessibles which are widgets.
This does not include:
- global coordinates
- setters
- scrolling
- alpha, layers, zorder, and the like
We only want to show relevant, local actions for
widgets, but _gtk_widget_get_action_muxer() will
return the muxer of a parent widget (all the way
up to the toplevel), if the widget does not have
any actions of its own. To detect this situation,
compare what _gtk_widget_get_action_muxer() returns
for the parent widget, and act accordingly.