Accessibility: Top level widgets should only be in the hierarchy once
On Linux for example Orca gets confused when showing a dialog that is a child of another widget since it would show up twice in the hierarchy. Task-number: QTBUG-39444 Change-Id: I84773ecc3d6774a652dbeb29ad201779f5b3191c Reviewed-by: Jan Arve Sæther <jan-arve.saether@digia.com>
This commit is contained in:
parent
d448725403
commit
d71f9d8c05
@ -240,10 +240,10 @@ QWidget *QAccessibleWidget::widget() const
|
||||
*/
|
||||
QObject *QAccessibleWidget::parentObject() const
|
||||
{
|
||||
QObject *parent = object()->parent();
|
||||
if (!parent)
|
||||
parent = qApp;
|
||||
return parent;
|
||||
QWidget *w = widget();
|
||||
if (!w || w->isWindow() || !w->parentWidget())
|
||||
return qApp;
|
||||
return w->parent();
|
||||
}
|
||||
|
||||
/*! \reimp */
|
||||
@ -353,11 +353,7 @@ QAccessibleWidget::relations(QAccessible::Relation match /*= QAccessible::AllRel
|
||||
/*! \reimp */
|
||||
QAccessibleInterface *QAccessibleWidget::parent() const
|
||||
{
|
||||
Q_ASSERT(widget());
|
||||
QObject *parentWidget= widget()->parentWidget();
|
||||
if (!parentWidget)
|
||||
parentWidget = qApp;
|
||||
return QAccessible::queryAccessibleInterface(parentWidget);
|
||||
return QAccessible::queryAccessibleInterface(parentObject());
|
||||
}
|
||||
|
||||
/*! \reimp */
|
||||
|
@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
QString qt_accStripAmp(const QString &text);
|
||||
|
||||
QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel)
|
||||
QList<QWidget*> childWidgets(const QWidget *widget)
|
||||
{
|
||||
if (widget == 0)
|
||||
return QList<QWidget*>();
|
||||
@ -85,7 +85,7 @@ QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel)
|
||||
if (!w)
|
||||
continue;
|
||||
QString objectName = w->objectName();
|
||||
if ((includeTopLevel || !w->isWindow())
|
||||
if (!w->isWindow()
|
||||
&& !qobject_cast<QFocusFrame*>(w)
|
||||
&& !qobject_cast<QMenu*>(w)
|
||||
&& objectName != QLatin1String("qt_rubberband")
|
||||
@ -970,7 +970,7 @@ QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget)
|
||||
|
||||
QAccessibleInterface *QAccessibleMainWindow::child(int index) const
|
||||
{
|
||||
QList<QWidget*> kids = childWidgets(mainWindow(), true);
|
||||
QList<QWidget*> kids = childWidgets(mainWindow());
|
||||
if (index >= 0 && index < kids.count()) {
|
||||
return QAccessible::queryAccessibleInterface(kids.at(index));
|
||||
}
|
||||
@ -979,13 +979,13 @@ QAccessibleInterface *QAccessibleMainWindow::child(int index) const
|
||||
|
||||
int QAccessibleMainWindow::childCount() const
|
||||
{
|
||||
QList<QWidget*> kids = childWidgets(mainWindow(), true);
|
||||
QList<QWidget*> kids = childWidgets(mainWindow());
|
||||
return kids.count();
|
||||
}
|
||||
|
||||
int QAccessibleMainWindow::indexOfChild(const QAccessibleInterface *iface) const
|
||||
{
|
||||
QList<QWidget*> kids = childWidgets(mainWindow(), true);
|
||||
QList<QWidget*> kids = childWidgets(mainWindow());
|
||||
return kids.indexOf(static_cast<QWidget*>(iface->object()));
|
||||
}
|
||||
|
||||
@ -998,7 +998,7 @@ QAccessibleInterface *QAccessibleMainWindow::childAt(int x, int y) const
|
||||
if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y))
|
||||
return 0;
|
||||
|
||||
QWidgetList kids = childWidgets(mainWindow(), true);
|
||||
QWidgetList kids = childWidgets(mainWindow());
|
||||
QPoint rp = mainWindow()->mapFromGlobal(QPoint(x, y));
|
||||
for (int i = 0; i < kids.size(); ++i) {
|
||||
QWidget *child = kids.at(i);
|
||||
|
@ -69,7 +69,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
|
||||
extern QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel = false);
|
||||
extern QList<QWidget*> childWidgets(const QWidget *widget);
|
||||
|
||||
QString qt_accStripAmp(const QString &text);
|
||||
QString qt_accHotKey(const QString &text);
|
||||
|
@ -251,6 +251,7 @@ private slots:
|
||||
|
||||
void applicationTest();
|
||||
void mainWindowTest();
|
||||
void subWindowTest();
|
||||
void buttonTest();
|
||||
void scrollBarTest();
|
||||
void tabTest();
|
||||
@ -1003,6 +1004,66 @@ void tst_QAccessibility::mainWindowTest()
|
||||
}
|
||||
}
|
||||
|
||||
// Dialogs and other sub-windows must appear in the
|
||||
// accessibility hierarchy exactly once as top level objects
|
||||
void tst_QAccessibility::subWindowTest()
|
||||
{
|
||||
{
|
||||
QWidget mainWidget;
|
||||
mainWidget.setGeometry(100, 100, 100, 100);
|
||||
mainWidget.show();
|
||||
QLabel label(QStringLiteral("Window Contents"), &mainWidget);
|
||||
mainWidget.setLayout(new QHBoxLayout());
|
||||
mainWidget.layout()->addWidget(&label);
|
||||
|
||||
QDialog d(&mainWidget);
|
||||
d.show();
|
||||
|
||||
QAccessibleInterface *app = QAccessible::queryAccessibleInterface(qApp);
|
||||
QVERIFY(app);
|
||||
QCOMPARE(app->childCount(), 2);
|
||||
|
||||
QAccessibleInterface *windowIface = QAccessible::queryAccessibleInterface(&mainWidget);
|
||||
QVERIFY(windowIface);
|
||||
QCOMPARE(windowIface->childCount(), 1);
|
||||
QCOMPARE(app->child(0), windowIface);
|
||||
QCOMPARE(windowIface->parent(), app);
|
||||
|
||||
QAccessibleInterface *dialogIface = QAccessible::queryAccessibleInterface(&d);
|
||||
QVERIFY(dialogIface);
|
||||
QCOMPARE(app->child(1), dialogIface);
|
||||
QCOMPARE(dialogIface->parent(), app);
|
||||
QCOMPARE(dialogIface->parent(), app);
|
||||
}
|
||||
|
||||
{
|
||||
QMainWindow mainWindow;
|
||||
mainWindow.setGeometry(100, 100, 100, 100);
|
||||
mainWindow.show();
|
||||
QLabel label(QStringLiteral("Window Contents"), &mainWindow);
|
||||
mainWindow.setCentralWidget(&label);
|
||||
|
||||
QDialog d(&mainWindow);
|
||||
d.show();
|
||||
|
||||
QAccessibleInterface *app = QAccessible::queryAccessibleInterface(qApp);
|
||||
QVERIFY(app);
|
||||
QCOMPARE(app->childCount(), 2);
|
||||
|
||||
QAccessibleInterface *windowIface = QAccessible::queryAccessibleInterface(&mainWindow);
|
||||
QVERIFY(windowIface);
|
||||
QCOMPARE(windowIface->childCount(), 1);
|
||||
QCOMPARE(app->child(0), windowIface);
|
||||
|
||||
QAccessibleInterface *dialogIface = QAccessible::queryAccessibleInterface(&d);
|
||||
QVERIFY(dialogIface);
|
||||
QCOMPARE(app->child(1), dialogIface);
|
||||
QCOMPARE(dialogIface->parent(), app);
|
||||
QCOMPARE(windowIface->parent(), app);
|
||||
}
|
||||
QTestAccessibility::clearEvents();
|
||||
}
|
||||
|
||||
class CounterButton : public QPushButton {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user