qt5base-lts/tests/auto/other
Jan Arve Sæther 6707efcb97 a11y: Add support for Tables in macOS bridge
For a11y purposes, a table needs to be mapped into a logical
accessibility hierarchy.  There are several ways of doing this mapping,
and unfortunately macOS expects something different than what
QAccessibleInterface does.

So suppose we have a a 2x2 QTableView with both horizontal and vertical
header like this (the names reflect the QAccessible::Role names):

  +-----------+--------------+--------------+
  |           | ColumnHeader | ColumnHeader |
  +-----------+--------------+--------------+
  | RowHeader | Cell         | Cell         |
  +-----------+--------------+--------------+
  | RowHeader | Cell         | Cell         |
  +-----------+--------------+--------------+

In order to be presented to the screen reader on a platform, it goes
through two rounds of mapping:

QAccessibleInterface will have all headers and cells as direct children of the table:

 - Table
   +- ColumnHeader
   +- ColumnHeader
   +- RowHeader
   +- Cell
   +- Cell
   +- RowHeader
   +- Cell
   +- Cell

macOS expects a deeper hierarchy:

 - AXTable [QAccessible::Table]
   +- AXRow     [Qt:no eqiuivalent]
      +- [QAccessible::Cell] (The content of the cell, e.g. AXButton, AXGroup or whatever)
      +- [QAccessible::Cell] (The content of the cell, e.g. AXButton, AXGroup or whatever)
   +- AXRow
      +- [QAccessible::Cell] (The content of the cell, e.g. AXButton, AXGroup or whatever)
      +- [QAccessible::Cell] (The content of the cell, e.g. AXButton, AXGroup or whatever)
   +- AXColumn (this seems to just store the geometry of the column)
   +- AXColumn (this seems to just store the geometry of the column)
   +- AXGroup   (this represents the column headers)
      +- AXSortButton (clicking a header cell will trigger sorting)
      +- AXSortButton (clicking a header cell will trigger sorting)

It's unclear to me how RowHeaders are mapped (they are rarer than
ColumnHeaders, I expect to find them in e.g. spreadsheet applications).
I haven't found any native usage of them. So this patch simply ignores
them.

Notice that macOS have a three layer deep hierarchy to represent a table
(Table->Row->Cell), while QAccessibleInterface has a two-layer deep
hierarchy (Table->Row/Cell).

In the macOS bridge we therefore need to "inject" the Row/Column element
to be "between" the table and the cell.

The table will take ownership of all row and column elements that are
children of the table. These elements are not inserted into the cache
(it would be pointless, since the cache is basically just a mapping
between the QAccessibleInterface -> QMacAccessibilityElement, and the
row and column elements does not have a corresponding
QAccessibleInterface to be mapped from).

The rows and columns are therefore also created as soon as the table
element is initialized, and they are stored in two NSMutableArray
members of QMacAccessibilityElement.

A table is constructed like any other accessibility element, with a
valid axid and synthesizedRole set to nil.
Each child row and column element is constructed with the same axid as the
parent table element, and they will have the synthesizedRole set to
either NSAccessibilityRow or NSAccessibilityColumn.
With the synthesizedRole member we can then identify if we are a row,
column or the actual table, and implement their respective behaviors.

Notice that the child row/column is created with the parent's table axid
in order for them to have a way of finding their parent table element.
(there is no 'parent' member variable in QMacAccessibilityElement)

This glorious scheme isn't pretty, but seems to work.

Fixes: QTBUG-37207
Change-Id: I7c2451e629f5331b9a0ed61dc22c6e74a82cc173
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2022-11-10 19:50:14 +01:00
..
gestures Stabilize flakiness in tst_gestures 2022-11-08 18:52:26 +01:00
languagechange Change the license of all CMakeLists.txt and *.cmake files to BSD 2022-08-23 23:58:42 +02:00
macgui Change the license of all CMakeLists.txt and *.cmake files to BSD 2022-08-23 23:58:42 +02:00
macnativeevents QtBase tests: remove QT_DISABLE_DEPRECATED_UP_TO defines 2022-08-24 22:08:49 +02:00
macplist Change the license of all CMakeLists.txt and *.cmake files to BSD 2022-08-23 23:58:42 +02:00
networkselftest Port from container.count()/length() to size() 2022-10-04 07:40:08 +02:00
qabstractitemmodelutils Use SPDX license identifiers 2022-05-16 16:37:38 +02:00
qaccessibility Revert "Accessibility: don't emit focus change when reason is window activation" 2022-11-03 18:47:38 +01:00
qaccessibilitylinux a11y: support GetAccessibleId for at-spi 2022-10-25 15:19:41 +02:00
qaccessibilitymac a11y: Add support for Tables in macOS bridge 2022-11-10 19:50:14 +01:00
qcomplextext Port from container.count()/length() to size() 2022-10-04 07:40:08 +02:00
qfocusevent Deprecate QApplication::setActiveWindow() and mark as internal 2022-08-27 20:22:29 +02:00
qnetworkaccessmanager_and_qprogressdialog Change the license of all CMakeLists.txt and *.cmake files to BSD 2022-08-23 23:58:42 +02:00
qobjectrace Long live Q_UNREACHABLE_RETURN()! 2022-10-15 22:11:47 +02:00
qprocess_and_guieventloop Port from container::count() and length() to size() - V5 2022-11-03 14:59:24 +01:00
qsharedpointer_and_qwidget Change the license of all CMakeLists.txt and *.cmake files to BSD 2022-08-23 23:58:42 +02:00
qvariant_common Use SPDX license identifiers 2022-05-16 16:37:38 +02:00
sessionmanagement_macos Use SPDX license identifiers 2022-05-16 16:37:38 +02:00
toolsupport Change the license of all CMakeLists.txt and *.cmake files to BSD 2022-08-23 23:58:42 +02:00
xkbkeyboard Change the license of all CMakeLists.txt and *.cmake files to BSD 2022-08-23 23:58:42 +02:00
CMakeLists.txt Change the license of all CMakeLists.txt and *.cmake files to BSD 2022-08-23 23:58:42 +02:00