diff options
author | Michael Weghorn <m.weghorn@posteo.de> | 2024-04-09 16:17:58 +0200 |
---|---|---|
committer | Michael Weghorn <m.weghorn@posteo.de> | 2024-05-14 00:32:37 +0200 |
commit | 24986ccb7b2020cbb574700a31667e88ed243194 (patch) | |
tree | cc72cf5f76a432cc669914f827cdd935ff548fe0 | |
parent | c9e62c24440e99ace02dcceffea2ae6542f49224 (diff) |
a11y atspi: Forward new QAccessibleAnnouncementEvent to AT-SPI
Forward the newly added QAccessibleAnnouncementEvent
to the AT-SPI level as a corresponding AT-SPI Announcement
event.
The AtspiLive enum to specify the priority/politeness
level was added in at-spi2-core/libatspi commit [1] which is
contained in libatspi versions >= 2.50, so define
the relevant values ATSPI_LIVE_ASSERTIVE and ATSPI_LIVE_POLITE
manually for older libatspi versions.
(Note that the mention of binary compatibility in above-mentioned
at-spi2-core commit only applies for ATK, not AT-SPI, so is not
relevant here.)
This makes announcement from the example app attached to QTBUG-75003
work when using the Orca screen reader on Linux.
[1] https://gitlab.gnome.org/GNOME/at-spi2-core/-/commit/32c9420ec82f07da8033c675a2bbf25e535f0509
Task-number: QTBUG-75003
Change-Id: I752aadca2abdda58b3869e17e74fcd9d7572f915
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r-- | src/gui/accessible/linux/atspiadaptor.cpp | 38 | ||||
-rw-r--r-- | src/gui/accessible/linux/atspiadaptor_p.h | 3 |
2 files changed, 41 insertions, 0 deletions
diff --git a/src/gui/accessible/linux/atspiadaptor.cpp b/src/gui/accessible/linux/atspiadaptor.cpp index b3269a2a95..2cebad1453 100644 --- a/src/gui/accessible/linux/atspiadaptor.cpp +++ b/src/gui/accessible/linux/atspiadaptor.cpp @@ -35,6 +35,13 @@ #define ATSPI_COORD_TYPE_PARENT 2 #endif +// ATSPI_*_VERSION defines were added in libatspi 2.50, +// as was the AtspiLive enum; define values here for older versions +#if !defined(ATSPI_MAJOR_VERSION) || !defined(ATSPI_MINOR_VERSION) || ATSPI_MAJOR_VERSION < 2 || ATSPI_MINOR_VERSION < 50 +#define ATSPI_LIVE_POLITE 1 +#define ATSPI_LIVE_ASSERTIVE 2 +#endif + QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; @@ -47,6 +54,7 @@ AtSpiAdaptor::AtSpiAdaptor(DBusConnection *connection, QObject *parent) , sendFocus(0) , sendObject(0) , sendObject_active_descendant_changed(0) + , sendObject_announcement(0) , sendObject_attributes_changed(0) , sendObject_bounds_changed(0) , sendObject_children_changed(0) @@ -678,6 +686,8 @@ void AtSpiAdaptor::setBitFlag(const QString &flag) if (false) { } else if (right.startsWith("ActiveDescendantChanged"_L1)) { sendObject_active_descendant_changed = 1; + } else if (right.startsWith("Announcement"_L1)) { + sendObject_announcement = 1; } else if (right.startsWith("AttributesChanged"_L1)) { sendObject_attributes_changed = 1; } else if (right.startsWith("BoundsChanged"_L1)) { @@ -929,6 +939,26 @@ void AtSpiAdaptor::notifyStateChange(QAccessibleInterface *interface, const QStr sendDBusSignal(path, ATSPI_DBUS_INTERFACE_EVENT_OBJECT ""_L1, "StateChanged"_L1, stateArgs); } +void AtSpiAdaptor::sendAnnouncement(QAccessibleAnnouncementEvent *event) +{ + QAccessibleInterface *iface = event->accessibleInterface(); + if (!iface) { + qCWarning(lcAccessibilityAtspi, "Announcement event has no accessible set."); + return; + } + if (!iface->isValid()) { + qCWarning(lcAccessibilityAtspi) << "Announcement event with invalid accessible: " << iface; + return; + } + + const QString path = pathForInterface(iface); + const QString message = event->message(); + const QAccessible::AnnouncementPriority prio = event->priority(); + const int politeness = (prio == QAccessible::AnnouncementPriority::Assertive) ? ATSPI_LIVE_ASSERTIVE : ATSPI_LIVE_POLITE; + + const QVariantList args = packDBusSignalArguments(QString(), politeness, 0, QVariant::fromValue(QDBusVariant(message))); + sendDBusSignal(path, ATSPI_DBUS_INTERFACE_EVENT_OBJECT ""_L1, "Announcement"_L1, args); +} /*! This function gets called when Qt notifies about accessibility updates. @@ -1003,6 +1033,14 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event) sendFocusChanged(event->accessibleInterface()); break; } + + case QAccessible::Announcement: { + if (sendObject || sendObject_announcement) { + QAccessibleAnnouncementEvent *announcementEvent = static_cast<QAccessibleAnnouncementEvent*>(event); + sendAnnouncement(announcementEvent); + } + break; + } case QAccessible::TextInserted: case QAccessible::TextRemoved: case QAccessible::TextUpdated: { diff --git a/src/gui/accessible/linux/atspiadaptor_p.h b/src/gui/accessible/linux/atspiadaptor_p.h index c2f9b60ebf..aab15d4501 100644 --- a/src/gui/accessible/linux/atspiadaptor_p.h +++ b/src/gui/accessible/linux/atspiadaptor_p.h @@ -85,6 +85,8 @@ private: void notifyStateChange(QAccessibleInterface *interface, const QString& state, int value); + void sendAnnouncement(QAccessibleAnnouncementEvent *event); + // accessible helper functions AtspiRole getRole(QAccessibleInterface *interface) const; QSpiRelationArray relationSet(QAccessibleInterface *interface, const QDBusConnection &connection) const; @@ -130,6 +132,7 @@ private: // all of object uint sendObject : 1; uint sendObject_active_descendant_changed : 1; + uint sendObject_announcement : 1; uint sendObject_attributes_changed : 1; uint sendObject_bounds_changed : 1; uint sendObject_children_changed : 1; |