diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-03-26 10:14:45 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-27 14:37:16 +0100 |
commit | f16d690a2f8c6ff1830a15794950c8564ae18a29 (patch) | |
tree | 64be48ac43a332e2040f1ed8451efe4e605ba1e7 /src/plugins | |
parent | 7aec099ca3cbc3f04562db027dc88f29e7ca28e4 (diff) |
Accessibility Mac: Fix handling of top level widget
This simplifies how we handle QNSView for accessibility purposes.
Instead of trying to half-merge the top level widget
(window->accessibleRoot) into the view, just have the view
always return it as child.
This makes the accessibility implementation for QNSView simpler
and makes applications that show a top level widget such as a button
possible. (We would return accessibility ignored for the button before).
As a side effect finding the active focus and hit-testing should be more reliable as
well.
Task-number: QTBUG-37794
Change-Id: Ib52037f88da8887a0bdc77204b0f3daddfe7709d
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@digia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 18 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsviewaccessibility.mm | 53 |
2 files changed, 30 insertions, 41 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index bc98d002f0..0b674b8d2f 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -417,7 +417,23 @@ } - (id)accessibilityFocusedUIElement { - return NSAccessibilityUnignoredAncestor(self); + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + + if (!iface || !iface->isValid()) { + qWarning() << "FocusedUIElement for INVALID"; + return nil; + } + QAccessibleInterface *childInterface = iface->focusChild(); + if (childInterface) { + QAccessible::Id childAxid = QAccessible::uniqueId(childInterface); + // FIXME: parent could be wrong + QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self]; + [accessibleElement autorelease]; + return accessibleElement; + } + + // no focus found + return nil; } @end diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm index a438950a55..31e3e343b9 100644 --- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm +++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm @@ -54,6 +54,15 @@ @implementation QNSView (QNSViewAccessibility) +- (id)childAccessibleElement { + if (!m_window->accessibleRoot()) + return nil; + + QAccessible::Id childId = QAccessible::uniqueId(m_window->accessibleRoot()); + QCocoaAccessibleElement *child = [QCocoaAccessibleElement createElementWithId: childId parent: self]; + return [child autorelease]; +} + // The QNSView is a container that the user does not interact directly with: // Remove it from the user-visible accessibility tree. - (BOOL)accessibilityIsIgnored { @@ -61,58 +70,22 @@ } - (id)accessibilityAttributeValue:(NSString *)attribute { - // activate accessibility updates QCocoaIntegration::instance()->accessibility()->setActive(true); - if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) { - if (m_window->accessibleRoot()) - return QCocoaAccessible::macRole(m_window->accessibleRoot()); - return NSAccessibilityUnknownRole; - } else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) { - return NSAccessibilityRoleDescriptionForUIElement(self); - } else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { - if (!m_window->accessibleRoot()) - return [super accessibilityAttributeValue:attribute]; - return QCocoaAccessible::unignoredChildren(self, m_window->accessibleRoot()); + if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { + return NSAccessibilityUnignoredChildrenForOnlyChild([self childAccessibleElement]); } else { return [super accessibilityAttributeValue:attribute]; } } - (id)accessibilityHitTest:(NSPoint)point { - if (!m_window->accessibleRoot()) - return [super accessibilityHitTest:point]; - - QAccessibleInterface *childInterface = m_window->accessibleRoot()->childAt(point.x, qt_mac_flipYCoordinate(point.y)); - // No child found, meaning we hit the NSView - if (!childInterface) { - return [super accessibilityHitTest:point]; - } - - // Hit a child, forward to child accessible interface. - QAccessible::Id childAxid = QAccessible::uniqueId(childInterface); - // FIXME: parent could be wrong - QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self ]; - [accessibleElement autorelease]; - return [accessibleElement accessibilityHitTest:point]; + return [[self childAccessibleElement] accessibilityHitTest: point]; } - (id)accessibilityFocusedUIElement { - if (!m_window->accessibleRoot()) - return [super accessibilityFocusedUIElement]; - - QAccessibleInterface *childInterface = m_window->accessibleRoot()->focusChild(); - if (childInterface) { - QAccessible::Id childAxid = QAccessible::uniqueId(childInterface); - // FIXME: parent could be wrong - QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self]; - [accessibleElement autorelease]; - return accessibleElement; - } - - // should not happen - return nil; + return [[self childAccessibleElement] accessibilityFocusedUIElement]; } @end |