a11y uia: Forward new QAccessibleAnnouncementEvent to UIA

Bridge the newly added QAccessibleAnnouncementEvent to UIA
on Windows, by calling UiaRaiseNotificationEvent [1].

This makes the announcement from the example app attached
to QTBUG-75003 work when using the NVDA screen reader on Windows.

As described in commit d25d9f2c26,
implement the UiaRaiseNotificationEvent function for MingW
in qwindowsuiautomation as MingW doesn't provide that
itself yet (see the earlier MingW build failure without
that "kludge" in place: [2]).

[1] https://learn.microsoft.com/en-us/windows/win32/api/uiautomationcoreapi/nf-uiautomationcoreapi-uiaraisenotificationevent
[2] a2e63edda6/build_1714142084/log.txt.gz

Fixes: QTBUG-75003
Change-Id: Ia32d49276e0dd33cff5113b4169ee317869390e7
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
bb10
Michael Weghorn 2024-04-24 08:42:12 +02:00
parent 24986ccb7b
commit 0377ad2f83
4 changed files with 30 additions and 0 deletions

View File

@ -127,6 +127,9 @@ void QWindowsUiaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event
return;
switch (event->type()) {
case QAccessible::Announcement:
QWindowsUiaMainProvider::raiseNotification(static_cast<QAccessibleAnnouncementEvent *>(event));
break;
case QAccessible::Focus:
QWindowsUiaMainProvider::notifyFocusChange(event);
break;

View File

@ -204,6 +204,24 @@ void QWindowsUiaMainProvider::notifyTextChange(QAccessibleEvent *event)
}
}
void QWindowsUiaMainProvider::raiseNotification(QAccessibleAnnouncementEvent *event)
{
if (QAccessibleInterface *accessible = event->accessibleInterface()) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
BSTR message = bStrFromQString(event->message());
QAccessible::AnnouncementPriority prio = event->priority();
NotificationProcessing processing = (prio == QAccessible::AnnouncementPriority::Assertive)
? NotificationProcessing_ImportantAll
: NotificationProcessing_All;
BSTR activityId = bStrFromQString(QString::fromLatin1(""));
UiaRaiseNotificationEvent(provider, NotificationKind_Other, processing, message, activityId);
::SysFreeString(message);
::SysFreeString(activityId);
}
}
}
HRESULT STDMETHODCALLTYPE QWindowsUiaMainProvider::QueryInterface(REFIID iid, LPVOID *iface)
{
HRESULT result = QComObject::QueryInterface(iid, iface);

View File

@ -34,6 +34,7 @@ public:
static void notifyNameChange(QAccessibleEvent *event);
static void notifySelectionChange(QAccessibleEvent *event);
static void notifyTextChange(QAccessibleEvent *event);
static void raiseNotification(QAccessibleAnnouncementEvent *event);
// IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface) override;

View File

@ -69,6 +69,14 @@ HRESULT WINAPI UiaRaiseAutomationEvent(IRawElementProviderSimple *pProvider, EVE
return func.invoke(pProvider, id);
}
HRESULT WINAPI UiaRaiseNotificationEvent(
IRawElementProviderSimple *pProvider, NotificationKind notificationKind,
NotificationProcessing notificationProcessing, BSTR displayString, BSTR activityId)
{
static auto func = winapi_func("uiautomationcore", FN(UiaRaiseNotificationEvent));
return func.invoke(pProvider, notificationKind, notificationProcessing, displayString, activityId);
}
#endif // defined(__MINGW32__) || defined(__MINGW64__)
#endif // QT_CONFIG(accessibility)