From e17dddfd3bcc09a9ae919a1650107c8cd3a75d08 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Thu, 20 Dec 2012 16:09:39 +0100 Subject: [PATCH] Make hierarchy of actions in menubars more consistent. There is an assumption that the interface returned from iface->parent() would have iface as one of its children (thus, parent->indexOfChild(iface) should always return an integer != -1, indicating that it is a child. This is a good assumption, otherwise an hierarchy would be presented differently depending on how it is traversed. However, a QMenu created like this: QMenu *menu = new QMenu("weird parent", mainWindow); mainWindow->menuBar()->addMenu(menu); will have a different ancestor sequence than a menu created like this: mainWindow->menuBar()->addMenu("ok parent"); This is because it will walk up the QObject hierarchy. This patch tries to deal with that by looking at which widgets the action of the menu is associated with before determining which should be the accessible parent. Change-Id: I00dad8a94463f772d7b1f5d66fdb36b2e8d3aea2 Reviewed-by: Frederik Gladhorn --- src/plugins/accessible/widgets/qaccessiblemenu.cpp | 13 ++++++++++--- .../other/qaccessibility/tst_qaccessibility.cpp | 11 +++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp index fd2619f5458..e467ef50bdd 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.cpp +++ b/src/plugins/accessible/widgets/qaccessiblemenu.cpp @@ -104,9 +104,16 @@ QAccessibleInterface *QAccessibleMenu::child(int index) const QAccessibleInterface *QAccessibleMenu::parent() const { - QWidget *parent = menu()->parentWidget(); - if (qobject_cast(parent) || qobject_cast(parent)) { - return new QAccessibleMenuItem(parent, menu()->menuAction()); + if (QAction *menuAction = menu()->menuAction()) { + QList parentCandidates; + parentCandidates << menu()->parentWidget(); + parentCandidates << menuAction->associatedWidgets(); + foreach (QWidget *w, parentCandidates) { + if (qobject_cast(w) || qobject_cast(w)) { + if (w->actions().indexOf(menuAction) != -1) + return new QAccessibleMenuItem(w, menuAction); + } + } } return QAccessibleWidget::parent(); } diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index ea322b20a10..68fde2fd2ed 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -1265,14 +1265,21 @@ void tst_QAccessibility::menuTest() mw.menuBar()->addAction("Action!"); + QMenu *childOfMainWindow = new QMenu(QStringLiteral("&Tools"), &mw); + childOfMainWindow->addAction("&Options"); + mw.menuBar()->addMenu(childOfMainWindow); + mw.show(); // triggers layout QTest::qWait(100); - QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(mw.menuBar()); + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&mw); QCOMPARE(verifyHierarchy(interface), 0); + delete interface; + + interface = QAccessible::queryAccessibleInterface(mw.menuBar()); QVERIFY(interface); - QCOMPARE(interface->childCount(), 5); + QCOMPARE(interface->childCount(), 6); QCOMPARE(interface->role(), QAccessible::MenuBar); QAccessibleInterface *iFile = interface->child(0);