summaryrefslogtreecommitdiffstats
path: root/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/other/qaccessibility/tst_qaccessibility.cpp')
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp169
1 files changed, 169 insertions, 0 deletions
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index d2a9688f10..ed38976d94 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -243,6 +243,7 @@ private slots:
void accelerators();
#endif
void bridgeTest();
+ void focusChild();
protected slots:
void onClicked();
@@ -3931,5 +3932,173 @@ void tst_QAccessibility::bridgeTest()
#endif
}
+class FocusChildTestAccessibleInterface : public QAccessibleInterface
+{
+public:
+ FocusChildTestAccessibleInterface(int index, bool focus, QAccessibleInterface *parent)
+ : m_parent(parent)
+ , m_index(index)
+ , m_focus(focus)
+ {
+ QAccessible::registerAccessibleInterface(this);
+ }
+
+ bool isValid() const override { return true; }
+ QObject *object() const override { return nullptr; }
+ QAccessibleInterface *childAt(int, int) const override { return nullptr; }
+ QAccessibleInterface *parent() const override { return m_parent; }
+ QAccessibleInterface *child(int) const override { return nullptr; }
+ int childCount() const override { return 0; }
+ int indexOfChild(const QAccessibleInterface *) const override { return -1; }
+ QString text(QAccessible::Text) const override { return QStringLiteral("FocusChildTestAccessibleInterface %1").arg(m_index); }
+ void setText(QAccessible::Text, const QString &) override { }
+ QRect rect() const override { return QRect(); }
+ QAccessible::Role role() const override { return QAccessible::StaticText; }
+
+ QAccessible::State state() const override
+ {
+ QAccessible::State s;
+ s.focused = m_focus;
+ return s;
+ }
+
+private:
+ QAccessibleInterface *m_parent;
+ int m_index;
+ bool m_focus;
+};
+
+class FocusChildTestAccessibleWidget : public QAccessibleWidget
+{
+public:
+ static QAccessibleInterface *ifaceFactory(const QString &key, QObject *o)
+ {
+ if (key == "QtTestAccessibleWidget")
+ return new FocusChildTestAccessibleWidget(static_cast<QtTestAccessibleWidget *>(o));
+ return 0;
+ }
+
+ FocusChildTestAccessibleWidget(QtTestAccessibleWidget *w)
+ : QAccessibleWidget(w)
+ {
+ m_children.push_back(new FocusChildTestAccessibleInterface(0, false, this));
+ m_children.push_back(new FocusChildTestAccessibleInterface(1, true, this));
+ m_children.push_back(new FocusChildTestAccessibleInterface(2, false, this));
+ }
+
+ QAccessible::State state() const override
+ {
+ QAccessible::State s = QAccessibleWidget::state();
+ s.focused = false;
+ return s;
+ }
+
+ QAccessibleInterface *focusChild() const override
+ {
+ for (int i = 0; i < childCount(); ++i) {
+ if (child(i)->state().focused)
+ return child(i);
+ }
+
+ return nullptr;
+ }
+
+ QAccessibleInterface *child(int index) const override
+ {
+ return m_children[index];
+ }
+
+ int childCount() const override
+ {
+ return m_children.size();
+ }
+
+private:
+ QVector<QAccessibleInterface *> m_children;
+};
+
+void tst_QAccessibility::focusChild()
+{
+ {
+ QMainWindow mainWindow;
+ QtTestAccessibleWidget *widget1 = new QtTestAccessibleWidget(0, "Widget1");
+ QAccessibleInterface *iface1 = QAccessible::queryAccessibleInterface(widget1);
+ QtTestAccessibleWidget *widget2 = new QtTestAccessibleWidget(0, "Widget2");
+ QAccessibleInterface *iface2 = QAccessible::queryAccessibleInterface(widget2);
+
+ QWidget *centralWidget = new QWidget;
+ QHBoxLayout *centralLayout = new QHBoxLayout;
+ centralWidget->setLayout(centralLayout);
+ mainWindow.setCentralWidget(centralWidget);
+ centralLayout->addWidget(widget1);
+ centralLayout->addWidget(widget2);
+
+ mainWindow.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
+
+ // widget1 has not been focused yet -> it has no active focus nor focus widget.
+ QVERIFY(!iface1->focusChild());
+
+ // widget1 is focused -> it has active focus and focus widget.
+ widget1->setFocus();
+ QCOMPARE(iface1->focusChild(), iface1);
+ QCOMPARE(QAccessible::queryAccessibleInterface(&mainWindow)->focusChild(), iface1);
+
+ // widget1 lose focus -> it has no active focus but has focus widget what is itself.
+ // In this case, the focus child of widget1's interface is itself and the focusChild() call
+ // should not run into an infinite recursion.
+ widget2->setFocus();
+ QCOMPARE(iface1->focusChild(), iface1);
+ QCOMPARE(iface2->focusChild(), iface2);
+ QCOMPARE(QAccessible::queryAccessibleInterface(&mainWindow)->focusChild(), iface2);
+
+ delete widget1;
+ delete widget2;
+ delete centralWidget;
+ QTestAccessibility::clearEvents();
+ }
+
+ {
+ QMainWindow mainWindow;
+ QAccessible::installFactory(&FocusChildTestAccessibleWidget::ifaceFactory);
+ QtTestAccessibleWidget *widget = new QtTestAccessibleWidget(0, "FocusChildTestWidget");
+ mainWindow.setCentralWidget(widget);
+ mainWindow.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
+
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&mainWindow);
+ QVERIFY(!iface->focusChild());
+ widget->setFocus();
+ QCOMPARE(iface->focusChild(), QAccessible::queryAccessibleInterface(widget)->child(1));
+
+ delete widget;
+ QAccessible::removeFactory(FocusChildTestAccessibleWidget::ifaceFactory);
+ QTestAccessibility::clearEvents();
+ }
+
+ {
+ QMainWindow mainWindow;
+ QTabBar *tabBar = new QTabBar();
+ tabBar->insertTab(0, "First tab");
+ tabBar->insertTab(1, "Second tab");
+ tabBar->insertTab(2, "Third tab");
+ mainWindow.setCentralWidget(tabBar);
+ mainWindow.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
+
+ tabBar->setFocus();
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&mainWindow);
+ QCOMPARE(iface->focusChild()->text(QAccessible::Name), QStringLiteral("First tab"));
+ QCOMPARE(iface->focusChild()->role(), QAccessible::PageTab);
+ tabBar->setCurrentIndex(1);
+ QCOMPARE(iface->focusChild()->text(QAccessible::Name), QStringLiteral("Second tab"));
+ QCOMPARE(iface->focusChild()->role(), QAccessible::PageTab);
+
+ delete tabBar;
+ QTestAccessibility::clearEvents();
+ }
+}
+
+
QTEST_MAIN(tst_QAccessibility)
#include "tst_qaccessibility.moc"