diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2022-08-24 15:03:26 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-08-30 21:05:26 +0000 |
commit | 2b42c90c3773d3479a9b7d8452087828189573e9 (patch) | |
tree | fb9caf6116d6e304fffad76e9b2fa26d5c670923 /tests | |
parent | 942331e49bbbd0ef0a439a019296cae227149981 (diff) |
Fix TextInput and TextField mouse/touch selection fallback behavior
We tried to make default behavior depend on the import version; but in
Controls that does not work well, because the QQuickTextField instance
is created in a style-specific QML file that does not use the same
import version that the user is using. So we work around it by adding
support for a Controls-specific env var to revert to pre-6.4 behavior.
Adding the autotest proves that the fallback was broken a different
way too: we didn't check selectByTouchDrag in all the necessary places.
Amends 650342de792e0ab37ce8bac8ccde21ab9b96b2c9
[ChangeLog][Controls][TextField] The selectByMouse property is now
enabled by default, but no longer enables selecting by dragging your
finger across text on a touchscreen. Platforms that are optimized for
touchscreens normally use special text-selection handles, which interact
with Qt via QInputMethod. You can opt out of the behavior change by
setting the environment variable
QT_QUICK_CONTROLS_TEXT_SELECTION_BEHAVIOR=old.
Task-number: QTBUG-10684
Task-number: QTBUG-38934
Task-number: QTBUG-101205
Change-Id: If1c1d6bd9c538f52022ae06d5252d178a1ae5a38
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
(cherry picked from commit 42848bda5cb7ed92781cbbd536005af617e91020)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tests')
6 files changed, 166 insertions, 0 deletions
diff --git a/tests/auto/quickcontrols2/CMakeLists.txt b/tests/auto/quickcontrols2/CMakeLists.txt index ce391638f4..e2b37a6202 100644 --- a/tests/auto/quickcontrols2/CMakeLists.txt +++ b/tests/auto/quickcontrols2/CMakeLists.txt @@ -31,6 +31,7 @@ add_subdirectory(qquickninepatchimage) add_subdirectory(qquickpopup) add_subdirectory(qquickstyle) add_subdirectory(qquicktextarea) +add_subdirectory(qquicktextfield) add_subdirectory(qquickuniversalstyle) add_subdirectory(qquickuniversalstyleconf) add_subdirectory(revisions) diff --git a/tests/auto/quickcontrols2/qquicktextfield/CMakeLists.txt b/tests/auto/quickcontrols2/qquicktextfield/CMakeLists.txt new file mode 100644 index 0000000000..953e75d9d8 --- /dev/null +++ b/tests/auto/quickcontrols2/qquicktextfield/CMakeLists.txt @@ -0,0 +1,46 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +##################################################################### +## tst_qquicktextfield Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquicktextfield + SOURCES + tst_qquicktextfield.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquicktextfield CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquicktextfield CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquicktextfield/data/mouseselection_default.qml b/tests/auto/quickcontrols2/qquicktextfield/data/mouseselection_default.qml new file mode 100644 index 0000000000..2bcaf2abd4 --- /dev/null +++ b/tests/auto/quickcontrols2/qquicktextfield/data/mouseselection_default.qml @@ -0,0 +1,7 @@ +import QtQuick.Controls + +TextField { + width: 400 + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" +} + diff --git a/tests/auto/quickcontrols2/qquicktextfield/data/mouseselection_old_default.qml b/tests/auto/quickcontrols2/qquicktextfield/data/mouseselection_old_default.qml new file mode 100644 index 0000000000..0eb774a322 --- /dev/null +++ b/tests/auto/quickcontrols2/qquicktextfield/data/mouseselection_old_default.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls 6.3 + +TextField { + width: 400 + text: "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ" +} diff --git a/tests/auto/quickcontrols2/qquicktextfield/data/mouseselection_old_overridden.qml b/tests/auto/quickcontrols2/qquicktextfield/data/mouseselection_old_overridden.qml new file mode 100644 index 0000000000..0e357e032f --- /dev/null +++ b/tests/auto/quickcontrols2/qquicktextfield/data/mouseselection_old_overridden.qml @@ -0,0 +1,8 @@ +import QtQuick +import QtQuick.Controls 6.3 + +TextField { + width: 400 + selectByMouse: true + text: "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ" +} diff --git a/tests/auto/quickcontrols2/qquicktextfield/tst_qquicktextfield.cpp b/tests/auto/quickcontrols2/qquicktextfield/tst_qquicktextfield.cpp new file mode 100644 index 0000000000..c04a9ffd3e --- /dev/null +++ b/tests/auto/quickcontrols2/qquicktextfield/tst_qquicktextfield.cpp @@ -0,0 +1,97 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtTest/qtesttouch.h> + +#include <QtGui/qfontmetrics.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qpa/qplatformintegration.h> +#include <QtGui/qtestsupport_gui.h> +#include <QtQuick/qquickview.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> +#include <QtQuickControlsTestUtils/private/qtest_quickcontrols_p.h> + +class tst_QQuickTextField : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_QQuickTextField(); + +private slots: + void initTestCase() override; + void touchscreenDoesNotSelect_data(); + void touchscreenDoesNotSelect(); + +private: + QScopedPointer<QPointingDevice> touchDevice = QScopedPointer<QPointingDevice>(QTest::createTouchDevice()); +}; + +tst_QQuickTextField::tst_QQuickTextField() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_QQuickTextField::initTestCase() +{ + QQmlDataTest::initTestCase(); + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); +} + +void tst_QQuickTextField::touchscreenDoesNotSelect_data() +{ + QTest::addColumn<QUrl>("src"); + QTest::addColumn<bool>("setEnv"); + QTest::addColumn<bool>("selectByMouse"); + QTest::addColumn<bool>("selectByTouch"); + QTest::newRow("new default") << testFileUrl("mouseselection_default.qml") << false << true << false; +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + QTest::newRow("putenv") << testFileUrl("mouseselection_default.qml") << true << false << false; + QTest::newRow("old_import") << testFileUrl("mouseselection_old_default.qml") << false << true << false; + QTest::newRow("old+putenv") << testFileUrl("mouseselection_old_default.qml") << true << false << false; + QTest::newRow("old+putenv+selectByMouse") << testFileUrl("mouseselection_old_overridden.qml") << true << true << true; +#endif +} + +void tst_QQuickTextField::touchscreenDoesNotSelect() +{ + QFETCH(QUrl, src); + QFETCH(bool, setEnv); + QFETCH(bool, selectByMouse); + QFETCH(bool, selectByTouch); + + if (setEnv) + qputenv("QT_QUICK_CONTROLS_TEXT_SELECTION_BEHAVIOR", "old"); + else + qunsetenv("QT_QUICK_CONTROLS_TEXT_SELECTION_BEHAVIOR"); + + QQuickView window; + QVERIFY(QQuickTest::showView(window, src)); + + QQuickTextField *textField = qobject_cast<QQuickTextField *>(window.rootObject()); + QVERIFY(textField != nullptr); + QCOMPARE(textField->selectByMouse(), selectByMouse); + textField->setSelectByMouse(true); // enable selection with pre-6.4 import version + QVERIFY(textField->selectedText().isEmpty()); + + if (selectByMouse) { + // press-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = QFontMetrics(textField->font()).height() / 2; + QTest::touchEvent(&window, touchDevice.data()).press(0, QPoint(x1,y), &window); + QTest::touchEvent(&window, touchDevice.data()).move(0, QPoint(x2,y), &window); + QTest::touchEvent(&window, touchDevice.data()).release(0, QPoint(x2,y), &window); + QQuickTouchUtils::flush(&window); + // if the env var is set, fall back to old behavior: touch swipe _does_ select text if selectByMouse is true + QCOMPARE(textField->selectedText().isEmpty(), !selectByTouch); + } +} + +QTEST_QUICKCONTROLS_MAIN(tst_QQuickTextField) + +#include "tst_qquicktextfield.moc" |