diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-06-05 18:41:11 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-06-07 13:39:43 +0200 |
commit | b006d6d9dea11ac788a54ee3ffd13a9463003a32 (patch) | |
tree | 9c7ab54054ed82610195a025f7013af3a5b91940 /src/plugins/platforms/ios | |
parent | 0237709e2cde08ce792081615250377295722e19 (diff) |
iOS: Don't invalidate a11y whenever UI elements are added or removed
The UIAccessibilityScreenChangedNotification will result in iOS resetting
its state, focusing the first a11y element on the screen. We shouldn't
tie clearing the a11y cache to this notification, as those are two
separate actions.
In the case of adding or removing individual elements, we still likely
need to clear the cache, but can inform the system of the more granular
UIAccessibilityLayoutChangedNotification to have it re-read the a11y
tree.
We still handle additions and removal of a11y elements with Window
or Dialog roles as UIAccessibilityScreenChangedNotification, as these
likely involve major UI changes.
The implicit UIAccessibilityScreenChangedNotification on QIOSWindow
destruction has been removed, as it's assumed iOS will automatically
refresh its a11y tree when a UIWindow is destroyed, and in any case
it's up to the individual clients of QAccessible to send the relevant
QAccessibleEvent to inform about the situation.
Pick-to: 6.6 6.5
Fixes: QTBUG-100094
Change-Id: If7d5cb961743e5ca97d45553b05ae5e92f82d275
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/plugins/platforms/ios')
-rw-r--r-- | src/plugins/platforms/ios/qiosplatformaccessibility.mm | 17 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.mm | 1 | ||||
-rw-r--r-- | src/plugins/platforms/ios/quiview_accessibility.mm | 1 |
3 files changed, 14 insertions, 5 deletions
diff --git a/src/plugins/platforms/ios/qiosplatformaccessibility.mm b/src/plugins/platforms/ios/qiosplatformaccessibility.mm index d54b7db57a..f22782fb04 100644 --- a/src/plugins/platforms/ios/qiosplatformaccessibility.mm +++ b/src/plugins/platforms/ios/qiosplatformaccessibility.mm @@ -25,8 +25,6 @@ void invalidateCache(QAccessibleInterface *iface) // This will invalidate everything regardless of what window the // interface belonged to. We might want to revisit this strategy later. // (Therefore this function still takes the interface as argument) - // It is also responsible for the bug that focus gets temporary lost - // when items get added or removed from the screen foreach (QWindow *win, QGuiApplication::topLevelWindows()) { if (win && win->handle()) { QT_PREPEND_NAMESPACE(QIOSWindow) *window = static_cast<QT_PREPEND_NAMESPACE(QIOSWindow) *>(win->handle()); @@ -38,14 +36,25 @@ void invalidateCache(QAccessibleInterface *iface) void QIOSPlatformAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) { - if (!isActive() || !event->accessibleInterface()) + auto *accessibleInterface = event->accessibleInterface(); + if (!isActive() || !accessibleInterface) return; switch (event->type()) { case QAccessible::ObjectCreated: case QAccessible::ObjectShow: case QAccessible::ObjectHide: case QAccessible::ObjectDestroyed: - invalidateCache(event->accessibleInterface()); + invalidateCache(accessibleInterface); + switch (accessibleInterface->role()) { + case QAccessible::Window: + case QAccessible::Dialog: + // Bigger changes to the UI require a full reset of VoiceOver + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); + break; + default: + // While smaller changes can be handled by re-reading the layout + UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil); + } break; default: break; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 99f9e38846..8de094533b 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -75,6 +75,7 @@ QIOSWindow::~QIOSWindow() [m_view touchesCancelled:[NSSet set] withEvent:0]; clearAccessibleCache(); + m_view.platformWindow = 0; [m_view removeFromSuperview]; [m_view release]; diff --git a/src/plugins/platforms/ios/quiview_accessibility.mm b/src/plugins/platforms/ios/quiview_accessibility.mm index 366141ef81..04e1f8cfb3 100644 --- a/src/plugins/platforms/ios/quiview_accessibility.mm +++ b/src/plugins/platforms/ios/quiview_accessibility.mm @@ -54,7 +54,6 @@ - (void)clearAccessibleCache { [m_accessibleElements removeAllObjects]; - UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, @""); } // this is a container, returning yes here means the functions below will never be called |