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