- GTK Accessibility
- GtkAccessible — Accessible interface
- GtkATContext — An object communicating to Assistive Technologies
The GtkAccessible interface provides the accessibility information about an application’s user interface elements. Assistive technology (AT) applications, like Orca, convey this information to users with disabilities, or reduced abilities, to help them use the application.
Standard GTK controls implement the GtkAccessible interface and are thus accessible to ATs by default. This means that if you use GTK controls such as GtkButton, GtkEntry, or GtkListView, you only need to supply application-specific details when the defaults values are incomplete. You can do this by setting the appropriate properties in your GtkBuilder template and UI definition files, or by setting the properties defined by the GtkAccessible interface.
If you are implementing your own GtkWidget derived type, you will need to set the GtkAccessible properties yourself, and provide an implementation of the GtkAccessible virtual functions.
The fundamental concepts of an accessible widget are roles and attributes; each GTK control has a role, while its functionality is described by a set of attributes.
Roles define the taxonomy and semantics of a UI control to any
assistive technology application; for instance, a button will
have a role of GTK_ACCESSIBLE_ROLE_BUTTON
; an
entry will have a role of
GTK_ACCESSIBLE_ROLE_TEXTBOX
; a toggle button
will have a role of
GTK_ACCESSIBLE_ROLE_CHECKBOX
; etc.
Each role is part of the widget’s instance, and cannot be changed over time or as the result of a user action. Roles allows assistive technology applications to identify a UI control and decide how to present it to a user; if a part of the application’s UI changes role, the control needs to be removed and replaced with another one with the appropriate role.
Each role name is part of the GtkAccessibleRole enumeration.
Role name | Description | Related GTK widget |
---|---|---|
BUTTON
|
A control that performs an action when pressed | GtkButton, GtkLinkButton, GtkExpander |
CHECKBOX
|
A control that has three possible value:
true , false , or
undefined
|
GtkCheckButton |
COMBOBOX
|
A control that can be expanded to show a list of possible values to select | GtkComboBox |
COLUMN_HEADER
|
A header in a columned list | GtkColumnView |
DIALOG
|
A dialog that prompts the user to enter information or require a response | GtkDialog and subclasses |
GRID
|
A grid of items | GtkFlowBox, GtkGridView |
GRID_CELL
|
An item in a grid | GtkFlowBoxChild, GtkGridView, GtkColumnView |
IMG
|
An image | GtkImage, GtkPicture |
LABEL
|
A visible name or caption for a user interface component | GtkLabel |
LINK
|
A clickable hyperlink | GtkLinkButton |
LIST
|
A list of items | GtkListBox |
LIST_ITEM
|
An item in a list | GtkListBoxRow |
MENU
|
A menu | GtkPopoverMenu |
MENU_BAR
|
A menubar | GtkPopoverMenuBar |
MENU_ITEM
|
A menu item | Items in GtkPopoverMenu |
MENU_ITEM_CHECKBOX
|
Check menu item | Items in GtkPopoverMenu |
MENU_ITEM_RADIO
|
Radio menu item | Items in GtkPopoverMenu |
METER
|
Represents a value within a known range | GtkLevelBar |
NONE
|
Not represented in the accessibility tree | the slider of a GtkScale |
PROGRESS_BAR
|
An element that display progress | GtkProgressBar |
RADIO
|
A checkable input in a group of radio roles | GtkCheckButton |
ROW
|
A row in a columned list | GtkColumnView |
SCROLLBAR
|
A graphical object controlling the scrolling of content | GtkScrollbar |
SEARCH_BOX
|
A text box for entering search criteria | GtkSearchEntry |
SEPARATOR
|
A divider that separates sections of content or groups of items | GtkSeparator |
SPIN_BUTTON
|
A range control that allows seelcting among discrete choices | GtkSpinButton |
SWITCH
|
A control that represents on/off values | GtkSwitch |
TAB
|
A tab in a list of tabs for switching pages | GtkStackSwitcher, GtkNotebook |
TAB_LIST
|
A list of tabs for switching pages | GtkStackSwitcher, GtkNotebook |
TAB_PANEL
|
A page in a notebook or stack | GtkStack |
TEXT_BOX
|
A type of input that allows free-form text as its value. | GtkEntry, GtkPasswordEntry, GtkTextView |
TREE_GRID
|
A treeview-like columned list | GtkColumnView |
WINDOW
|
An application window | GtkWindow |
...
|
… |
See the WAI-ARIA list of roles for additional information.
Attributes provide specific information about an accessible UI control, and describe it for the assistive technology applications. GTK divides the accessible attributes into three categories:
properties, described by the values of the GtkAccessibleProperty enumeration
relations, described by the values of the GtkAccessibleRelation enumeration
states, described by the values of the GtkAccessibleState enumeration
Each attribute accepts a value of a specific type.
Unlike roles, attributes may change over time, or in response to user action; for instance:
a toggle button will change its
GTK_ACCESSIBLE_STATE_CHECKED
state every time it is toggled, either by the user or programmaticallysetting the mnemonic widget on a GtkLabel will update the
GTK_ACCESSIBLE_RELATION_LABELLED_BY
relation on the widget with a reference to the labelchanging the GtkAdjustment instance on a GtkScrollbar will change the
GTK_ACCESSIBLE_PROPERTY_VALUE_MAX
,GTK_ACCESSIBLE_PROPERTY_VALUE_MIN
, andGTK_ACCESSIBLE_PROPERTY_VALUE_NOW
properties with the upper, lower, and value properties of the GtkAdjustment
See the WAI-ARIA list of attributes for additional information.
Each state name is part of the GtkAccessibleState enumeration.
State name | ARIA attribute | Value type | Notes |
---|---|---|---|
GTK_ACCESSIBLE_STATE_BUSY
|
“aria-busy” | boolean | |
GTK_ACCESSIBLE_STATE_CHECKED
|
“aria-checked” | GtkAccessibleTristate | Indicates the current state of a GtkCheckButton |
GTK_ACCESSIBLE_STATE_DISABLED
|
“aria-disabled” | boolean | Corresponds to the “sensitive” property on GtkWidget |
GTK_ACCESSIBLE_STATE_EXPANDED
|
“aria-expanded” | boolean or undefined | Corresponds to the “expanded” property on GtkExpander |
GTK_ACCESSIBLE_STATE_HIDDEN
|
“aria-hidden” | boolean | Corresponds to the “visible” property on GtkWidget |
GTK_ACCESSIBLE_STATE_INVALID
|
“aria-invalid” | GtkAccessibleInvalidState | Set when a widget is showing an error |
GTK_ACCESSIBLE_STATE_PRESSED
|
“aria-pressed” | GtkAccessibleTristate | Indicates the current state of a GtkToggleButton |
GTK_ACCESSIBLE_STATE_SELECTED
|
“aria-selected” | boolean or undefined | Set when a widget is selected |
Each property name is part of the GtkAccessibleProperty enumeration.
Each relation name is part of the GtkAccessibleRelation enumeration.
Note: When using
gtk_accessible_update_relation()
with a relation that requires
a list of GtkAccessible instances, you should pass every
accessible object separately, followed by NULL
.
Even if standard UI controls provided by GTK have accessibility information out of the box, there are some additional properties and considerations for application developers. For instance, if your application presents the user with a form to fill out, you should ensure that:
the container of the form has a
GTK_ACCESSIBLE_ROLE_FORM
roleeach text entry widget in the form has the
GTK_ACCESSIBLE_RELATION_LABELLED_BY
relation pointing to the label widget that describes it
Another example: if you create a toolbar containing buttons with only icons, you should ensure that:
the container has a
GTK_ACCESSIBLE_ROLE_TOOLBAR
roleeach button has a
GTK_ACCESSIBLE_PROPERTY_LABEL
property set with the user readable and localised action performed when pressed; for instance “Copy”, “Paste”, “Add layer”, or “Remove”
GTK will try to fill in some information by using ancillary UI
control properties, for instance the accessible label will be
taken from the label or placeholder text used by the UI control,
or from its tooltip, if the
GTK_ACCESSIBLE_PROPERTY_LABEL
property or the
GTK_ACCESSIBLE_RELATION_LABELLED_BY
relation
are unset. Nevertheless, it is good practice and project hygiene
to explicitly specify the accessible properties, just like it’s
good practice to specify tooltips and style classes.
Application developers using GTK
should ensure that their UI
controls are accessible as part of the development process. When
using GtkBuilder
templates and UI definition
files, GTK provides a validation tool that verifies that each UI
element has a valid role and properties; this tool can be used as
part of the application’s test suite to avoid regressions.
Each UI control implements the GtkAccessible interface to allow widget and application developers to specify the roles, state, and relations between UI controls. This API is purely descriptive.
Each GtkAccessible
implementation must provide
a GtkATContext instance, which acts as a proxy to the specific
platform’s accessibility API:
AT-SPI on Linux/BSD
NSAccessibility on macOS
Active Accessibility on Windows
Additionally, an ad hoc accessibility backend is available for the GTK testsuite, to ensure reproducibility of issues in the CI pipeline.
The authoring practices are aimed at application developers, as well as developers of GUI elements based on GTK.
Functionally, GtkAccessible roles, states, properties, and relations are analogous to a CSS for assistive technologies. For screen reader users, for instance, the various accessible attributes control the rendering of their non-visual experience. Incorrect roles and attributes may result in a completely inaccessible user interface.
The following code:
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_BUTTON);
is a promise that the widget being created will provide the same
keyboard interactions expected for a button. An accessible role
of a button will not turn automatically any widget into a
GtkButton; but if your widget behaves like a button, using the
GTK_ACCESSIBLE_ROLE_BUTTON
will allow any assistive technology
to handle it like they would a GtkButton.
Accessible attributes can be used to override the content of a UI element, for instance:
gtk_label_set_text (GTK_LABEL (label), "Some text"); gtk_accessible_update_property (GTK_ACCESSIBLE (label), GTK_ACCESSIBLE_PROPERTY_LABEL, "Assistive technologies users will perceive " "this text, not the contents of the label", -1);
In the example above, the “label” property will override the contents of the label widget.
The attributes can also enhance the UI:
gtk_button_set_label (GTK_BUTTON (button), "Download"); gtk_box_append (GTK_BOX (button), button); gtk_label_set_text (GTK_LABEL (label), "Final report.pdf"); gtk_box_append (GTK_BOX (box), label); gtk_accessible_update_relation (GTK_ACCESSIBLE (button), GTK_ACCESSIBLE_RELATION_LABELLED_BY, g_list_append (NULL, label), -1);
In the example above, an assistive technology will read the button’s accessible label as “Download Final report.pdf”.
The power of hiding and enhancing can be a double-edged sword, as it can lead to inadvertently overriding the accessible semantics of existing widgets.
The accessibility API is mainly used to express semantics useful
for assistive technologies, but it can also be used to hide
elements. The canonical way to do so is to use the
GTK_ACCESSIBLE_ROLE_PRESENTATION
, which declares that a UI
element is purely meant for presentation purposes, and as such it
has no meaningful impact on the accessibility of the interface.
A “presentation” role should not be confused with the
GTK_ACCESSIBLE_STATE_HIDDEN
state; the “hidden”
state is transient, and is typically controlled by showing and
hiding a widget using the GtkWidget API.
When creating custom widgets, following established patterns can help ensuring that the widgets work well for users of accessible technologies as well.
A button is a widget that enables users to trigger an action. While it is recommended you use GtkButton for anything that looks and behaves like a button, it is possible to apply a button behavior to UI elements like images by using a GtkGestureClick gesture. When doing so, you should:
Give your widget the role
GTK_ACCESSIBLE_ROLE_BUTTON
Install an action with no parameters, which will activate the widget
For custom entries, it is highly recommended that you implement the GtkEditable interface by using a GtkText widget as delegate. If you do this, GTK will make your widgets text editing functionality accessible in the same way as a GtkSpinButton or GtkSearchEntry.
If you make a tab-based interface, you should consider using GtkStack as the core, and just make a custom tab widget to control the active stack page. When doing so, the following extra steps will ensure that your tabs are accessible in the same way as GtkStackSwitcher or GtkNotebook:
Give your tab container the role
GTK_ACCESSIBLE_ROLE_TAB_LIST
Give your tab widgets the role
GTK_ACCESSIBLE_ROLE_TAB
Set up the
GTK_ACCESSIBLE_RELATION_CONTROLS
relation between each tab and the GtkStackPage object for its pageSet the
GTK_ACCESSIBLE_PROPERTY_SELECTED
property on each tab, with the active tab getting the valueTRUE
, all othersFALSE
To allow changing the active tab via accessible technologies,
you can export actions. Since the accessibility interfaces only
support actions without parameters, you can either provide
previous-tab
and next-tab
actions on the tab container that let users step through the
tabs one-by-one, or add a activate-tab
action
on each tab.
A value control (ie a widget that controls a one-dimensional
quantity that can be represented by a GtkAdjustment) can be
represented to accessible technologies by setting the
GTK_ACCESSIBLE_PROPERTY_VALUE_MIN
,
GTK_ACCESSIBLE_PROPERTY_VALUE_MAX
, and
GTK_ACCESSIBLE_PROPERTY_VALUE_NOW
properties.
To allow changing the value via accessible technologies, you can
export actions. Since the accessibility interfaces only support
actions without parameters, you should provide actions such as
increase-value
and
decrease-value
.