aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquicktextinput
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-07-22 09:56:04 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2021-07-23 21:02:45 +0200
commitbbcbb7c78f2f07e6c5e380ec5c018ac2a7abf292 (patch)
treed09275a89f3924935b2acdf640209af17cf8cb3a /tests/auto/quick/qquicktextinput
parent66a5167dab35aedf1c7bef3e0f8deea903c12a5e (diff)
Pass the focus reason through to the control on mouse press
Otherwise, a TextInput item will always receive OtherFocusReason when clicking into it. Add a test that simulates focus changes with mouse and keys, records the incoming focus events and verifies the correct focus reason is set in the event. Qt Quick provides no mechanism to access the focus reason from within QML (onActiveFocusChange only has a bool parameter, the focusReason property exists only in QtQuickControl). Task-number: QTBUG-75862 Pick-to: 6.2 6.1 5.15 Change-Id: Ifea95c7ef2ac88c6c8e8bbdc8d2dbe5205ff922e Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto/quick/qquicktextinput')
-rw-r--r--tests/auto/quick/qquicktextinput/data/focusReason.qml39
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp80
2 files changed, 119 insertions, 0 deletions
diff --git a/tests/auto/quick/qquicktextinput/data/focusReason.qml b/tests/auto/quick/qquicktextinput/data/focusReason.qml
new file mode 100644
index 0000000000..7ac913d363
--- /dev/null
+++ b/tests/auto/quick/qquicktextinput/data/focusReason.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.2
+
+Rectangle {
+ width: 400
+ height: 400
+
+ Column {
+ spacing: 5
+ TextInput {
+ id: first
+ objectName: "first"
+ width: 100
+ Rectangle { anchors.fill: parent; color: parent.activeFocus ? "red" : "blue"; opacity: 0.3 }
+ KeyNavigation.backtab: third
+ KeyNavigation.tab: second
+ KeyNavigation.down: second
+ }
+ TextInput {
+ id: second
+ objectName: "second"
+ width: 100
+ Rectangle { anchors.fill: parent; color: parent.activeFocus ? "red" : "blue"; opacity: 0.3 }
+ KeyNavigation.up: first
+ KeyNavigation.backtab: first
+ KeyNavigation.tab: third
+ }
+ TextInput {
+ objectName: "third"
+ id: third
+ width: 100
+ Rectangle { anchors.fill: parent; color: parent.activeFocus ? "red" : "blue"; opacity: 0.3 }
+ KeyNavigation.backtab: second
+ KeyNavigation.tab: first
+ }
+ Component.onCompleted: {
+ first.focus = true
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index eada215781..f61be67107 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -239,6 +239,8 @@ private slots:
void QTBUG_77814_InsertRemoveNoSelection();
void checkCursorDelegateWhenPaddingChanged();
+
+ void focusReason();
private:
void simulateKeys(QWindow *window, const QList<Key> &keys);
#if QT_CONFIG(shortcut)
@@ -7053,6 +7055,84 @@ void tst_qquicktextinput::checkCursorDelegateWhenPaddingChanged()
QCOMPARE(cursorDelegate->y(), textInput->topPadding());
}
+/*!
+ Verifies that TextInput items get focus in/out events with the
+ correct focus reason set.
+
+ Up and Down keys translates to Backtab and Tab focus reasons.
+
+ See QTBUG-75862.
+*/
+void tst_qquicktextinput::focusReason()
+{
+ QQuickView view;
+ view.setSource(testFileUrl("focusReason.qml"));
+
+ QQuickTextInput *first = view.rootObject()->findChild<QQuickTextInput *>("first");
+ QQuickTextInput *second = view.rootObject()->findChild<QQuickTextInput *>("second");
+ QQuickTextInput *third = view.rootObject()->findChild<QQuickTextInput *>("third");
+ QVERIFY(first && second && third);
+
+ class FocusEventFilter : public QObject
+ {
+ public:
+ using QObject::QObject;
+
+ QHash<QObject*, Qt::FocusReason> lastFocusReason;
+ protected:
+ bool eventFilter(QObject *o, QEvent *e)
+ {
+ if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut) {
+ QFocusEvent *fe = static_cast<QFocusEvent*>(e);
+ lastFocusReason[o] = fe->reason();
+ }
+ return QObject::eventFilter(o, e);
+ }
+ } eventFilter;
+ first->installEventFilter(&eventFilter);
+ second->installEventFilter(&eventFilter);
+ third->installEventFilter(&eventFilter);
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ QCOMPARE(qApp->focusObject(), first);
+ // on some platforms we don't get ActiveWindowFocusReason; tolerate this,
+ // it's not what we are testing in this test
+ if (eventFilter.lastFocusReason[first] != Qt::ActiveWindowFocusReason) {
+ QEXPECT_FAIL("", qPrintable(QString("No window activation event on the %1 platform")
+ .arg(QGuiApplication::platformName())),
+ Continue);
+ }
+ QCOMPARE(eventFilter.lastFocusReason[first], Qt::ActiveWindowFocusReason);
+
+ QTest::mouseClick(&view, Qt::LeftButton, {},
+ (second->boundingRect().center() + second->position()).toPoint());
+ QTRY_COMPARE(qApp->focusObject(), second);
+ QCOMPARE(eventFilter.lastFocusReason[first], Qt::MouseFocusReason);
+ QCOMPARE(eventFilter.lastFocusReason[second], Qt::MouseFocusReason);
+
+ QTest::keyClick(&view, Qt::Key_Tab);
+ QCOMPARE(qApp->focusObject(), third);
+ QCOMPARE(eventFilter.lastFocusReason[second], Qt::TabFocusReason);
+ QCOMPARE(eventFilter.lastFocusReason[third], Qt::TabFocusReason);
+
+ QTest::keyClick(&view, Qt::Key_Backtab);
+ QCOMPARE(qApp->focusObject(), second);
+ QCOMPARE(eventFilter.lastFocusReason[third], Qt::BacktabFocusReason);
+ QCOMPARE(eventFilter.lastFocusReason[second], Qt::BacktabFocusReason);
+
+ QTest::keyClick(&view, Qt::Key_Up);
+ QCOMPARE(qApp->focusObject(), first);
+ QCOMPARE(eventFilter.lastFocusReason[second], Qt::BacktabFocusReason);
+ QCOMPARE(eventFilter.lastFocusReason[first], Qt::BacktabFocusReason);
+
+ QTest::keyClick(&view, Qt::Key_Down);
+ QCOMPARE(qApp->focusObject(), second);
+ QCOMPARE(eventFilter.lastFocusReason[second], Qt::TabFocusReason);
+ QCOMPARE(eventFilter.lastFocusReason[first], Qt::TabFocusReason);
+}
+
QTEST_MAIN(tst_qquicktextinput)
#include "tst_qquicktextinput.moc"