iOS: Iterate accessible interface to find window

Many subclasses of QAccessibleInterface implement window(), but
some don't, and the documentation states that the backend (us)
will traverse ancestors until it finds one with a window.

We were not doing that for iOS, which caused a crash for
QAccessibleTabButton, which doesn't have a window.

In case we ever hit the code path where we can't find a
window we also skip adding the nil element to the array
in createAccessibleElement, as that causes an exception.

Amends 7a512d1267442e646bb7942291197b2b03f4d1cd

Pick-to: 6.8 6.5
Change-Id: I9b758423956e845a01b014022f4d3ab6306be94e
Reviewed-by: Doris Verria <doris.verria@qt.io>
(cherry picked from commit 6689921b9da3780676a416324eafcac98ab211a3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Tor Arne Vestbø 2024-11-28 22:57:37 +01:00 committed by Qt Cherry-pick Bot
parent 8a7ee8d522
commit b3c60bd11f
2 changed files with 13 additions and 7 deletions

View File

@ -36,16 +36,22 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAccessibilityElement);
QMacAccessibilityElement *element = cache->elementForId(anId);
if (!element) {
auto *a11yInterface = QAccessible::accessibleInterface(anId);
Q_ASSERT(a11yInterface);
auto *window = a11yInterface->window();
QWindow *window = nullptr;
auto *iface = QAccessible::accessibleInterface(anId);
while (iface) {
if ((window = iface->window()))
break;
iface = iface->parent();
}
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);
qWarning() << "Could not create a11y element for" << iface
<< "with window" << window
<< "and platform window" << (window ? window->handle() : nullptr);
}
}
return element;

View File

@ -13,8 +13,8 @@
if (!iface || iface->state().invisible || (iface->text(QAccessible::Name).isEmpty() && iface->text(QAccessible::Value).isEmpty() && iface->text(QAccessible::Description).isEmpty()))
return;
QAccessible::Id accessibleId = QAccessible::uniqueId(iface);
UIAccessibilityElement *elem = [QT_MANGLE_NAMESPACE(QMacAccessibilityElement) elementWithId:accessibleId];
[m_accessibleElements addObject:elem];
if (UIAccessibilityElement *elem = [QT_MANGLE_NAMESPACE(QMacAccessibilityElement) elementWithId:accessibleId])
[m_accessibleElements addObject:elem];
}
- (void)createAccessibleContainer:(QAccessibleInterface *)iface