Commit Graph

36 Commits

Author SHA1 Message Date
Emmanuele Bassi
e940704018 a11y: Ignore more structural roles when computing labels
These roles should not have a fallback name when explicitly unlabelled.
2020-11-12 21:46:05 +00:00
Emmanuele Bassi
9052f6dafe a11y: Rework ownership and lifetime of GtkATContext
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.
2020-11-11 19:45:43 +00:00
Emmanuele Bassi
04c4d293a7 a11y: Skip unlabelled structural roles
If a structural role is left unlabelled, just leave it unnamed.
2020-11-11 18:33:15 +00:00
Emmanuele Bassi
7ed06480cf a11y: Add private API to clone a GtkATContext
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.
2020-11-10 14:31:56 +00:00
Emmanuele Bassi
0af6630521 a11y: Consolidate accessibility environment variables
Use a single environment variable for everything:

 - select the ATContext implementation
 - select the test ATContext
 - disable ATContext entirely

We use the same pattern as GSK_RENDERER, GTK_DEBUG, etc.

The documentation needs to be updated to include the environment
variable.
2020-11-09 16:21:49 +00:00
Emmanuele Bassi
ae9758b964 a11y: Unrealize ATContext on dispose 2020-11-04 17:15:13 +00:00
Emmanuele Bassi
dafb2b0361 a11y: Allow updating role on unrealized contexts
We can still change the accessible role if an ATContext instance is
unrealized.
2020-11-04 15:22:31 +00:00
Emmanuele Bassi
30210c7087 a11y: Move ATContext to an explicit realization model
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.
2020-11-04 15:02:44 +00:00
Emmanuele Bassi
fbb08a30e2 a11y: Add child state change to GtkATContext
And the required private API in GtkAccessible to notify AT contexts of
changes in the children list.
2020-10-21 14:04:49 +01:00
Matthias Clasen
a8baee342c a11y: Fix handling of LABELLED_BY relation
There were several places where we were confusing
GList and GSList and list->data and list->next, causing
a crash in the accessible name computation for buttons
with mnemonic labels.
2020-10-20 21:27:39 -04:00
Emmanuele Bassi
51f5690ae3 Merge branch 'ebassi/for-master' into 'master'
Ebassi/for master

See merge request GNOME/gtk!2720
2020-10-19 20:26:57 +00:00
Matthias Clasen
dfc7d26275 a11y: Tweak name and description computation
Instead of falling back to the role nick for both,
fall back to the class name for the name, and to
the empty string for the description. This makes
labels show up in Accerciser the same way they
did in GTK 3, and seems more useful to me than
the alternative.
2020-10-19 14:58:34 -04:00
Emmanuele Bassi
7c7dabae8c a11y: Rework accessible name/description computation
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).
2020-10-19 17:54:14 +01:00
Matthias Clasen
d50ebd947c a11y: Add bounds change api
Add a way for GTK to pass bounds change information
to the AT context.
2020-10-19 12:19:55 -04:00
Matthias Clasen
3ad03b1706 a11y: Add a separate vfunc for platform changes
The state_change vfunc is becoming unwieldy. Lets move
the platform changes to their own vfunc, as a start.
2020-10-19 12:09:08 -04:00
Matthias Clasen
caeea0e368 Remove excessively spammy debug messages
Non need to announce the same things for every context
we create, and the path is not really that interesting.
without knowing what it belongs to. I would suggest to
make it visible in the inspector instead, so you can
look it up for the widgets you are interested in.
2020-10-13 17:24:06 -04:00
Matthias Clasen
b5ee73d299 a11y: Pass on platform changes
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.
2020-10-12 15:10:40 -04:00
Matthias Clasen
824ab7e4ed atcontext: labelled-by has a reference list
This is unclear - our docs state that all the
relations have value type reference, but in fact
they all have value type reference list.
2020-10-12 15:10:40 -04:00
Emmanuele Bassi
21482e8264 a11y: Compute the label for a GtkATContext
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
2020-10-12 16:19:32 +01:00
Emmanuele Bassi
8c18480092 a11y: Add a display to GtkATContext
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.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi
8f19bb0832 a11y: Add dummy AT-SPI context
Does not do anything, at the moment, but it's going to get filled out
soon.

The backend is selected depending on the platform being compiled in;
since we're using AT-SPI on X11 and Wayland, and we don't have other
accessibility implementations, we currently don't care about run time
selection, but we're going to have to deal with that.
2020-10-12 16:19:31 +01:00
Emmanuele Bassi
d58136e23d a11y: Simplify the ATContext::state-change signal
We cannot pass all the data we pass to the virtual function, because the
types are private, but the class and the signal are public API.

The signal is just a notification, so we can decouple the virtual
function (which stays the same, for internal types that implement the
ATContext API contract) from the signal.
2020-08-25 16:36:08 +01:00
Emmanuele Bassi
797b3bd1b1 a11y: Do not notify of empty state changes
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.
2020-08-25 16:36:08 +01:00
Emmanuele Bassi
1338dcddcb a11y: GtkATContext.update_state() was renamed to update() 2020-08-25 16:36:08 +01:00
Matthias Clasen
f561000124 docs: Clean up many dangling links
In many cases, these were references to no longer
existing api, so some rewording was necessary.
2020-08-04 22:11:34 -04:00
Rico Tzschichholz
f02a17805e a11y: Fix typo in GtkATContext::state-changed docs 2020-07-30 09:06:49 +02:00
Matthias Clasen
07bf9045fb a11y: Document GtkATContext::state-changed 2020-07-28 22:40:10 -04:00
Matthias Clasen
ecc329fa2a a11y: Add change notification to GtkATContext
Emit a ::state-change signal when state changes;
this was already a vfunc, but we want to listen
to state changes from the inspector too.
2020-07-28 08:41:24 -04:00
Emmanuele Bassi
4060febd7f a11y: Make GtkATContext.create() public
Implementations of the GtkAccessible interface should have a way to
instantiate the appropriate GtkATContext.
2020-07-27 11:48:11 +01:00
Emmanuele Bassi
b9a1cb74a1 a11y: Add API to retrieve accessible values
We are going to use this for implementing ATContext subclasses, but also
in the testing API.
2020-07-26 20:49:08 +01:00
Emmanuele Bassi
03b773f45a a11y: Change default accessible role
Only GtkWidget should use GTK_ACCESSIBLE_ROLE_WIDGET as its default
accessible role; the default for GtkAccessible and GtkATContext should
be GTK_ACCESSIBLE_ROLE_NONE, meaning "an element whose implicit native
role semantics will not be mapped to the accessibility API", according
to the WAI-ARIA specification.
2020-07-26 20:31:15 +01:00
Emmanuele Bassi
0d87f8cd62 a11y: Add testing API
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
2020-07-26 20:31:15 +01:00
Emmanuele Bassi
732578eb53 a11y: Consolidate the attributes container
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.
2020-07-26 20:31:15 +01:00
Emmanuele Bassi
1124f2507d a11y: Add relations API
Since we split relation attributes from the generic properties, we need
to add API for setting and retrieving their values.
2020-07-26 20:31:15 +01:00
Emmanuele Bassi
da1ce01a6f Add accessible properties to GtkAccessible
We propagate the accessible state and properties to each ATContext in
the same virtual function, since they are functionally similar.
2020-07-26 20:31:15 +01:00
Emmanuele Bassi
a382dfd3bd Add GtkATContext
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.
2020-07-26 20:31:14 +01:00