diff options
author | Doris Verria <doris.verria@qt.io> | 2024-02-21 15:28:18 +0100 |
---|---|---|
committer | Doris Verria <doris.verria@qt.io> | 2024-05-02 09:59:36 +0200 |
commit | 3f3787a6b4f54f2603598e49eeebb58532aa2afa (patch) | |
tree | e29566feda11d0bb99d9db88e74f1bed6f442e9b /tests | |
parent | 0cb899e21a26200a2a21ecc6868f77db5733134f (diff) |
Give focus to parent window when focus chain wraps
If the focus chain wraps when tabbing (prev == last && next == first),
we need to give a chance to the parent window to gain focus so that
the focus can be passed to the next/prev object in the focus chain.
To give focus to the prev/next target, override new virtual
setFocusToTarget for QQuickWindowPrivate.
Task-number: QTBUG-121789
Change-Id: Ibe91af53ca622e7fe2b7fc662a95f1a5d7cb479b
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/quick/qquickitem2/CMakeLists.txt | 5 | ||||
-rw-r--r-- | tests/auto/quick/qquickitem2/data/embedded.qml | 30 | ||||
-rw-r--r-- | tests/auto/quick/qquickitem2/tst_qquickitem.cpp | 73 |
3 files changed, 108 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickitem2/CMakeLists.txt b/tests/auto/quick/qquickitem2/CMakeLists.txt index 7034acc184..6b115efd2e 100644 --- a/tests/auto/quick/qquickitem2/CMakeLists.txt +++ b/tests/auto/quick/qquickitem2/CMakeLists.txt @@ -37,6 +37,11 @@ qt_internal_add_test(tst_qquickitem2 ## Scopes: ##################################################################### +qt_internal_extend_target(tst_qquickitem2 CONDITION TARGET Qt::Widgets + LIBRARIES + Qt::Widgets +) + qt_internal_extend_target(tst_qquickitem2 CONDITION ANDROID OR IOS DEFINES QT_QMLTEST_DATADIR=":/data" diff --git a/tests/auto/quick/qquickitem2/data/embedded.qml b/tests/auto/quick/qquickitem2/data/embedded.qml new file mode 100644 index 0000000000..a9cf115699 --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/embedded.qml @@ -0,0 +1,30 @@ +import QtQuick + +Rectangle { + width: 300 + height: 300 + + Column { + anchors.fill: parent + anchors.rightMargin: 2 + anchors.leftMargin: 2 + anchors.topMargin: 10 + spacing: 20 + Rectangle { + objectName: "rect1" + width: parent.width + height: 30 + border.width: 1 + border.color: activeFocus ? "blue" : "black" + focusPolicy: Qt.TabFocus + } + Rectangle { + objectName: "rect2" + width: parent.width + height: 30 + border.width: 1 + border.color: activeFocus ? "blue" : "black" + focusPolicy: Qt.TabFocus + } + } +} diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index 57deb0a46a..267be73ec9 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -23,6 +23,11 @@ #include <QtQuickTestUtils/private/viewtestutils_p.h> #include <QtQuickTestUtils/private/platforminputcontext_p.h> #include <QtTest/private/qpropertytesthelper_p.h> +#ifdef QT_WIDGETS_LIB +#include <QtWidgets/qwidget.h> +#include <QtWidgets/qboxlayout.h> +#include <QtWidgets/qlineedit.h> +#endif using namespace QQuickVisualTestUtils; @@ -134,6 +139,10 @@ private slots: void lastFocusChangeReason(); void focusInScopeChanges(); +#ifdef QT_WIDGETS_LIB + void embeddedInWidgetsFocus(); +#endif + private: QQmlEngine engine; bool qt_tab_all_widgets() { @@ -4431,6 +4440,70 @@ void tst_QQuickItem::focusInScopeChanges() QVERIFY(textInput->hasActiveFocus()); } +#ifdef QT_WIDGETS_LIB +void tst_QQuickItem::embeddedInWidgetsFocus() +{ + QWidget root; + QVBoxLayout *layout = new QVBoxLayout(&root); + + QLineEdit *lineEdit1 = new QLineEdit(&root); + lineEdit1->setFocusPolicy(Qt::FocusPolicy::TabFocus); + + QQuickView *quickView = new QQuickView; + quickView->setSource(testFileUrl("embedded.qml")); + QWidget *container = QWidget::createWindowContainer(quickView, &root); + container->setMinimumSize(quickView->size()); + container->setFocusPolicy(Qt::TabFocus); + + QLineEdit *lineEdit2 = new QLineEdit(&root); + lineEdit2->setFocusPolicy(Qt::FocusPolicy::TabFocus); + + layout->addWidget(lineEdit1); + layout->addWidget(container); + layout->addWidget(lineEdit2); + + QQuickItem *rect1 = findItem<QQuickItem>(quickView->rootObject(), "rect1"); + QQuickItem *rect2 = findItem<QQuickItem>(quickView->rootObject(), "rect2"); + QVERIFY(rect1); + QVERIFY(rect2); + + root.show(); + QTRY_VERIFY(root.isVisible()); + QVERIFY(QTest::qWaitForWindowExposed(&root)); + QVERIFY(QTest::qWaitForWindowFocused(root.windowHandle())); + + lineEdit1->setFocus(); + QTRY_VERIFY(lineEdit1->hasFocus()); + + // Tab forward + QTest::keyClick(QGuiApplication::focusWindow(), Qt::Key_Tab); + QTRY_VERIFY(container->hasFocus()); + QVERIFY(QTest::qWaitForWindowFocused(quickView)); + QVERIFY(rect1->hasActiveFocus()); + + QTest::keyClick(QGuiApplication::focusWindow(), Qt::Key_Tab); + QTRY_VERIFY(rect2->hasActiveFocus()); + + QTest::keyClick(QGuiApplication::focusWindow(), Qt::Key_Tab); + QVERIFY(QTest::qWaitForWindowFocused(root.windowHandle())); + QVERIFY(lineEdit2->hasFocus()); + QVERIFY(!rect2->hasActiveFocus()); + + // Tab backwards + QTest::keyClick(QGuiApplication::focusWindow(), Qt::Key_Tab, Qt::ShiftModifier); + QTRY_VERIFY(container->hasFocus()); + QVERIFY(QTest::qWaitForWindowFocused(quickView)); + QVERIFY(rect2->hasActiveFocus()); + + QTest::keyClick(QGuiApplication::focusWindow(), Qt::Key_Tab, Qt::ShiftModifier); + QVERIFY(rect1->hasActiveFocus()); + + QTest::keyClick(QGuiApplication::focusWindow(), Qt::Key_Tab, Qt::ShiftModifier); + QVERIFY(QTest::qWaitForWindowFocused(root.windowHandle())); + QVERIFY(lineEdit1->hasFocus()); +} +#endif + QTEST_MAIN(tst_QQuickItem) #include "tst_qquickitem.moc" |