diff options
author | Tor Arne Vestbø <[email protected]> | 2024-02-05 17:14:34 +0100 |
---|---|---|
committer | Tor Arne Vestbø <[email protected]> | 2024-03-04 15:13:52 +0000 |
commit | c14bbd243c1e98dc08b6af7147547847402f66ac (patch) | |
tree | a91822747032fc57ef7f72c1789a64060df80cfa | |
parent | 95f83db223c5e5723a6ccfa0619a44a83392b27f (diff) |
iOS: Propagate focus changes to VoiceOver
Changing the focus object should update the VoiceOver focused element,
the same way we do it on macOS.
There's no NSAccessibilityFocusedUIElementChangedNotification on iOS,
but we can pass the focused element as an argument when posting the
UIAccessibilityLayoutChangedNotification.
The class method on QMacAccessibilityElement to get an element for
an QAccessible::Id was not used by any callers, and has been modified
to resolve the container from the QAccessibleInterface, so that we
don't need to plumb that all the way from the focus change event.
Inspired-by: Jan Möller <[email protected]>
Fixes: QTBUG-114608
Change-Id: I2e43ae649bc7e3a44c1e1200e8de66bf420b1949
Reviewed-by: Lars Schmertmann <[email protected]>
Reviewed-by: Volker Hilsheimer <[email protected]>
(cherry picked from commit 7a512d1267442e646bb7942291197b2b03f4d1cd)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
(cherry picked from commit 1c8cb94e4ab7b6255c95caebf7d7f545a1e9a0ff)
(cherry picked from commit 6e434de7008d9ba214b10208057573bc2f5c05c5)
Reviewed-by: Tor Arne Vestbø <[email protected]>
-rw-r--r-- | src/plugins/platforms/ios/qiosplatformaccessibility.mm | 11 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.mm | 5 | ||||
-rw-r--r-- | src/plugins/platforms/ios/quiaccessibilityelement.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/ios/quiaccessibilityelement.mm | 17 |
5 files changed, 32 insertions, 5 deletions
diff --git a/src/plugins/platforms/ios/qiosplatformaccessibility.mm b/src/plugins/platforms/ios/qiosplatformaccessibility.mm index 38fc631f4ca..77517108eec 100644 --- a/src/plugins/platforms/ios/qiosplatformaccessibility.mm +++ b/src/plugins/platforms/ios/qiosplatformaccessibility.mm @@ -7,6 +7,7 @@ #include <QtGui/QtGui> #include "qioswindow.h" +#include "quiaccessibilityelement.h" QIOSPlatformAccessibility::QIOSPlatformAccessibility() {} @@ -40,6 +41,16 @@ void QIOSPlatformAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *even if (!isActive() || !accessibleInterface) return; switch (event->type()) { + case QAccessible::Focus: { + auto *element = [QMacAccessibilityElement elementWithId:event->uniqueId()]; + Q_ASSERT(element); + // There's no NSAccessibilityFocusedUIElementChangedNotification, like we have on + // macOS. Instead, the documentation for UIAccessibilityLayoutChangedNotification + // specifies that the optional argument to UIAccessibilityPostNotification is the + // accessibility element for VoiceOver to move to after processing the notification. + UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, element); + break; + } case QAccessible::ObjectCreated: case QAccessible::ObjectShow: case QAccessible::ObjectHide: diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index a4100449ccd..76be1c9ee26 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -60,6 +60,8 @@ public: CAEAGLLayer *eaglLayer() const; #endif + UIView *view() const; + private: void applicationStateChanged(Qt::ApplicationState state); void applyGeometry(const QRect &rect); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index ca615756bdf..5ab2d3b4a21 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -384,6 +384,11 @@ QDebug operator<<(QDebug debug, const QIOSWindow *window) } #endif // !QT_NO_DEBUG_STREAM +UIView *QIOSWindow::view() const +{ + return m_view; +} + QT_END_NAMESPACE #include "moc_qioswindow.cpp" diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.h b/src/plugins/platforms/ios/quiaccessibilityelement.h index d217760b5c8..415c9a87527 100644 --- a/src/plugins/platforms/ios/quiaccessibilityelement.h +++ b/src/plugins/platforms/ios/quiaccessibilityelement.h @@ -14,7 +14,7 @@ @property (readonly) QAccessible::Id axid; - (instancetype)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view; -+ (instancetype)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view; ++ (instancetype)elementWithId:(QAccessible::Id)anId; @end diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.mm b/src/plugins/platforms/ios/quiaccessibilityelement.mm index 44a5efb4db7..5c3849c9215 100644 --- a/src/plugins/platforms/ios/quiaccessibilityelement.mm +++ b/src/plugins/platforms/ios/quiaccessibilityelement.mm @@ -8,6 +8,7 @@ #include "private/qaccessiblecache_p.h" #include "private/qcore_mac_p.h" #include "uistrings_p.h" +#include "qioswindow.h" QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAccessibilityElement); @@ -23,7 +24,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAccessibilityElement); return self; } -+ (instancetype)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view ++ (instancetype)elementWithId:(QAccessible::Id)anId { Q_ASSERT(anId); if (!anId) @@ -33,9 +34,17 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAccessibilityElement); QMacAccessibilityElement *element = cache->elementForId(anId); if (!element) { - Q_ASSERT(QAccessible::accessibleInterface(anId)); - element = [[self alloc] initWithId:anId withAccessibilityContainer:view]; - cache->insertElement(anId, element); + auto *a11yInterface = QAccessible::accessibleInterface(anId); + Q_ASSERT(a11yInterface); + auto *window = a11yInterface->window(); + if (window && window->handle()) { + auto *platformWindow = static_cast<QIOSWindow*>(window->handle()); + element = [[self alloc] initWithId:anId withAccessibilityContainer:platformWindow->view()]; + cache->insertElement(anId, element); + } else { + qWarning() << "Could not create a11y element for" << window + << "with platform window" << (window ? window->handle() : nullptr); + } } return element; } |