summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2023-11-10 18:25:02 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2024-02-29 04:44:22 +0000
commitfb5ffe862688a87cfc136113e067bcba0c49a7ae (patch)
tree1612b26c714875043714d4709a1142bb3b946655 /src/gui
parent6164b17d226a4dd2099a852a6c34bae6fa19876d (diff)
a11y: Add new QAccessibleAttributesInterface
This adds a new QAccessibleAttributes interface that implements support for reporting (object) attributes (as compared to offset-specific text attributes, which are handled by the QAccessibleTextInterface). The concept of object attributes/properties can be found in all of ARIA, AT-SPI2 on Linux, IAccessible2 and UIA on Windows and NSAccessibility on macOS, and while some of the properties/attributes on these platforms can be mapped to from information retrieved via existing QAccessible* interfaces, a lot of relevant information cannot be made available this way. The new interface is meant to bridge this gap. Each attribute is handled as a key-value pair. Other than for the handling of text attributes (where a single string is used for all attributes, s. QAccessibleTextInterface::attributes), the object attributes handled by the new interface use the newly introduced QAccessible::Attribute enum class for keys. This helps to clearly define the semantics of each attribute and simplifies mapping to the different platform representations in the platform a11y bridges. Initially, two attribute types, Custom and Level are added, s. the documentation added with this commit for more details. Mapping of these two attributes to their platform equivalent for AT-SPI2 on Linux and UIA on Windows will be added in following commits. The Core Accessibility API Mappings specification [1] can be very useful when considering new attributes to add and how to bridge them to the specific platform APIs. Conceptually, the possibility to expose object-specific attributes might seem a good fit for the existing QAccessibleInterface, but adding new virtual methods to non-leaf classes would be an ABI-incompatible change [2], so adding a new interface/class is necessary. There is also a related discussion for Gtk 4 in [3], which - other than Gtk 3 - currently also lacks API to support many AT-SPI object attributes relevant for assistive technology like screen readers. The implementation here is also inspired by the dicussion there. A sample implementation for LibreOffice can be found at [4]. [1] https://www.w3.org/TR/core-aam-1.2/ [2] https://community.kde.org/Policies/Binary_Compatibility_Examples#Add_new_virtuals_to_a_non-leaf_class [3] https://gitlab.gnome.org/GNOME/gtk/-/issues/6196 [4] https://gerrit.libreoffice.org/c/core/+/159309 [ChangeLog][QtGui][QAccessibleAttributesInterface] Added new QAccessibleAttributesInterface that can be used to expose object attributes/properties to assistive technology. Task-number: QTBUG-119057 Change-Id: I9d51c818e82673d1e755a3c909d3e8f5bb064a35 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/qaccessible.cpp88
-rw-r--r--src/gui/accessible/qaccessible.h13
-rw-r--r--src/gui/accessible/qaccessible_base.h8
3 files changed, 107 insertions, 2 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index ea8ab097d1..46bca16dad 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -412,6 +412,43 @@ Q_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core");
\sa QAccessibleTextInterface
*/
+/*! \enum QAccessible::Attribute
+ This enum describes different types of attributes used by the
+ \l QAccessibleAttributesInterface.
+ \since 6.8
+
+ These attributes are comparable to the concept of properties/(object)
+ attributes found in ARIA, AT-SPI2, IAccessible, UIA and NSAccessibility
+ and are mapped to their platform counterpart where applicable.
+
+ Each attribute is handled as a key-value pair, with the values of this
+ enumeration being used as keys.
+
+ Attribute values are represented in a \l QVariant. The type of the value
+ stored in the \l QVariant is fixed and specified below for each of the
+ attribute types.
+
+ \value Custom value type: \a QHash<QString, QString>
+ The \a Custom attribute is special in that
+ it can effectively represent multiple attributes at
+ once, since it itself is a \l QHash used to represent
+ key-value pairs.
+ For platforms supporting custom key-value pairs for
+ attributes, those set in the \a Custom attribute
+ are bridged to the platform layer without applying any
+ translation to platform-specific attributes. In general,
+ the other, more strongly typed attributes should be used.
+ This attribute can e.g. be used for prototyping
+ before officially adding an official new enumeration value
+ for a specific feature.
+ \value Level value type: \a int
+ Defines the hierarchical level of an element within a structure,
+ e.g. the heading level of a heading. This attribute conceptually
+ matches the "aria-level" property in ARIA.
+
+ \sa QAccessibleAttributesInterface
+*/
+
/*!
\enum QAccessible::InterfaceType
@@ -431,8 +468,9 @@ Q_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core");
\value TableCellInterface For cells in a TableInterface object.
\value HyperlinkInterface For hyperlink nodes (usually embedded as children of text nodes)
\value [since 6.5] SelectionInterface For non-text objects that support selection of child objects.
+ \value [since 6.8] AttributesInterface For objects that support object-specific attributes.
- \sa QAccessibleInterface::interface_cast(), QAccessibleTextInterface, QAccessibleValueInterface, QAccessibleActionInterface, QAccessibleTableInterface, QAccessibleTableCellInterface, QAccessibleSelectionInterface
+ \sa QAccessibleInterface::interface_cast(), QAccessibleTextInterface, QAccessibleValueInterface, QAccessibleActionInterface, QAccessibleTableInterface, QAccessibleTableCellInterface, QAccessibleSelectionInterface, QAccessibleAttributesInterface
*/
#if QT_CONFIG(accessibility)
@@ -3069,6 +3107,54 @@ bool QAccessibleSelectionInterface::isSelected(QAccessibleInterface *childItem)
*/
+/*!
+ \since 6.8
+ \class QAccessibleAttributesInterface
+ \inmodule QtGui
+ \ingroup accessibility
+
+ \brief The QAccessibleAttributesInterface class implements support for
+ reporting attributes for an accessible object.
+
+ Attributes are key-value pairs. Values are stored in \l QVariant.
+
+ The \a QAccessible::Attributes enumeration describes the available keys and
+ documents which type to use for the value of each key.
+
+ While the text-specific attributes handled by \l QAccessibleTextInterface::attributes
+ are specific to objects implementing text and are specific to a specific text
+ position/offset, the attributes handled by the \l QAccessibleAttributesInterface
+ can be used for objects of any role and apply for the whole object.
+
+ Classes already implementing \l QAccessibleTextInterface for text-specific attrtibutes
+ may want to implement \l QAccessibleAttributesInterface in addition for object-specific
+ attributes.
+*/
+
+/*!
+
+ Destroys the QAccessibleAttributesInterface.
+*/
+QAccessibleAttributesInterface::~QAccessibleAttributesInterface()
+{
+}
+
+/*!
+ \fn QList<QAccessible::Attribute> QAccessibleAttributesInterface::attributeKeys() const
+
+ Returns the keys of all attributes the object supports. The \l QAccessible::Attribute
+ enumeration describes available keys.
+*/
+
+/*!
+ \fn QVariant QAccessibleAttributesInterface::attributeValue(QAccessible::Attribute key) const
+
+ Returns the value of the attribute \a key of this object.
+
+ If the specificed attribute is not set for this object, an invalid
+ \l QVariant is returned.
+*/
+
/*! \internal */
QString qAccessibleLocalizedActionDescription(const QString &actionName)
{
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index 3fdc4eb7d9..0a92e76c73 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -43,6 +43,7 @@ class QAccessibleTableInterface;
class QAccessibleTableCellInterface;
class QAccessibleHyperlinkInterface;
class QAccessibleSelectionInterface;
+class QAccessibleAttributesInterface;
class QAccessibleTableModelChangeEvent;
class Q_GUI_EXPORT QAccessibleInterface
@@ -106,6 +107,9 @@ public:
inline QAccessibleSelectionInterface *selectionInterface()
{ return reinterpret_cast<QAccessibleSelectionInterface *>(interface_cast(QAccessible::SelectionInterface)); }
+ inline QAccessibleAttributesInterface *attributesInterface()
+ { return reinterpret_cast<QAccessibleAttributesInterface *>(interface_cast(QAccessible::AttributesInterface)); }
+
virtual void virtual_hook(int id, void *data);
virtual void *interface_cast(QAccessible::InterfaceType)
@@ -284,6 +288,15 @@ public:
virtual bool clear() = 0;
};
+class Q_GUI_EXPORT QAccessibleAttributesInterface
+{
+public:
+ virtual ~QAccessibleAttributesInterface();
+ virtual QList<QAccessible::Attribute> attributeKeys() const = 0;
+ virtual QVariant attributeValue(QAccessible::Attribute key) const = 0;
+};
+
+
class Q_GUI_EXPORT QAccessibleEvent
{
Q_DISABLE_COPY(QAccessibleEvent)
diff --git a/src/gui/accessible/qaccessible_base.h b/src/gui/accessible/qaccessible_base.h
index 74926a3565..2d2b1de316 100644
--- a/src/gui/accessible/qaccessible_base.h
+++ b/src/gui/accessible/qaccessible_base.h
@@ -349,7 +349,8 @@ public:
TableInterface,
TableCellInterface,
HyperlinkInterface,
- SelectionInterface
+ SelectionInterface,
+ AttributesInterface,
};
enum TextBoundaryType {
@@ -361,6 +362,11 @@ public:
NoBoundary
};
+ enum class Attribute {
+ Custom,
+ Level,
+ };
+
typedef QAccessibleInterface*(*InterfaceFactory)(const QString &key, QObject*);
typedef void(*UpdateHandler)(QAccessibleEvent *event);
typedef void(*RootObjectHandler)(QObject*);