From 795b9fdc52993e0199f462add398b5de8e4d75c4 Mon Sep 17 00:00:00 2001 From: Liang Qi <liang.qi@digia.com> Date: Tue, 7 May 2013 14:21:12 +0200 Subject: [PATCH] Mac: respect the system settings in Full Keyboard Access Because we use TableView as ListView, then only SpinBox, TextField, TextAre and TableView could be selected. Change-Id: I65ca106e60a57d86e029647653ae110fd81edaa4 Reviewed-by: Jens Bache-Wiig <jens.bache-wiig@digia.com> --- .../data/activeFocusOnTab.qml | 8 +- .../activeFocusOnTab/tst_activeFocusOnTab.cpp | 128 +++++++++++++++++- .../data/activefocusontab.qml | 2 + tests/auto/controls/data/tst_button.qml | 4 + tests/auto/controls/data/tst_checkbox.qml | 5 + tests/auto/controls/data/tst_combobox.qml | 4 + tests/auto/controls/data/tst_groupbox.qml | 4 + tests/auto/controls/data/tst_label.qml | 4 + tests/auto/controls/data/tst_progressbar.qml | 4 + tests/auto/controls/data/tst_radiobutton.qml | 5 + tests/auto/controls/data/tst_scrollview.qml | 4 + tests/auto/controls/data/tst_slider.qml | 4 + tests/auto/controls/data/tst_statusbar.qml | 4 + tests/auto/controls/data/tst_tabview.qml | 48 +++---- tests/auto/controls/data/tst_toolbar.qml | 4 + tests/auto/controls/data/tst_toolbutton.qml | 4 + tests/auto/testplugin/testcppmodels.h | 27 ++++ tests/auto/testplugin/testplugin.cpp | 1 + tests/auto/testplugin/testplugin.pro | 2 +- 19 files changed, 237 insertions(+), 29 deletions(-) diff --git a/tests/auto/activeFocusOnTab/data/activeFocusOnTab.qml b/tests/auto/activeFocusOnTab/data/activeFocusOnTab.qml index 5955b61ef..20f1a77f4 100644 --- a/tests/auto/activeFocusOnTab/data/activeFocusOnTab.qml +++ b/tests/auto/activeFocusOnTab/data/activeFocusOnTab.qml @@ -44,8 +44,8 @@ import QtQuick.Controls 1.0 Item { id: main objectName: "main" - width: 800 - height: 600 + width: 400 + height: 800 focus: true Component.onCompleted: button1.focus = true Column { @@ -197,6 +197,10 @@ Item { objectName: "textfield" text: "abc" } + TableView { + id: tableview + objectName: "tableview" + } TextArea { id: textarea objectName: "textarea" diff --git a/tests/auto/activeFocusOnTab/tst_activeFocusOnTab.cpp b/tests/auto/activeFocusOnTab/tst_activeFocusOnTab.cpp index 19d0d194c..6278149ec 100644 --- a/tests/auto/activeFocusOnTab/tst_activeFocusOnTab.cpp +++ b/tests/auto/activeFocusOnTab/tst_activeFocusOnTab.cpp @@ -45,6 +45,8 @@ #include <QtQml/qqmlcontext.h> #include <QtQuick/qquickview.h> #include <QtQuick/private/qquickitem_p.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qpa/qplatformtheme.h> #include "../shared/util.h" #include "../shared/visualtestutil.h" @@ -61,8 +63,14 @@ private slots: void cleanup(); void activeFocusOnTab(); + void activeFocusOnTab2(); private: QQmlEngine engine; + bool qt_tab_all_widgets() { + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + return theme->themeHint(QPlatformTheme::TabAllWidgets).toBool(); + return true; + } }; tst_activeFocusOnTab::tst_activeFocusOnTab() @@ -80,6 +88,9 @@ void tst_activeFocusOnTab::cleanup() void tst_activeFocusOnTab::activeFocusOnTab() { + if (!qt_tab_all_widgets()) + QSKIP("This function doesn't support NOT iterating all."); + QQuickView *window = new QQuickView(0); window->setBaseSize(QSize(800,600)); @@ -215,7 +226,16 @@ void tst_activeFocusOnTab::activeFocusOnTab() QVERIFY(item); QVERIFY(item->hasActiveFocus()); - // Tab: textfield->textarea + // Tab: textfield->tableview + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->rootObject(), "tableview"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // Tab: tableview->textarea key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); QGuiApplication::sendEvent(window, &key); QVERIFY(key.isAccepted()); @@ -224,7 +244,16 @@ void tst_activeFocusOnTab::activeFocusOnTab() QVERIFY(item); QVERIFY(item->hasActiveFocus()); - // BackTab: textarea->textfield + // BackTab: textarea->tableview + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->rootObject(), "tableview"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // BackTab: tableview->textfield key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); QGuiApplication::sendEvent(window, &key); QVERIFY(key.isAccepted()); @@ -422,6 +451,101 @@ void tst_activeFocusOnTab::activeFocusOnTab() delete window; } +void tst_activeFocusOnTab::activeFocusOnTab2() +{ + if (qt_tab_all_widgets()) + QSKIP("This function doesn't support iterating all."); + + QQuickView *window = new QQuickView(0); + window->setBaseSize(QSize(800,600)); + + window->setSource(testFileUrl("activeFocusOnTab.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + // original: spinbox + QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "spinbox"); + QVERIFY(item); + item->forceActiveFocus(); + QVERIFY(item->hasActiveFocus()); + + // Tab: spinbox->textfield + QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->rootObject(), "textfield"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // Tab: textfield->tableview + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->rootObject(), "tableview"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // Tab: tableview->textarea + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->rootObject(), "textarea"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // BackTab: textarea->tableview + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->rootObject(), "tableview"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // BackTab: tableview->textfield + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->rootObject(), "textfield"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // BackTab: textfield->spinbox + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->rootObject(), "spinbox"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // BackTab: spinbox->textarea + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->rootObject(), "textarea"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // BackTab: textarea->tableview + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->rootObject(), "tableview"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + delete window; +} + QTEST_MAIN(tst_activeFocusOnTab) #include "tst_activeFocusOnTab.moc" diff --git a/tests/auto/applicationwindow/data/activefocusontab.qml b/tests/auto/applicationwindow/data/activefocusontab.qml index 4ca3a2506..bd4c48262 100644 --- a/tests/auto/applicationwindow/data/activefocusontab.qml +++ b/tests/auto/applicationwindow/data/activefocusontab.qml @@ -59,6 +59,7 @@ ApplicationWindow { id: sub1 objectName: "sub1" activeFocusOnTab: true + Accessible.role: Accessible.Table width: 100 height: 50 Rectangle { @@ -70,6 +71,7 @@ ApplicationWindow { id: sub2 objectName: "sub2" activeFocusOnTab: true + Accessible.role: Accessible.Table width: 100 height: 50 Rectangle { diff --git a/tests/auto/controls/data/tst_button.qml b/tests/auto/controls/data/tst_button.qml index f949ec6ea..29e2a3f63 100644 --- a/tests/auto/controls/data/tst_button.qml +++ b/tests/auto/controls/data/tst_button.qml @@ -40,6 +40,7 @@ import QtQuick 2.1 import QtTest 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -122,6 +123,9 @@ TestCase { } function test_activeFocusOnTab() { + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/controls/data/tst_checkbox.qml b/tests/auto/controls/data/tst_checkbox.qml index 1c74e34d8..40600d9e3 100644 --- a/tests/auto/controls/data/tst_checkbox.qml +++ b/tests/auto/controls/data/tst_checkbox.qml @@ -40,6 +40,7 @@ import QtQuick 2.1 import QtTest 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -237,6 +238,10 @@ Item { function test_activeFocusOnTab() { checkBox.destroy() wait(0) //QTBUG-30523 so processEvents is called + + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml index 9110eb1cf..c36218a31 100644 --- a/tests/auto/controls/data/tst_combobox.qml +++ b/tests/auto/controls/data/tst_combobox.qml @@ -40,6 +40,7 @@ import QtQuick 2.1 import QtTest 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -144,6 +145,9 @@ TestCase { } function test_activeFocusOnTab() { + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/controls/data/tst_groupbox.qml b/tests/auto/controls/data/tst_groupbox.qml index 12784b48e..5599ca5f3 100644 --- a/tests/auto/controls/data/tst_groupbox.qml +++ b/tests/auto/controls/data/tst_groupbox.qml @@ -41,6 +41,7 @@ import QtQuick 2.1 import QtTest 1.0 import QtQuick.Controls 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -113,6 +114,9 @@ TestCase { } function test_activeFocusOnTab() { + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/controls/data/tst_label.qml b/tests/auto/controls/data/tst_label.qml index a50786913..9b416d6a7 100644 --- a/tests/auto/controls/data/tst_label.qml +++ b/tests/auto/controls/data/tst_label.qml @@ -40,6 +40,7 @@ import QtQuick 2.1 import QtTest 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -59,6 +60,9 @@ TestCase { } function test_activeFocusOnTab() { + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/controls/data/tst_progressbar.qml b/tests/auto/controls/data/tst_progressbar.qml index 3dc7a29ab..7febd6619 100644 --- a/tests/auto/controls/data/tst_progressbar.qml +++ b/tests/auto/controls/data/tst_progressbar.qml @@ -40,6 +40,7 @@ import QtQuick 2.1 import QtTest 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -130,6 +131,9 @@ TestCase { } function test_activeFocusOnTab() { + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/controls/data/tst_radiobutton.qml b/tests/auto/controls/data/tst_radiobutton.qml index 855f8c7a6..7d04c0c36 100644 --- a/tests/auto/controls/data/tst_radiobutton.qml +++ b/tests/auto/controls/data/tst_radiobutton.qml @@ -40,6 +40,7 @@ import QtQuick 2.1 import QtTest 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -190,6 +191,10 @@ Item { function test_activeFocusOnTab() { radioButton.destroy() wait(0) //QTBUG-30523 so processEvents is called + + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/controls/data/tst_scrollview.qml b/tests/auto/controls/data/tst_scrollview.qml index c273c16b7..d5c3e0086 100644 --- a/tests/auto/controls/data/tst_scrollview.qml +++ b/tests/auto/controls/data/tst_scrollview.qml @@ -41,6 +41,7 @@ import QtQuick 2.1 import QtTest 1.0 import QtQuick.Controls 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -114,6 +115,9 @@ TestCase { } function test_activeFocusOnTab() { + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/controls/data/tst_slider.qml b/tests/auto/controls/data/tst_slider.qml index cf9e8db19..7c07ba4cb 100644 --- a/tests/auto/controls/data/tst_slider.qml +++ b/tests/auto/controls/data/tst_slider.qml @@ -40,6 +40,7 @@ import QtQuick 2.1 import QtTest 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -165,6 +166,9 @@ Item { } function test_activeFocusOnTab() { + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/controls/data/tst_statusbar.qml b/tests/auto/controls/data/tst_statusbar.qml index aa8a7d54d..e95e14bbb 100644 --- a/tests/auto/controls/data/tst_statusbar.qml +++ b/tests/auto/controls/data/tst_statusbar.qml @@ -40,6 +40,7 @@ import QtQuick 2.1 import QtTest 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -59,6 +60,9 @@ TestCase { } function test_activeFocusOnTab() { + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/controls/data/tst_tabview.qml b/tests/auto/controls/data/tst_tabview.qml index ad1322658..43c42c99e 100644 --- a/tests/auto/controls/data/tst_tabview.qml +++ b/tests/auto/controls/data/tst_tabview.qml @@ -236,16 +236,16 @@ TestCase { active: true; \ Column { \ objectName: "column1"; \ - property alias button1: _button1; \ - property alias button2: _button2; \ + property alias child1: _child1; \ + property alias child2: _child2; \ anchors.fill: parent; \ - Button { \ - id: _button1; \ - text: "button 1 in Tab1"; \ + TextField { \ + id: _child1; \ + text: "textfile 1 in Tab1"; \ } \ - Button { \ - id: _button2; \ - text: "button 2 in Tab1"; \ + TextField { \ + id: _child2; \ + text: "textfile 2 in Tab1"; \ } \ } \ } \ @@ -255,16 +255,16 @@ TestCase { active: true; \ Column { \ objectName: "column2"; \ - property alias button3: _button3; \ - property alias button4: _button4; \ + property alias child3: _child3; \ + property alias child4: _child4; \ anchors.fill: parent; \ - Button { \ - id: _button3; \ - text: "button 1 in Tab2"; \ + TextField { \ + id: _child3; \ + text: "textfile 1 in Tab2"; \ } \ - Button { \ - id: _button4; \ - text: "button 2 in Tab2"; \ + TextField { \ + id: _child4; \ + text: "textfile 2 in Tab2"; \ } \ } \ } \ @@ -280,10 +280,10 @@ TestCase { var column2 = getColumnItem(tabView.tab2, "column2") verify(column2 !== null) - var button1 = column1.button1 - verify(button1 !== null) - var button3 = column2.button3 - verify(button3 !== null) + var child1 = column1.child1 + verify(child1 !== null) + var child3 = column2.child3 + verify(child3 !== null) var tabbarItem = getTabBarItem(tabView) verify(tabbarItem !== null) @@ -300,7 +300,7 @@ TestCase { waitForRendering(tab1) mouseClick(tab1, tab1.width/2, tab1.height/2) - verify(button1.activeFocus) + verify(child1.activeFocus) var tab2 = mouseareas[1].parent verify(tab2 !== null) @@ -308,15 +308,15 @@ TestCase { waitForRendering(tab2) mouseClick(tab2, tab2.width/2, tab2.height/2) - verify(button3.activeFocus) + verify(child3.activeFocus) waitForRendering(tab1) mouseClick(tab1, tab1.width/2, tab1.height/2) - verify(button1.activeFocus) + verify(child1.activeFocus) waitForRendering(tab2) mouseClick(tab2, tab2.width/2, tab2.height/2) - verify(button3.activeFocus) + verify(child3.activeFocus) tabView.destroy() } diff --git a/tests/auto/controls/data/tst_toolbar.qml b/tests/auto/controls/data/tst_toolbar.qml index fc545bd5e..97106ff4b 100644 --- a/tests/auto/controls/data/tst_toolbar.qml +++ b/tests/auto/controls/data/tst_toolbar.qml @@ -40,6 +40,7 @@ import QtQuick 2.1 import QtTest 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -59,6 +60,9 @@ TestCase { } function test_activeFocusOnTab() { + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/controls/data/tst_toolbutton.qml b/tests/auto/controls/data/tst_toolbutton.qml index 9ce7b1434..b02587430 100644 --- a/tests/auto/controls/data/tst_toolbutton.qml +++ b/tests/auto/controls/data/tst_toolbutton.qml @@ -40,6 +40,7 @@ import QtQuick 2.1 import QtTest 1.0 +import QtQuickControlsTests 1.0 Item { id: container @@ -72,6 +73,9 @@ TestCase { } function test_activeFocusOnTab() { + if (!SystemInfo.tabAllWidgets) + skip("This function doesn't support NOT iterating all.") + var test_control = 'import QtQuick 2.1; \ import QtQuick.Controls 1.0; \ Item { \ diff --git a/tests/auto/testplugin/testcppmodels.h b/tests/auto/testplugin/testcppmodels.h index 8a1b686ea..e495af0bc 100644 --- a/tests/auto/testplugin/testcppmodels.h +++ b/tests/auto/testplugin/testcppmodels.h @@ -44,6 +44,33 @@ #include <QAbstractListModel> #include <QVariant> +#include <QtGui/private/qguiapplication_p.h> +#include <qpa/qplatformtheme.h> +#include <QtQml/QQmlEngine> +#include <QtQml/QJSEngine> + +class SystemInfo : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool tabAllWidgets READ tabAllWidgets CONSTANT) + +public: + SystemInfo() {} + bool tabAllWidgets() const { + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + return theme->themeHint(QPlatformTheme::TabAllWidgets).toBool(); + return true; + } +}; + +static QObject *systeminfo_provider(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + + SystemInfo *systemInfo = new SystemInfo(); + return systemInfo; +} class TestObject : public QObject { diff --git a/tests/auto/testplugin/testplugin.cpp b/tests/auto/testplugin/testplugin.cpp index d0eaa8586..df8e6e1cd 100644 --- a/tests/auto/testplugin/testplugin.cpp +++ b/tests/auto/testplugin/testplugin.cpp @@ -51,6 +51,7 @@ void TestPlugin::registerTypes(const char *uri) // cpp models qmlRegisterType<TestObject>(uri, 1, 0, "TestObject"); qmlRegisterType<TestItemModel>(uri, 1, 0, "TestItemModel"); + qmlRegisterSingletonType<SystemInfo>(uri, 1, 0, "SystemInfo", systeminfo_provider); } void TestPlugin::initializeEngine(QQmlEngine *engine, const char * /*uri*/) diff --git a/tests/auto/testplugin/testplugin.pro b/tests/auto/testplugin/testplugin.pro index d25d3a9f1..3800a80eb 100644 --- a/tests/auto/testplugin/testplugin.pro +++ b/tests/auto/testplugin/testplugin.pro @@ -3,7 +3,7 @@ CONFIG += plugin TARGET = testplugin TARGETPATH = QtQuickControlsTests -QT += qml quick +QT += qml quick core-private gui-private qtHaveModule(widgets) { QT += widgets } -- GitLab