<sect1 id="gtk-accessibility">
  <title>GTK Accessibility</title>
  <sect2>
    <title>The standard accessibility interface</title>
    <para>
      The <link linkend="GtkAccessible"><type>GtkAccessible</type></link> 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.
    </para>
    <para>
      Standard GTK controls implement the <link linkend="GtkAccessible"><type>GtkAccessible</type></link> interface and
      are thus accessible to ATs by default. This means that if you use
      GTK controls such as <link linkend="GtkButton"><type>GtkButton</type></link>, <link linkend="GtkEntry"><type>GtkEntry</type></link>, or <link linkend="GtkListView"><type>GtkListView</type></link>, 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 <link linkend="GtkBuilder"><type>GtkBuilder</type></link> template and UI definition files,
      or by setting the properties defined by the <link linkend="GtkAccessible"><type>GtkAccessible</type></link>
      interface.
    </para>
    <para>
      If you are implementing your own <link linkend="GtkWidget"><type>GtkWidget</type></link> derived type, you will
      need to set the <link linkend="GtkAccessible"><type>GtkAccessible</type></link> properties yourself, and provide an
      implementation of the <link linkend="GtkAccessible"><type>GtkAccessible</type></link> virtual functions.
    </para>
  </sect2>
  <sect2>
    <title>Accessible roles and attributes</title>
    <para>
      The fundamental concepts of an accessible widget are
      <emphasis>roles</emphasis> and <emphasis>attributes</emphasis>;
      each GTK control has a role, while its functionality is described
      by a set of <emphasis>attributes</emphasis>.
    </para>
    <sect3>
      <title>Roles</title>
      <para>
        Roles define the taxonomy and semantics of a UI control to any
        assistive technology application; for instance, a button will
        have a role of <literal>GTK_ACCESSIBLE_ROLE_BUTTON</literal>; an
        entry will have a role of
        <literal>GTK_ACCESSIBLE_ROLE_TEXTBOX</literal>; a toggle button
        will have a role of
        <literal>GTK_ACCESSIBLE_ROLE_CHECKBOX</literal>; etc.
      </para>
      <para>
        Each role is part of the widget’s instance, and
        <emphasis role="strong">cannot</emphasis> 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.
      </para>
      <sect4>
        <title>List of accessible roles</title>
        <para>
          Each role name is part of the <link linkend="GtkAccessibleRole"><type>GtkAccessibleRole</type></link> enumeration.
        </para>
        <informaltable>
          <tgroup cols="3">
            <colspec colwidth="25*" align="left" />
            <colspec colwidth="29*" align="left" />
            <colspec colwidth="45*" align="left" />
            <thead>
              <row>
                <entry>
                  Role name
                </entry>
                <entry>
                  Description
                </entry>
                <entry>
                  Related GTK widget
                </entry>
              </row>
            </thead>
            <tbody>
              <row>
                <entry>
                  <literal>BUTTON</literal>
                </entry>
                <entry>
                  A control that performs an action when pressed
                </entry>
                <entry>
                  <link linkend="GtkButton"><type>GtkButton</type></link>, <link linkend="GtkLinkButton"><type>GtkLinkButton</type></link>, <link linkend="GtkExpander"><type>GtkExpander</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>CHECKBOX</literal>
                </entry>
                <entry>
                  A control that has three possible value:
                  <literal>true</literal>, <literal>false</literal>, or
                  <literal>undefined</literal>
                </entry>
                <entry>
                  <link linkend="GtkCheckButton"><type>GtkCheckButton</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>COMBOBOX</literal>
                </entry>
                <entry>
                  A control that can be expanded to show a list of
                  possible values to select
                </entry>
                <entry>
                  <link linkend="GtkComboBox"><type>GtkComboBox</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>COLUMN_HEADER</literal>
                </entry>
                <entry>
                  A header in a columned list
                </entry>
                <entry>
                  <link linkend="GtkColumnView"><type>GtkColumnView</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>DIALOG</literal>
                </entry>
                <entry>
                  A dialog that prompts the user to enter information or
                  require a response
                </entry>
                <entry>
                  <link linkend="GtkDialog"><type>GtkDialog</type></link> and subclasses
                </entry>
              </row>
              <row>
                <entry>
                  <literal>GRID</literal>
                </entry>
                <entry>
                  A grid of items
                </entry>
                <entry>
                  <link linkend="GtkFlowBox"><type>GtkFlowBox</type></link>, <link linkend="GtkGridView"><type>GtkGridView</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>GRID_CELL</literal>
                </entry>
                <entry>
                  An item in a grid
                </entry>
                <entry>
                  <link linkend="GtkFlowBoxChild"><type>GtkFlowBoxChild</type></link>, <link linkend="GtkGridView"><type>GtkGridView</type></link>, <link linkend="GtkColumnView"><type>GtkColumnView</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>IMG</literal>
                </entry>
                <entry>
                  An image
                </entry>
                <entry>
                  <link linkend="GtkImage"><type>GtkImage</type></link>, <link linkend="GtkPicture"><type>GtkPicture</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>LABEL</literal>
                </entry>
                <entry>
                  A visible name or caption for a user interface
                  component
                </entry>
                <entry>
                  <link linkend="GtkLabel"><type>GtkLabel</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>LINK</literal>
                </entry>
                <entry>
                  A clickable hyperlink
                </entry>
                <entry>
                  <link linkend="GtkLinkButton"><type>GtkLinkButton</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>LIST</literal>
                </entry>
                <entry>
                  A list of items
                </entry>
                <entry>
                  <link linkend="GtkListBox"><type>GtkListBox</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>LIST_ITEM</literal>
                </entry>
                <entry>
                  An item in a list
                </entry>
                <entry>
                  <link linkend="GtkListBoxRow"><type>GtkListBoxRow</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>MENU</literal>
                </entry>
                <entry>
                  A menu
                </entry>
                <entry>
                  <link linkend="GtkPopoverMenu"><type>GtkPopoverMenu</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>MENU_BAR</literal>
                </entry>
                <entry>
                  A menubar
                </entry>
                <entry>
                  <link linkend="GtkPopoverMenuBar"><type>GtkPopoverMenuBar</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>MENU_ITEM</literal>
                </entry>
                <entry>
                  A menu item
                </entry>
                <entry>
                  Items in <link linkend="GtkPopoverMenu"><type>GtkPopoverMenu</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>MENU_ITEM_CHECKBOX</literal>
                </entry>
                <entry>
                  Check menu item
                </entry>
                <entry>
                  Items in <link linkend="GtkPopoverMenu"><type>GtkPopoverMenu</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>MENU_ITEM_RADIO</literal>
                </entry>
                <entry>
                  Radio menu item
                </entry>
                <entry>
                  Items in <link linkend="GtkPopoverMenu"><type>GtkPopoverMenu</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>METER</literal>
                </entry>
                <entry>
                  Represents a value within a known range
                </entry>
                <entry>
                  <link linkend="GtkLevelBar"><type>GtkLevelBar</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>NONE</literal>
                </entry>
                <entry>
                  Not represented in the accessibility tree
                </entry>
                <entry>
                  the slider of a <link linkend="GtkScale"><type>GtkScale</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>PROGRESS_BAR</literal>
                </entry>
                <entry>
                  An element that display progress
                </entry>
                <entry>
                  <link linkend="GtkProgressBar"><type>GtkProgressBar</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>RADIO</literal>
                </entry>
                <entry>
                  A checkable input in a group of radio roles
                </entry>
                <entry>
                  <link linkend="GtkCheckButton"><type>GtkCheckButton</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>ROW</literal>
                </entry>
                <entry>
                  A row in a columned list
                </entry>
                <entry>
                  <link linkend="GtkColumnView"><type>GtkColumnView</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>SCROLLBAR</literal>
                </entry>
                <entry>
                  A graphical object controlling the scrolling of
                  content
                </entry>
                <entry>
                  <link linkend="GtkScrollbar"><type>GtkScrollbar</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>SEARCH_BOX</literal>
                </entry>
                <entry>
                  A text box for entering search criteria
                </entry>
                <entry>
                  <link linkend="GtkSearchEntry"><type>GtkSearchEntry</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>SEPARATOR</literal>
                </entry>
                <entry>
                  A divider that separates sections of content or groups
                  of items
                </entry>
                <entry>
                  <link linkend="GtkSeparator"><type>GtkSeparator</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>SPIN_BUTTON</literal>
                </entry>
                <entry>
                  A range control that allows seelcting among discrete
                  choices
                </entry>
                <entry>
                  <link linkend="GtkSpinButton"><type>GtkSpinButton</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>SWITCH</literal>
                </entry>
                <entry>
                  A control that represents on/off values
                </entry>
                <entry>
                  <link linkend="GtkSwitch"><type>GtkSwitch</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>TAB</literal>
                </entry>
                <entry>
                  A tab in a list of tabs for switching pages
                </entry>
                <entry>
                  <link linkend="GtkStackSwitcher"><type>GtkStackSwitcher</type></link>, <link linkend="GtkNotebook"><type>GtkNotebook</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>TAB_LIST</literal>
                </entry>
                <entry>
                  A list of tabs for switching pages
                </entry>
                <entry>
                  <link linkend="GtkStackSwitcher"><type>GtkStackSwitcher</type></link>, <link linkend="GtkNotebook"><type>GtkNotebook</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>TAB_PANEL</literal>
                </entry>
                <entry>
                  A page in a notebook or stack
                </entry>
                <entry>
                  <link linkend="GtkStack"><type>GtkStack</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>TEXT_BOX</literal>
                </entry>
                <entry>
                  A type of input that allows free-form text as its
                  value.
                </entry>
                <entry>
                  <link linkend="GtkEntry"><type>GtkEntry</type></link>, <link linkend="GtkPasswordEntry"><type>GtkPasswordEntry</type></link>, <link linkend="GtkTextView"><type>GtkTextView</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>TREE_GRID</literal>
                </entry>
                <entry>
                  A treeview-like columned list
                </entry>
                <entry>
                  <link linkend="GtkColumnView"><type>GtkColumnView</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>WINDOW</literal>
                </entry>
                <entry>
                  An application window
                </entry>
                <entry>
                  <link linkend="GtkWindow"><type>GtkWindow</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <literal>...</literal>
                </entry>
                <entry>
                  …
                </entry>
                <entry>
                </entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        <para>
          See the
          <ulink url="https://www.w3.org/WAI/PF/aria/appendices#quickref">WAI-ARIA</ulink>
          list of roles for additional information.
        </para>
      </sect4>
    </sect3>
    <sect3>
      <title>Attributes</title>
      <para>
        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:
      </para>
      <itemizedlist spacing="compact">
        <listitem>
          <para>
            <emphasis>properties</emphasis>, described by the values of
            the <link linkend="GtkAccessibleProperty"><type>GtkAccessibleProperty</type></link> enumeration
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>relations</emphasis>, described by the values of
            the <link linkend="GtkAccessibleRelation"><type>GtkAccessibleRelation</type></link> enumeration
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>states</emphasis>, described by the values of the
            <link linkend="GtkAccessibleState"><type>GtkAccessibleState</type></link> enumeration
          </para>
        </listitem>
      </itemizedlist>
      <para>
        Each attribute accepts a value of a specific type.
      </para>
      <para>
        Unlike roles, attributes may change over time, or in response to
        user action; for instance:
      </para>
      <itemizedlist spacing="compact">
        <listitem>
          <para>
            a toggle button will change its
            <link linkend="GTK-ACCESSIBLE-STATE-CHECKED:CAPS"><literal>GTK_ACCESSIBLE_STATE_CHECKED</literal></link> state every time it is
            toggled, either by the user or programmatically
          </para>
        </listitem>
        <listitem>
          <para>
            setting the mnemonic widget on a <link linkend="GtkLabel"><type>GtkLabel</type></link> will update the
            <link linkend="GTK-ACCESSIBLE-RELATION-LABELLED-BY:CAPS"><literal>GTK_ACCESSIBLE_RELATION_LABELLED_BY</literal></link> relation on the widget
            with a reference to the label
          </para>
        </listitem>
        <listitem>
          <para>
            changing the <link linkend="GtkAdjustment"><type>GtkAdjustment</type></link> instance on a <link linkend="GtkScrollbar"><type>GtkScrollbar</type></link> will
            change the <link linkend="GTK-ACCESSIBLE-PROPERTY-VALUE-MAX:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_VALUE_MAX</literal></link>,
            <link linkend="GTK-ACCESSIBLE-PROPERTY-VALUE-MIN:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_VALUE_MIN</literal></link>, and
            <link linkend="GTK-ACCESSIBLE-PROPERTY-VALUE-NOW:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_VALUE_NOW</literal></link> properties with the
            upper, lower, and value properties of the <link linkend="GtkAdjustment"><type>GtkAdjustment</type></link>
          </para>
        </listitem>
      </itemizedlist>
      <para>
        See the
        <ulink url="https://www.w3.org/WAI/PF/aria/appendices#quickref">WAI-ARIA</ulink>
        list of attributes for additional information.
      </para>
      <sect4>
        <title>List of accessible states</title>
        <para>
          Each state name is part of the <link linkend="GtkAccessibleState"><type>GtkAccessibleState</type></link>
          enumeration.
        </para>
        <informaltable>
          <tgroup cols="4">
            <colspec colwidth="25*" align="left" />
            <colspec colwidth="34*" align="left" />
            <colspec colwidth="25*" align="left" />
            <colspec colwidth="14*" align="left" />
            <thead>
              <row>
                <entry>
                  State name
                </entry>
                <entry>
                  ARIA attribute
                </entry>
                <entry>
                  Value type
                </entry>
                <entry>
                  Notes
                </entry>
              </row>
            </thead>
            <tbody>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-STATE-BUSY:CAPS"><literal>GTK_ACCESSIBLE_STATE_BUSY</literal></link>
                </entry>
                <entry>
                  <quote>aria-busy</quote>
                </entry>
                <entry>
                  boolean
                </entry>
                <entry>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-STATE-CHECKED:CAPS"><literal>GTK_ACCESSIBLE_STATE_CHECKED</literal></link>
                </entry>
                <entry>
                  <quote>aria-checked</quote>
                </entry>
                <entry>
                  <link linkend="GtkAccessibleTristate"><type>GtkAccessibleTristate</type></link>
                </entry>
                <entry>
                  Indicates the current state of a <link linkend="GtkCheckButton"><type>GtkCheckButton</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-STATE-DISABLED:CAPS"><literal>GTK_ACCESSIBLE_STATE_DISABLED</literal></link>
                </entry>
                <entry>
                  <quote>aria-disabled</quote>
                </entry>
                <entry>
                  boolean
                </entry>
                <entry>
                  Corresponds to the <link linkend="GtkWidget--sensitive"><type>“sensitive”</type></link> property on
                  <link linkend="GtkWidget"><type>GtkWidget</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-STATE-EXPANDED:CAPS"><literal>GTK_ACCESSIBLE_STATE_EXPANDED</literal></link>
                </entry>
                <entry>
                  <quote>aria-expanded</quote>
                </entry>
                <entry>
                  boolean or undefined
                </entry>
                <entry>
                  Corresponds to the <link linkend="GtkExpander--expanded"><type>“expanded”</type></link> property on
                  <link linkend="GtkExpander"><type>GtkExpander</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-STATE-HIDDEN:CAPS"><literal>GTK_ACCESSIBLE_STATE_HIDDEN</literal></link>
                </entry>
                <entry>
                  <quote>aria-hidden</quote>
                </entry>
                <entry>
                  boolean
                </entry>
                <entry>
                  Corresponds to the <link linkend="GtkWidget--visible"><type>“visible”</type></link> property on
                  <link linkend="GtkWidget"><type>GtkWidget</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-STATE-INVALID:CAPS"><literal>GTK_ACCESSIBLE_STATE_INVALID</literal></link>
                </entry>
                <entry>
                  <quote>aria-invalid</quote>
                </entry>
                <entry>
                  <link linkend="GtkAccessibleInvalidState"><type>GtkAccessibleInvalidState</type></link>
                </entry>
                <entry>
                  Set when a widget is showing an error
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-STATE-PRESSED:CAPS"><literal>GTK_ACCESSIBLE_STATE_PRESSED</literal></link>
                </entry>
                <entry>
                  <quote>aria-pressed</quote>
                </entry>
                <entry>
                  <link linkend="GtkAccessibleTristate"><type>GtkAccessibleTristate</type></link>
                </entry>
                <entry>
                  Indicates the current state of a <link linkend="GtkToggleButton"><type>GtkToggleButton</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-STATE-SELECTED:CAPS"><literal>GTK_ACCESSIBLE_STATE_SELECTED</literal></link>
                </entry>
                <entry>
                  <quote>aria-selected</quote>
                </entry>
                <entry>
                  boolean or undefined
                </entry>
                <entry>
                  Set when a widget is selected
                </entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
      </sect4>
      <sect4>
        <title>List of accessible properties</title>
        <para>
          Each property name is part of the <link linkend="GtkAccessibleProperty"><type>GtkAccessibleProperty</type></link>
          enumeration.
        </para>
        <informaltable>
          <tgroup cols="3">
            <colspec colwidth="30*" align="left" />
            <colspec colwidth="40*" align="left" />
            <colspec colwidth="30*" align="left" />
            <thead>
              <row>
                <entry>
                  State name
                </entry>
                <entry>
                  ARIA attribute
                </entry>
                <entry>
                  Value type
                </entry>
              </row>
            </thead>
            <tbody>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-AUTOCOMPLETE:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE</literal></link>
                </entry>
                <entry>
                  <quote>aria-autocomplete</quote>
                </entry>
                <entry>
                  <link linkend="GtkAccessibleAutocomplete"><type>GtkAccessibleAutocomplete</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-DESCRIPTION:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_DESCRIPTION</literal></link>
                </entry>
                <entry>
                  <quote>aria-description</quote>
                </entry>
                <entry>
                  translatable string
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-HAS-POPUP:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_HAS_POPUP</literal></link>
                </entry>
                <entry>
                  <quote>aria-haspopup</quote>
                </entry>
                <entry>
                  boolean
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-KEY-SHORTCUTS:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_KEY_SHORTCUTS</literal></link>
                </entry>
                <entry>
                  <quote>aria-keyshortcuts</quote>
                </entry>
                <entry>
                  string
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-LABEL:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_LABEL</literal></link>
                </entry>
                <entry>
                  <quote>aria-label</quote>
                </entry>
                <entry>
                  translatable string
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-LEVEL:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_LEVEL</literal></link>
                </entry>
                <entry>
                  <quote>aria-level</quote>
                </entry>
                <entry>
                  integer
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-MODAL:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_MODAL</literal></link>
                </entry>
                <entry>
                  <quote>aria-modal</quote>
                </entry>
                <entry>
                  boolean
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-MULTI-LINE:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_MULTI_LINE</literal></link>
                </entry>
                <entry>
                  <quote>aria-multiline</quote>
                </entry>
                <entry>
                  boolean
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-MULTI-SELECTABLE:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE</literal></link>
                </entry>
                <entry>
                  <quote>aria-multiselectable</quote>
                </entry>
                <entry>
                  boolean
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-ORIENTATION:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_ORIENTATION</literal></link>
                </entry>
                <entry>
                  <quote>aria-orientation</quote>
                </entry>
                <entry>
                  <link linkend="GtkOrientation"><type>GtkOrientation</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-PLACEHOLDER:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_PLACEHOLDER</literal></link>
                </entry>
                <entry>
                  <quote>aria-placeholder</quote>
                </entry>
                <entry>
                  translatable string
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-READ-ONLY:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_READ_ONLY</literal></link>
                </entry>
                <entry>
                  <quote>aria-readonly</quote>
                </entry>
                <entry>
                  boolean
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-REQUIRED:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_REQUIRED</literal></link>
                </entry>
                <entry>
                  <quote>aria-required</quote>
                </entry>
                <entry>
                  boolean
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-ROLE-DESCRIPTION:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_ROLE_DESCRIPTION</literal></link>
                </entry>
                <entry>
                  <quote>aria-roledescription</quote>
                </entry>
                <entry>
                  translatable string
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-SORT:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_SORT</literal></link>
                </entry>
                <entry>
                  <quote>aria-sort</quote>
                </entry>
                <entry>
                  <link linkend="GtkAccessibleSort"><type>GtkAccessibleSort</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-VALUE-MAX:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_VALUE_MAX</literal></link>
                </entry>
                <entry>
                  <quote>aria-valuemax</quote>
                </entry>
                <entry>
                  double
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-VALUE-MIN:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_VALUE_MIN</literal></link>
                </entry>
                <entry>
                  <quote>aria-valuemin</quote>
                </entry>
                <entry>
                  double
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-VALUE-NOW:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_VALUE_NOW</literal></link>
                </entry>
                <entry>
                  <quote>aria-valuenow</quote>
                </entry>
                <entry>
                  double
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-PROPERTY-VALUE-TEXT:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT</literal></link>
                </entry>
                <entry>
                  <quote>aria-valuetext</quote>
                </entry>
                <entry>
                  translatable string
                </entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
      </sect4>
      <sect4>
        <title>List of accessible relations</title>
        <para>
          Each relation name is part of the <link linkend="GtkAccessibleRelation"><type>GtkAccessibleRelation</type></link>
          enumeration.
        </para>
        <informaltable>
          <tgroup cols="3">
            <colspec colwidth="30*" align="left" />
            <colspec colwidth="40*" align="left" />
            <colspec colwidth="30*" align="left" />
            <thead>
              <row>
                <entry>
                  State name
                </entry>
                <entry>
                  ARIA attribute
                </entry>
                <entry>
                  Value type
                </entry>
              </row>
            </thead>
            <tbody>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-ACTIVE-DESCENDANT:CAPS"><literal>GTK_ACCESSIBLE_RELATION_ACTIVE_DESCENDANT</literal></link>
                </entry>
                <entry>
                  <quote>aria-activedescendant</quote>
                </entry>
                <entry>
                  <link linkend="GtkAccessible"><type>GtkAccessible</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-COL-COUNT:CAPS"><literal>GTK_ACCESSIBLE_RELATION_COL_COUNT</literal></link>
                </entry>
                <entry>
                  <quote>aria-colcount</quote>
                </entry>
                <entry>
                  integer
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-COL-INDEX:CAPS"><literal>GTK_ACCESSIBLE_RELATION_COL_INDEX</literal></link>
                </entry>
                <entry>
                  <quote>aria-colindex</quote>
                </entry>
                <entry>
                  integer
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-COL-INDEX-TEXT:CAPS"><literal>GTK_ACCESSIBLE_RELATION_COL_INDEX_TEXT</literal></link>
                </entry>
                <entry>
                  <quote>aria-colindextext</quote>
                </entry>
                <entry>
                  translatable string
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-COL-SPAN:CAPS"><literal>GTK_ACCESSIBLE_RELATION_COL_SPAN</literal></link>
                </entry>
                <entry>
                  <quote>aria-colspan</quote>
                </entry>
                <entry>
                  integer
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-CONTROLS:CAPS"><literal>GTK_ACCESSIBLE_RELATION_CONTROLS</literal></link>
                </entry>
                <entry>
                  <quote>aria-controls</quote>
                </entry>
                <entry>
                  a list of <link linkend="GtkAccessible"><type>GtkAccessible</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-DESCRIBED-BY:CAPS"><literal>GTK_ACCESSIBLE_RELATION_DESCRIBED_BY</literal></link>
                </entry>
                <entry>
                  <quote>aria-describedby</quote>
                </entry>
                <entry>
                  a list of <link linkend="GtkAccessible"><type>GtkAccessible</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-DETAILS:CAPS"><literal>GTK_ACCESSIBLE_RELATION_DETAILS</literal></link>
                </entry>
                <entry>
                  <quote>aria-details</quote>
                </entry>
                <entry>
                  a list of <link linkend="GtkAccessible"><type>GtkAccessible</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-ERROR-MESSAGE:CAPS"><literal>GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE</literal></link>
                </entry>
                <entry>
                  <quote>aria-errormessage</quote>
                </entry>
                <entry>
                  <link linkend="GtkAccessible"><type>GtkAccessible</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-FLOW-TO:CAPS"><literal>GTK_ACCESSIBLE_RELATION_FLOW_TO</literal></link>
                </entry>
                <entry>
                  <quote>aria-flowto</quote>
                </entry>
                <entry>
                  a list of <link linkend="GtkAccessible"><type>GtkAccessible</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-LABELLED-BY:CAPS"><literal>GTK_ACCESSIBLE_RELATION_LABELLED_BY</literal></link>
                </entry>
                <entry>
                  <quote>aria-labelledby</quote>
                </entry>
                <entry>
                  a list of <link linkend="GtkAccessible"><type>GtkAccessible</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-OWNS:CAPS"><literal>GTK_ACCESSIBLE_RELATION_OWNS</literal></link>
                </entry>
                <entry>
                  <quote>aria-owns</quote>
                </entry>
                <entry>
                  a list of <link linkend="GtkAccessible"><type>GtkAccessible</type></link>
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-POS-IN-SET:CAPS"><literal>GTK_ACCESSIBLE_RELATION_POS_IN_SET</literal></link>
                </entry>
                <entry>
                  <quote>aria-posinset</quote>
                </entry>
                <entry>
                  integer
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-ROW-COUNT:CAPS"><literal>GTK_ACCESSIBLE_RELATION_ROW_COUNT</literal></link>
                </entry>
                <entry>
                  <quote>aria-rowcount</quote>
                </entry>
                <entry>
                  integer
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-ROW-INDEX:CAPS"><literal>GTK_ACCESSIBLE_RELATION_ROW_INDEX</literal></link>
                </entry>
                <entry>
                  <quote>aria-rowindex</quote>
                </entry>
                <entry>
                  integer
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-ROW-INDEX-TEXT:CAPS"><literal>GTK_ACCESSIBLE_RELATION_ROW_INDEX_TEXT</literal></link>
                </entry>
                <entry>
                  <quote>aria-rowindextext</quote>
                </entry>
                <entry>
                  translatable string
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-ROW-SPAN:CAPS"><literal>GTK_ACCESSIBLE_RELATION_ROW_SPAN</literal></link>
                </entry>
                <entry>
                  <quote>aria-rowspan</quote>
                </entry>
                <entry>
                  integer
                </entry>
              </row>
              <row>
                <entry>
                  <link linkend="GTK-ACCESSIBLE-RELATION-SET-SIZE:CAPS"><literal>GTK_ACCESSIBLE_RELATION_SET_SIZE</literal></link>
                </entry>
                <entry>
                  <quote>aria-setsize</quote>
                </entry>
                <entry>
                  integer
                </entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        <para>
          <emphasis>Note</emphasis>: When using
          <link linkend="gtk-accessible-update-relation"><function>gtk_accessible_update_relation()</function></link> with a relation that requires
          a list of <link linkend="GtkAccessible"><type>GtkAccessible</type></link> instances, you should pass every
          accessible object separately, followed by <link linkend="NULL:CAPS"><literal>NULL</literal></link>.
        </para>
      </sect4>
    </sect3>
  </sect2>
  <sect2>
    <title>Application development rules</title>
    <para>
      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:
    </para>
    <itemizedlist spacing="compact">
      <listitem>
        <para>
          the container of the form has a
          <literal>GTK_ACCESSIBLE_ROLE_FORM</literal> role
        </para>
      </listitem>
      <listitem>
        <para>
          each text entry widget in the form has the
          <literal>GTK_ACCESSIBLE_RELATION_LABELLED_BY</literal>
          relation pointing to the label widget that describes it
        </para>
      </listitem>
    </itemizedlist>
    <para>
      Another example: if you create a toolbar containing buttons with
      only icons, you should ensure that:
    </para>
    <itemizedlist spacing="compact">
      <listitem>
        <para>
          the container has a
          <literal>GTK_ACCESSIBLE_ROLE_TOOLBAR</literal> role
        </para>
      </listitem>
      <listitem>
        <para>
          each button has a
          <literal>GTK_ACCESSIBLE_PROPERTY_LABEL</literal> property set
          with the user readable and localised action performed when
          pressed; for instance <quote>Copy</quote>,
          <quote>Paste</quote>, <quote>Add layer</quote>, or
          <quote>Remove</quote>
        </para>
      </listitem>
    </itemizedlist>
    <para>
      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
      <literal>GTK_ACCESSIBLE_PROPERTY_LABEL</literal> property or the
      <literal>GTK_ACCESSIBLE_RELATION_LABELLED_BY</literal> 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.
    </para>
    <para>
      Application developers using GTK
      <emphasis role="strong">should</emphasis> ensure that their UI
      controls are accessible as part of the development process. When
      using <literal>GtkBuilder</literal> 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.
    </para>
  </sect2>
  <sect2>
    <title>Implementations</title>
    <para>
      Each UI control implements the <link linkend="GtkAccessible"><type>GtkAccessible</type></link> interface to allow
      widget and application developers to specify the roles, state, and
      relations between UI controls. This API is purely descriptive.
    </para>
    <para>
      Each <literal>GtkAccessible</literal> implementation must provide
      a <link linkend="GtkATContext"><type>GtkATContext</type></link> instance, which acts as a proxy to the specific
      platform’s accessibility API:
    </para>
    <itemizedlist spacing="compact">
      <listitem>
        <para>
          AT-SPI on Linux/BSD
        </para>
      </listitem>
      <listitem>
        <para>
          NSAccessibility on macOS
        </para>
      </listitem>
      <listitem>
        <para>
          Active Accessibility on Windows
        </para>
      </listitem>
    </itemizedlist>
    <para>
      Additionally, an ad hoc accessibility backend is available for the
      GTK testsuite, to ensure reproducibility of issues in the CI
      pipeline.
    </para>
  </sect2>
  <sect2 id="authoring-practices">
    <title>Authoring practices</title>
    <para>
      The authoring practices are aimed at application developers, as
      well as developers of GUI elements based on GTK.
    </para>
    <para>
      Functionally, <link linkend="GtkAccessible"><type>GtkAccessible</type></link> 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.
    </para>
    <sect3>
      <title>A role is a promise</title>
      <para>
        The following code:
      </para>
      <programlisting language="c">
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_BUTTON);
</programlisting>
      <para>
        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
        <link linkend="GtkButton"><type>GtkButton</type></link>; but if your widget behaves like a button, using the
        <link linkend="GTK-ACCESSIBLE-ROLE-BUTTON:CAPS"><literal>GTK_ACCESSIBLE_ROLE_BUTTON</literal></link> will allow any assistive technology
        to handle it like they would a <link linkend="GtkButton"><type>GtkButton</type></link>.
      </para>
    </sect3>
    <sect3>
      <title>Attributes can both hide and enhance</title>
      <para>
        Accessible attributes can be used to override the content of a
        UI element, for instance:
      </para>
      <programlisting language="c">
