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 <jan.moeller@governikus.de> Fixes: QTBUG-114608 Pick-to: 6.7 6.6 6.5 Change-Id: I2e43ae649bc7e3a44c1e1200e8de66bf420b1949 Reviewed-by: Lars Schmertmann <lars.schmertmann@governikus.de> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>bb10
parent
af051f9be2
commit
7a512d1267
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <QtGui/QtGui>
|
||||
#include "qioswindow.h"
|
||||
#include "quiaccessibilityelement.h"
|
||||
|
||||
QIOSPlatformAccessibility::QIOSPlatformAccessibility()
|
||||
{}
|
||||
|
|
@ -42,6 +43,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:
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ public:
|
|||
#endif
|
||||
|
||||
bool isForeignWindow() const override;
|
||||
UIView *view() const;
|
||||
|
||||
private:
|
||||
void applicationStateChanged(Qt::ApplicationState state);
|
||||
|
|
|
|||
|
|
@ -458,6 +458,11 @@ bool QIOSWindow::isForeignWindow() const
|
|||
return ![m_view isKindOfClass:QUIView.class];
|
||||
}
|
||||
|
||||
UIView *QIOSWindow::view() const
|
||||
{
|
||||
return m_view;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "moc_qioswindow.cpp"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue