Now that GtkATContext is explicitly realized and unrealized, we should
always create an instance at widget initialization time, and drop it
during the widget finalization. This should make it easier to set up the
initial accessible state of a widget during the instance initialization,
as well as reduce the chances of accidental creation of GtkATContext
instances during the destruction sequence.
Some widgets might want to override GtkAccessible and create their own
context in order to control the accessible role post-construction time.
To avoid explicitly copying the existing state over from the original
ATContext to the new one, we need a way to clone the context's state
from inside the ATContext itself.
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.
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).
As a companion to go with the platform_change api,
add a gtk_accessible_get_platform_state() function
that can be used by backends to get the platform
state.
This is in preparation for making entries inherit
their focus states from the text widget within.
Add an enum for 'platform changes' to the at context
change notification mechanism. This will let us pass
along things that ARIA considers 'platform state' such
as focus or editability. The difference between the
platform state and other ARIA states is that we don't
keep the platform state separately in the at context
- backends are expected to just query the widgets.
This is just about avoiding notify listeners for
change notification.
The ARIA spec defines the mechanism for determining the name of an
accessible element—see §4.3 of the WAI-ARIA spec.
We follow the specification as much as it makes sense for GTK to do
so:
1. if the element is hidden, return an empty string
1. if the element has a labelled-by relation set, retrieve the
label of the related element
2. if the element has a label property set, use the value of
the property
3. if neither labelled-by nor label attributes are set, we use
the role to compute the name:
- for a `range` role, we return the contents of the value of
the `value-text` or `value-now` properties
- for any other role, we return a textual representation of
the GtkAccessibleRole enumeration value
Since we need to check at run time what kind of AT context to use, we
need a hook into the whole GDK backend machinery. The display connection
seems to be the best choice, in this case, as it allows us to determine
whether we're running on an X11 or Wayland system, and thus whether we
should create a GtkAtSpiContext.
This requires some surgery to fix the GtkATContext creation function, in
order to include a GdkDisplay instance.
If the ATContext state hasn't changed—for instance, if the accessible
attributes have been set to their default value, or have been set to the
same value—do not emit an accessible state change. State changes can be
arbitrarily expensive, so we want to ensure that they are meaningful.
We want to test the accessibility API, as well as the implementation
inside each widget. For that, we should expose an API that lets us
verify that a GtkAccessible has a given role, as well as a given
property.
The API follows the pattern of other GTest API:
- a macro to assert that a condition is respected
- a function that prints out the error message in case of failure
While we have split the various attributes for convenience, there's no
reason why we should have specialised data types for the attributes
container object.
Drop roles and properties that were deprecated in WAI-ARIA 1.1, and add
new roles and properties defined in WAI-ARIA 1.2 and later.
We also split the relationship properties into their own enumeration, so
we can keep the GtkAccessibleProperty type more compact.
The ATContext type is meant to be used as the base class for
implementations of the assistive technology API—the actual mechanism
needed to communicate to components like the screen reader, or any other
AT.
Every time the widget state changes, the ATContext is meant to broadcast
the state change; and every time the AT queries the state of a UI
element, the ATContext is meant to provide that information.
We also have a "test" ATContext implementation, which is meant to be
used to write tests to verify that changes are propagated without
requiring a whole desktop session.