gtk_label_set_text (GTK_LABEL (label), &quot;Some text&quot;);
gtk_accessible_update_property (GTK_ACCESSIBLE (label),
                GTK_ACCESSIBLE_PROPERTY_LABEL,
                &quot;Assistive technologies users will perceive &quot;
                &quot;this text, not the contents of the label&quot;,
                -1);
</programlisting>
      <para>
        In the example above, the <quote>label</quote> property will
        override the contents of the label widget.
      </para>
      <para>
        The attributes can also enhance the UI:
      </para>
      <programlisting language="c">
gtk_button_set_label (GTK_BUTTON (button), &quot;Download&quot;);
gtk_box_append (GTK_BOX (button), button);

gtk_label_set_text (GTK_LABEL (label), &quot;Final report.pdf&quot;);
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);
</programlisting>
      <para>
        In the example above, an assistive technology will read the
        button’s accessible label as <quote>Download Final
        report.pdf</quote>.
      </para>
      <para>
        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.
      </para>
    </sect3>
  </sect2>
  <sect2>
    <title>Hiding UI elements from the accessible tree</title>
    <para>
      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
      <link linkend="GTK-ACCESSIBLE-ROLE-PRESENTATION:CAPS"><literal>GTK_ACCESSIBLE_ROLE_PRESENTATION</literal></link>, 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.
    </para>
    <para>
      A <quote>presentation</quote> role should not be confused with the
      <link linkend="GTK-ACCESSIBLE-STATE-HIDDEN:CAPS"><literal>GTK_ACCESSIBLE_STATE_HIDDEN</literal></link> state; the <quote>hidden</quote>
      state is transient, and is typically controlled by showing and
      hiding a widget using the <link linkend="GtkWidget"><type>GtkWidget</type></link> API.
    </para>
  </sect2>
  <sect2>
    <title>Design patterns and custom widgets</title>
    <para>
      When creating custom widgets, following established patterns can
      help ensuring that the widgets work well for users of accessible
      technologies as well.
    </para>
    <sect3>
      <title>Buttons</title>
      <para>
        A button is a widget that enables users to trigger an action.
        While it is recommended you use <link linkend="GtkButton"><type>GtkButton</type></link> 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
        <link linkend="GtkGestureClick"><type>GtkGestureClick</type></link> gesture. When doing so, you should:
      </para>
      <itemizedlist spacing="compact">
        <listitem>
          <para>
            Give your widget the role <link linkend="GTK-ACCESSIBLE-ROLE-BUTTON:CAPS"><literal>GTK_ACCESSIBLE_ROLE_BUTTON</literal></link>
          </para>
        </listitem>
        <listitem>
          <para>
            Install an action with no parameters, which will activate
            the widget
          </para>
        </listitem>
      </itemizedlist>
    </sect3>
    <sect3>
      <title>Custom entries</title>
      <para>
        For custom entries, it is highly recommended that you implement
        the <link linkend="GtkEditable"><type>GtkEditable</type></link> interface by using a <link linkend="GtkText"><type>GtkText</type></link> widget as
        delegate. If you do this, GTK will make your widgets text
        editing functionality accessible in the same way as a
        <link linkend="GtkSpinButton"><type>GtkSpinButton</type></link> or <link linkend="GtkSearchEntry"><type>GtkSearchEntry</type></link>.
      </para>
    </sect3>
    <sect3>
      <title>Tab-based UI</title>
      <para>
        If you make a tab-based interface, you should consider using
        <link linkend="GtkStack"><type>GtkStack</type></link> 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 <link linkend="GtkStackSwitcher"><type>GtkStackSwitcher</type></link> or <link linkend="GtkNotebook"><type>GtkNotebook</type></link>:
      </para>
      <itemizedlist spacing="compact">
        <listitem>
          <para>
            Give your tab container the role
            <link linkend="GTK-ACCESSIBLE-ROLE-TAB-LIST:CAPS"><literal>GTK_ACCESSIBLE_ROLE_TAB_LIST</literal></link>
          </para>
        </listitem>
        <listitem>
          <para>
            Give your tab widgets the role <link linkend="GTK-ACCESSIBLE-ROLE-TAB:CAPS"><literal>GTK_ACCESSIBLE_ROLE_TAB</literal></link>
          </para>
        </listitem>
        <listitem>
          <para>
            Set up the <link linkend="GTK-ACCESSIBLE-RELATION-CONTROLS:CAPS"><literal>GTK_ACCESSIBLE_RELATION_CONTROLS</literal></link> relation
            between each tab and the <link linkend="GtkStackPage"><type>GtkStackPage</type></link> object for its page
          </para>
        </listitem>
        <listitem>
          <para>
            Set the <link linkend="GTK-ACCESSIBLE-PROPERTY-SELECTED:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_SELECTED</literal></link> property on each
            tab, with the active tab getting the value <link linkend="TRUE:CAPS"><literal>TRUE</literal></link>, all others
            <link linkend="FALSE:CAPS"><literal>FALSE</literal></link>
          </para>
        </listitem>
      </itemizedlist>
      <para>
        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
        <literal>previous-tab</literal> and <literal>next-tab</literal>
        actions on the tab container that let users step through the
        tabs one-by-one, or add a <literal>activate-tab</literal> action
        on each tab.
      </para>
    </sect3>
    <sect3>
      <title>Value controls</title>
      <para>
        A value control (ie a widget that controls a one-dimensional
        quantity that can be represented by a <link linkend="GtkAdjustment"><type>GtkAdjustment</type></link>) can be
        represented to accessible technologies by setting the
        <link linkend="GTK-ACCESSIBLE-PROPERTY-VALUE-MIN:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_VALUE_MIN</literal></link>,
        <link linkend="GTK-ACCESSIBLE-PROPERTY-VALUE-MAX:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_VALUE_MAX</literal></link>, and
        <link linkend="GTK-ACCESSIBLE-PROPERTY-VALUE-NOW:CAPS"><literal>GTK_ACCESSIBLE_PROPERTY_VALUE_NOW</literal></link> properties.
      </para>
      <para>
        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
        <literal>increase-value</literal> and
        <literal>decrease-value</literal>.
      </para>
    </sect3>
  </sect2>
</sect1>
