a11y on macOS: return a valid window element
Our accessibilityWindow implementation asks the parent for it's window, expecting that it will always be the same. This is conceptually correct. However, as we don't represent windows through QAccessibilityInterface and instead rely on the natively provided element, the filtering out of ignored elements result in accessibilityParent return a null object once the parent is the window. Instead, check if we get an interface that represents a Window, and if so fall through to the code returning the NSView (after going through QAcessibilityInterface::window call, which was so far missing). And if we then get a Window element as the parent, then we don't have to call accessibilityWindow on that parent again. Instead, return the result directly and only keep going if we got some other element. Add a test case that confirms that we now get a valid result for the window attribute. Pick-to: 6.8 6.5 Fixes: QTBUG-137157 Change-Id: Ifa485734b290284bd5a1286e3b3c18454442fa10 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> (cherry picked from commit 5dc261357e44ac9e15423997748e28ae659a3623) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit c75046876642663acb58aed0998702bece8b1e12)
This commit is contained in:
parent
ca91db230a
commit
355d5b85ae
@ -553,8 +553,11 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
|
||||
}
|
||||
|
||||
- (id) accessibilityWindow {
|
||||
// We're in the same window as our parent.
|
||||
return [self.accessibilityParent accessibilityWindow];
|
||||
// Go up until we find a parent that is a window
|
||||
NSAccessibilityElement *parent = self.accessibilityParent;
|
||||
if (parent && parent.accessibilityRole == NSAccessibilityWindowRole)
|
||||
return parent;
|
||||
return [parent accessibilityWindow];
|
||||
}
|
||||
|
||||
- (id) accessibilityTopLevelUIElementAttribute {
|
||||
@ -605,11 +608,6 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
|
||||
return NSAccessibilityUnignoredAncestor([QMacAccessibilityElement elementWithId:axid]);
|
||||
}
|
||||
|
||||
// macOS expects that the hierarchy is:
|
||||
// App -> Window -> Children
|
||||
// We don't actually have the window reflected properly in QAccessibility.
|
||||
// Check if the parent is the application and then instead return the native window.
|
||||
|
||||
if (QAccessibleInterface *parent = iface->parent()) {
|
||||
if (parent->tableInterface()) {
|
||||
QMacAccessibilityElement *tableElement =
|
||||
@ -627,7 +625,12 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
|
||||
QMacAccessibilityElement *rowElement = tableElement->rows[rowIndex];
|
||||
return NSAccessibilityUnignoredAncestor(rowElement);
|
||||
}
|
||||
if (parent->role() != QAccessible::Application)
|
||||
// macOS expects that the hierarchy is:
|
||||
// App -> Window -> Children
|
||||
// We don't actually have the window reflected properly in QAccessibility;
|
||||
// the native framework does that for us. Check if the parent is the
|
||||
// Application or a window, and if so return the native NSView instead.
|
||||
if (parent->role() != QAccessible::Application && parent->role() != QAccessible::Window)
|
||||
return NSAccessibilityUnignoredAncestor([QMacAccessibilityElement elementWithInterface: parent]);
|
||||
}
|
||||
|
||||
|
@ -382,6 +382,7 @@ QDebug operator<<(QDebug dbg, AXErrorTag err)
|
||||
return rect;
|
||||
}
|
||||
- (AXUIElementRef) parent { return (AXUIElementRef)[self _attributeValue:kAXParentAttribute]; }
|
||||
- (AXUIElementRef) window { return (AXUIElementRef)[self _attributeValue:kAXWindowAttribute]; }
|
||||
- (BOOL) focused { return [self _boolAttributeValue:kAXFocusedAttribute]; }
|
||||
- (NSInteger) numberOfCharacters { return [self _numberAttributeValue:kAXNumberOfCharactersAttribute]; }
|
||||
- (NSString*) selectedText { return [self _stringAttributeValue:kAXSelectedTextAttribute]; }
|
||||
@ -449,6 +450,7 @@ private Q_SLOTS:
|
||||
void tableViewTest();
|
||||
void treeViewTest();
|
||||
void tabBarTest();
|
||||
void windowTest();
|
||||
|
||||
private:
|
||||
AccessibleTestWindow *m_window;
|
||||
@ -933,5 +935,35 @@ void tst_QAccessibilityMac::tabBarTest()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QAccessibilityMac::windowTest()
|
||||
{
|
||||
QTextEdit *textEdit = new QTextEdit;
|
||||
m_window->addWidget(textEdit);
|
||||
QVERIFY(QTest::qWaitForWindowExposed(m_window));
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
TestAXObject *appObject = [TestAXObject getApplicationAXObject];
|
||||
QVERIFY(appObject);
|
||||
|
||||
NSArray *windowList = [appObject windowList];
|
||||
// one window
|
||||
QVERIFY([windowList count] == 1);
|
||||
AXUIElementRef windowRef = (AXUIElementRef)[windowList objectAtIndex:0];
|
||||
QVERIFY(windowRef != nil);
|
||||
TestAXObject *window = [[TestAXObject alloc] initWithAXUIElementRef:windowRef];
|
||||
QVERIFY(window.valid);
|
||||
|
||||
AXUIElementRef axTextEdit = [window findDirectChildByRole:kAXTextAreaRole];
|
||||
QVERIFY(axTextEdit != nil);
|
||||
|
||||
[appObject release];
|
||||
[window release];
|
||||
|
||||
TestAXObject *edit = [[TestAXObject alloc] initWithAXUIElementRef:axTextEdit];
|
||||
QVERIFY(edit.valid);
|
||||
AXUIElementRef axWindow = edit.window;
|
||||
QVERIFY(axWindow);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QAccessibilityMac)
|
||||
#include "tst_qaccessibilitymac.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user