From f4d5939ad613fda69aa750139ef929fac18b97ae Mon Sep 17 00:00:00 2001 From: Wang Chuan Date: Fri, 13 Dec 2019 21:50:03 +0800 Subject: QQuickToolTip: prevent closing after invisible tooltip created Since all items using ToolTip attached property share the same ToolTip item, a dynamically created invisible Tooltip may unexpectedly close the current visible ToolTip. Fix this issue by checking the parent of ToolTip when trying to close it Fixes: QTBUG-78202 Change-Id: I0f6558040c6b8bf22240b0c94af912a43d525ed9 Reviewed-by: Richard Moe Gustavsen --- src/quicktemplates2/qquicktooltip.cpp | 5 ++-- .../auto/qquickpopup/data/invisibleToolTipOpen.qml | 28 ++++++++++++++++++++++ tests/auto/qquickpopup/tst_qquickpopup.cpp | 28 ++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 tests/auto/qquickpopup/data/invisibleToolTipOpen.qml diff --git a/src/quicktemplates2/qquicktooltip.cpp b/src/quicktemplates2/qquicktooltip.cpp index 9ea0160e..9d733c94 100644 --- a/src/quicktemplates2/qquicktooltip.cpp +++ b/src/quicktemplates2/qquicktooltip.cpp @@ -557,8 +557,9 @@ void QQuickToolTipAttached::hide() QQuickToolTip *tip = d->instance(false); if (!tip) return; - - tip->close(); + // check the parent item to prevent unexpectedly closing tooltip by new created invisible tooltip + if (parent() == tip->parentItem()) + tip->close(); } QT_END_NAMESPACE diff --git a/tests/auto/qquickpopup/data/invisibleToolTipOpen.qml b/tests/auto/qquickpopup/data/invisibleToolTipOpen.qml new file mode 100644 index 00000000..2e58bb97 --- /dev/null +++ b/tests/auto/qquickpopup/data/invisibleToolTipOpen.qml @@ -0,0 +1,28 @@ +import QtQuick 2.13 +import QtQuick.Window 2.13 +import QtQuick.Controls 2.13 + +Window { + width: 400 + height: 400 + property alias mouseArea: mouseArea + property alias loader: loader + MouseArea { + id: mouseArea + property bool isToolTipVisible: false + width: 200 + height: 200 + hoverEnabled: true + ToolTip.text: "static tooltip" + ToolTip.visible: containsMouse + ToolTip.onVisibleChanged: isToolTipVisible = ToolTip.visible + } + Loader { + id: loader + active: false + sourceComponent: Rectangle { + ToolTip.text: "dynamic tooltip" + ToolTip.visible: false + } + } +} diff --git a/tests/auto/qquickpopup/tst_qquickpopup.cpp b/tests/auto/qquickpopup/tst_qquickpopup.cpp index e852a61e..f55d42bc 100644 --- a/tests/auto/qquickpopup/tst_qquickpopup.cpp +++ b/tests/auto/qquickpopup/tst_qquickpopup.cpp @@ -93,6 +93,7 @@ private slots: void countChanged(); void toolTipCrashOnClose(); void setOverlayParentToNull(); + void invisibleToolTipOpen(); }; void tst_QQuickPopup::initTestCase() @@ -1299,6 +1300,33 @@ void tst_QQuickPopup::setOverlayParentToNull() // While nullifying the overlay parent doesn't make much sense, it shouldn't crash. } +void tst_QQuickPopup::invisibleToolTipOpen() +{ + QQuickApplicationHelper helper(this, "invisibleToolTipOpen.qml"); + + QQuickWindow *window = helper.window; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickItem *mouseArea = qvariant_cast(window->property("mouseArea")); + QVERIFY(mouseArea); + QObject *loader = qvariant_cast(window->property("loader")); + QVERIFY(loader); + + QTest::mouseMove(window, QPoint(mouseArea->width() / 2, mouseArea->height() / 2)); + QTRY_VERIFY(mouseArea->property("isToolTipVisible").toBool()); + + QSignalSpy componentLoadedSpy(loader, SIGNAL(loaded())); + QVERIFY(componentLoadedSpy.isValid()); + + loader->setProperty("active", true); + QTRY_COMPARE(componentLoadedSpy.count(), 1); + + QTRY_VERIFY(mouseArea->property("isToolTipVisible").toBool()); +} + QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup) #include "tst_qquickpopup.moc" -- cgit v1.2.3 From 7be5d463e25218a2987d6c1735fd81bc226b29b6 Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Thu, 9 Jan 2020 10:28:05 +0200 Subject: Add changes file for Qt 5.14.1 + 8ee511bcd9f1376e9995ab3f30f6415ad60b7c05 Doc: Fix qdoc warnings + 463898f0765b83f6c391f6802a0ee06796f9f6d2 Respect user-set Accessible.name + 75b6ef710cddbf9395df35650438f0feb57ec076 SplitView: fix hoverable child items breaking handle hover state + aaec25a798352fc222f86ab3b299384575f51dc8 StackView: fix crash when recursively removing items + cb1c3528078659c297fb12ea6914978cec1d2614 ComboBox: change currentIndex (if applicable) when focus is lost + 06162b3712b6ff2e25e1b20a139fe5c42e95b123 StackView: fix an issue where the current item was hidden + bcdd38074be6828db41396bd3c0ec601993ed59b clang-tidy: fix cppcoreguidelines-pro-type-member-init + c23697e40881491ea218898bec08fb33dd7f5331 clang-tidy: fix readability-const-return-type + 0592dc1a4b4a16faeb1b622f10d56e77dba15776 Bump version + 090eab86b05478572485b3086c087a846fbae7fd Add binary compatibility file for qtquickcontrols2 Change-Id: Iab397951aac43f5581cbf27a09daf8233f28b2f4 Reviewed-by: Richard Moe Gustavsen --- dist/changes-5.14.1 | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 dist/changes-5.14.1 diff --git a/dist/changes-5.14.1 b/dist/changes-5.14.1 new file mode 100644 index 00000000..e12ea637 --- /dev/null +++ b/dist/changes-5.14.1 @@ -0,0 +1,29 @@ +Qt 5.14.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.14.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.14 series is binary compatible with the 5.13.x series. +Applications compiled for 5.13 will continue to run with 5.14. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - StackView: + * [QTBUG-80353] fixed crash when recursively removing items. + * [QTBUG-57267] fix an issue where the current item became hidden. + + - SplitView: + * [QTBUG-79846] fixed hoverable child items breaking handle hover state. -- cgit v1.2.3 From a2443f0a34da85de014b9507926c4ac415543b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 23 Jan 2020 13:48:04 +0100 Subject: Blacklist tst_QQuickMenu::popup on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It relies on moving the cursor. Task-number: QTBUG-76312 Change-Id: I317083b974d3e9e8d6d616dc3248ee64e0f36021 Reviewed-by: Morten Johan Sørvig --- tests/auto/qquickmenu/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/auto/qquickmenu/BLACKLIST diff --git a/tests/auto/qquickmenu/BLACKLIST b/tests/auto/qquickmenu/BLACKLIST new file mode 100644 index 00000000..71d96dfd --- /dev/null +++ b/tests/auto/qquickmenu/BLACKLIST @@ -0,0 +1,2 @@ +[popup] +macos # Can't control cursor (QTBUG-76312) -- cgit v1.2.3 From 28610e13e453c33d7118834a0effb7ac87427ffe Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 16 Jan 2020 10:22:39 +0100 Subject: Look for the fallback style in all of the style paths Fixes: QTBUG-81216 Change-Id: I9d3efeec7f9ec2beda24ff74e39d04104f5eb967 Reviewed-by: BogDan Vatra Reviewed-by: Richard Moe Gustavsen --- src/quickcontrols2/qquickstyle.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/quickcontrols2/qquickstyle.cpp b/src/quickcontrols2/qquickstyle.cpp index 7a3359ef..707e4730 100644 --- a/src/quickcontrols2/qquickstyle.cpp +++ b/src/quickcontrols2/qquickstyle.cpp @@ -384,7 +384,13 @@ void QQuickStylePrivate::init(const QUrl &baseUrl) spec->resolve(baseUrl); if (!spec->fallbackStyle.isEmpty()) { - QString fallbackStyle = spec->findStyle(QQmlFile::urlToLocalFileOrQrc(baseUrl), spec->fallbackStyle); + QString fallbackStyle; + const QStringList stylePaths = QQuickStylePrivate::stylePaths(); + for (const QString &path : stylePaths) { + fallbackStyle = spec->findStyle(path, spec->fallbackStyle); + if (!fallbackStyle.isEmpty()) + break; + } if (fallbackStyle.isEmpty()) { if (spec->fallbackStyle.compare(QStringLiteral("Default")) != 0) { qWarning() << "ERROR: unable to locate fallback style" << spec->fallbackStyle; -- cgit v1.2.3 From 20b9437d54b16abfdd7528868dea2a6c6de0c349 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Fri, 10 Jan 2020 14:10:30 +0100 Subject: set placeholderText by default, not text Task-number: QDS-456 Change-Id: I05b7ce9efab851b99d12ba272a79bf9ba4443398 Reviewed-by: Thomas Hartmann Reviewed-by: Mitch Curtis --- src/imports/controls/designer/qtquickcontrols2.metainfo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/imports/controls/designer/qtquickcontrols2.metainfo b/src/imports/controls/designer/qtquickcontrols2.metainfo index 9e6030b1..d27f1b90 100644 --- a/src/imports/controls/designer/qtquickcontrols2.metainfo +++ b/src/imports/controls/designer/qtquickcontrols2.metainfo @@ -443,7 +443,7 @@ MetaInfo { version: "2.0" requiredImport: "QtQuick.Controls" - Property { name: "text"; type: "binding"; value: "qsTr(\"Text Area\")" } + Property { name: "placeholderText"; type: "binding"; value: "qsTr(\"Text Area\")" } } } @@ -458,7 +458,7 @@ MetaInfo { version: "2.0" requiredImport: "QtQuick.Controls" - Property { name: "text"; type: "binding"; value: "qsTr(\"Text Field\")" } + Property { name: "placeholderText"; type: "binding"; value: "qsTr(\"Text Field\")" } } } -- cgit v1.2.3 From c5c945006244b6bf5189f1949a009f70ebd51d7a Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 27 Jan 2020 10:58:50 +0100 Subject: Doc: fix RangeSlider errors When the RangeSlider was copied into another file as a child item, it would produce errors about first and second being undefined. Change-Id: I0ecc9f6830509183a1b2b35e3faed5f06e78a0ef Fixes: QTBUG-80970 Reviewed-by: Shawn Rutledge --- .../controls/doc/snippets/qtquickcontrols2-rangeslider-custom.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/imports/controls/doc/snippets/qtquickcontrols2-rangeslider-custom.qml b/src/imports/controls/doc/snippets/qtquickcontrols2-rangeslider-custom.qml index 1c5db214..b8510ddd 100644 --- a/src/imports/controls/doc/snippets/qtquickcontrols2-rangeslider-custom.qml +++ b/src/imports/controls/doc/snippets/qtquickcontrols2-rangeslider-custom.qml @@ -54,22 +54,22 @@ RangeSlider { } first.handle: Rectangle { - x: control.leftPadding + first.visualPosition * (control.availableWidth - width) + x: control.leftPadding + control.first.visualPosition * (control.availableWidth - width) y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 26 implicitHeight: 26 radius: 13 - color: first.pressed ? "#f0f0f0" : "#f6f6f6" + color: control.first.pressed ? "#f0f0f0" : "#f6f6f6" border.color: "#bdbebf" } second.handle: Rectangle { - x: control.leftPadding + second.visualPosition * (control.availableWidth - width) + x: control.leftPadding + control.second.visualPosition * (control.availableWidth - width) y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 26 implicitHeight: 26 radius: 13 - color: second.pressed ? "#f0f0f0" : "#f6f6f6" + color: control.second.pressed ? "#f0f0f0" : "#f6f6f6" border.color: "#bdbebf" } } -- cgit v1.2.3 From 33474ce5f16f418a8f132ba88b8cbd5b5d1edcca Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Tue, 28 Jan 2020 15:11:55 +0000 Subject: Follow QML2_IMPORT_PATH in path search When searching for styles we include QLibraryInfo::Qml2ImportsPath so it makes sense to continue that to also include the runtime QML2_IMPORT_PATH when searching for QQC2 themes. It used to be included, but in 5.14 this behavior changed as a result of 7db4df2deca52a30b4c068abd4683a1720cf281e, so this line is restored. Change-Id: I185b29b323d870fc724e655104eaf42034707738 Reviewed-by: Andy Shaw Reviewed-by: Mitch Curtis --- src/quickcontrols2/qquickstyle.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/quickcontrols2/qquickstyle.cpp b/src/quickcontrols2/qquickstyle.cpp index 707e4730..61632b11 100644 --- a/src/quickcontrols2/qquickstyle.cpp +++ b/src/quickcontrols2/qquickstyle.cpp @@ -128,6 +128,7 @@ static QStringList defaultImportPathList() importPaths += QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath); # endif #endif + importPaths += envPathList("QML2_IMPORT_PATH"); importPaths += QStringLiteral(":/qt-project.org/imports"); importPaths += QCoreApplication::applicationDirPath(); return importPaths; -- cgit v1.2.3 From 1ee1fd16f09e72cbf3460904a1cf6314aa594927 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Sun, 2 Feb 2020 13:42:42 +0100 Subject: Bump version Change-Id: I9edcbf13f4fdd1f268dd71fa2b0c216c88483509 --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 32d4d650..7db332a6 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -5,4 +5,4 @@ DEFINES += QT_NO_FOREACH QT_NO_JAVA_STYLE_ITERATORS QT_NO_LINKED_LIST QQC2_SOURCE_TREE = $$PWD -MODULE_VERSION = 5.14.1 +MODULE_VERSION = 5.14.2 -- cgit v1.2.3 From 91eb563b278ca9c831c444380030c458adbf02f0 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 31 Jan 2020 09:52:16 +0100 Subject: Copy Qt Quick Designer-related files also for static builds Make sure that the 'designer' directory is copied to the build directory, or installed, also for static builds. This reverts the !static condition introduced to fix a build breakage in 01d076d0e81e5 . Anyhow, I couldn't reproduce the original problem (QTBUG-51708), nor is it clear why it was caused by the static build. Fixes: QTBUG-75682 Change-Id: I47af3907e464d4fd9e9965ac28545b7350f450ee Reviewed-by: Qt CI Bot Reviewed-by: Andy Shaw --- src/imports/controls/controls.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imports/controls/controls.pro b/src/imports/controls/controls.pro index 2aeaf9ab..66373d55 100644 --- a/src/imports/controls/controls.pro +++ b/src/imports/controls/controls.pro @@ -19,7 +19,7 @@ SOURCES += \ RESOURCES += \ $$PWD/qtquickcontrols2plugin.qrc -!static: qtConfig(quick-designer): include(designer/designer.pri) +qtConfig(quick-designer): include(designer/designer.pri) include(doc/doc.pri) CONFIG += no_cxx_module install_qml_files builtin_resources qtquickcompiler -- cgit v1.2.3 From b10912ba731144e8c41cbfa35fb1553ad04b2b88 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 3 Feb 2020 12:20:08 +0100 Subject: DialogButtonBox: don't change button text that has been explicitly set If a custom button is declared in a DialogButtonBox, qsTr() will take care of translation, and so we shouldn't touch it. Amends c18c7bd7f9596e5ad3d13876a91203e1ceba2544. Change-Id: I06221002cf850882f5318cf0a3ed86da35274d0c Fixes: QTBUG-81796 Reviewed-by: Andy Shaw --- src/quicktemplates2/qquickdialogbuttonbox.cpp | 7 +- .../data/dialogButtonBoxWithCustomButtons.qml | 75 ++++++++++++++++++++++ tests/auto/translation/tst_translation.cpp | 40 ++++++++++++ 3 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 tests/auto/translation/data/dialogButtonBoxWithCustomButtons.qml diff --git a/src/quicktemplates2/qquickdialogbuttonbox.cpp b/src/quicktemplates2/qquickdialogbuttonbox.cpp index 33b720ed..d448aeed 100644 --- a/src/quicktemplates2/qquickdialogbuttonbox.cpp +++ b/src/quicktemplates2/qquickdialogbuttonbox.cpp @@ -455,8 +455,11 @@ void QQuickDialogButtonBoxPrivate::updateLanguage() qmlAttachedPropertiesObject(button, true)); const auto boxAttachedPrivate = QQuickDialogButtonBoxAttachedPrivate::get(attached); const QPlatformDialogHelper::StandardButton standardButton = boxAttachedPrivate->standardButton; - const QString buttonText = QGuiApplicationPrivate::platformTheme()->standardButtonText(standardButton); - button->setText(QPlatformTheme::removeMnemonics(buttonText)); + // The button might be a custom one with explicitly specified text, so we shouldn't change it in that case. + if (standardButton != QPlatformDialogHelper::NoButton) { + const QString buttonText = QGuiApplicationPrivate::platformTheme()->standardButtonText(standardButton); + button->setText(QPlatformTheme::removeMnemonics(buttonText)); + } } --i; } diff --git a/tests/auto/translation/data/dialogButtonBoxWithCustomButtons.qml b/tests/auto/translation/data/dialogButtonBoxWithCustomButtons.qml new file mode 100644 index 00000000..6f046cf1 --- /dev/null +++ b/tests/auto/translation/data/dialogButtonBoxWithCustomButtons.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.14 +import QtQuick.Controls 2.14 + +Item { + property Dialog dialog: Dialog { + width: 300 + height: 300 + visible: true + + footer: DialogButtonBox { + Button { + objectName: "okButton" + text: qsTr("OK") + + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + } + Button { + objectName: "cancelButton" + text: qsTr("Cancel") + + DialogButtonBox.buttonRole: DialogButtonBox.RejectRole + } + } + } +} diff --git a/tests/auto/translation/tst_translation.cpp b/tests/auto/translation/tst_translation.cpp index 9cbca915..992c30a2 100644 --- a/tests/auto/translation/tst_translation.cpp +++ b/tests/auto/translation/tst_translation.cpp @@ -53,6 +53,7 @@ class tst_translation : public QQmlDataTest private slots: void dialogButtonBox(); + void dialogButtonBoxWithCustomButtons(); }; void tst_translation::dialogButtonBox() @@ -95,6 +96,45 @@ void tst_translation::dialogButtonBox() QCOMPARE(discardButton->text(), translatedDiscardText); } +// Test that custom buttons with explicitly specified text +// do not have that text overwritten on language changes. +void tst_translation::dialogButtonBoxWithCustomButtons() +{ + // This is just a way of simulating the translator going out of scope + // after the QML has been loaded. + QScopedPointer translator(new QTranslator); + // Doesn't matter which language it is, as we won't be using it anyway. + QVERIFY(translator->load(":/i18n/qtbase_fr.qm")); + QVERIFY(qApp->installTranslator(translator.data())); + + QQuickView view(testFileUrl("dialogButtonBoxWithCustomButtons.qml")); + if (view.status() != QQuickView::Ready) + QFAIL("Failed to load QML file"); + view.show(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickDialog *dialog = view.rootObject()->property("dialog").value(); + QVERIFY(dialog); + + QQuickDialogButtonBox *dialogButtonBox = qobject_cast(dialog->footer()); + QVERIFY(dialogButtonBox); + + auto okButton = dialogButtonBox->findChild("okButton"); + QVERIFY(okButton); + QCOMPARE(okButton->text(), QLatin1String("OK")); + + QQuickAbstractButton *cancelButton = dialogButtonBox->findChild("cancelButton"); + QVERIFY(cancelButton); + QCOMPARE(cancelButton->text(), QLatin1String("Cancel")); + + // Delete the translator and hence cause a LanguageChange event, + // but _without_ calling QQmlEngine::retranslate(), which would + // restore the original bindings and hence not reproduce the issue. + translator.reset(); + QCOMPARE(okButton->text(), QLatin1String("OK")); + QCOMPARE(cancelButton->text(), QLatin1String("Cancel")); +} + QTEST_MAIN(tst_translation) #include "tst_translation.moc" -- cgit v1.2.3 From 025f938c1b4676782674d54375e1e4e560e4b6cd Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 7 Feb 2020 11:33:50 +0100 Subject: Account for when a touch event is synthesized by Qt as a mouse event When a control is on a Flickable with a pressDelay then any press events sent from a touch device will be replayed as mouse events due to the delay. As a result we cannot depend on the fact that we got the first press as a touch event when checking if the id matches before accepting it. So we need to keep the previous pos when it is a synthesized mouse event so we can ensure the release is also accepted. Fixes: QTBUG-77202 Change-Id: I6f5d8506bd803daf834093e8fd412504150c4ca6 Reviewed-by: Shawn Rutledge Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickcontrol.cpp | 12 +++ src/quicktemplates2/qquickcontrol_p_p.h | 2 + tests/auto/qquickcontrol/data/flickable.qml | 71 ++++++++++++++++ tests/auto/qquickcontrol/qquickcontrol.pro | 14 ++++ tests/auto/qquickcontrol/tst_qquickcontrol.cpp | 110 +++++++++++++++++++++++++ 5 files changed, 209 insertions(+) create mode 100644 tests/auto/qquickcontrol/data/flickable.qml create mode 100644 tests/auto/qquickcontrol/qquickcontrol.pro create mode 100644 tests/auto/qquickcontrol/tst_qquickcontrol.cpp diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 7e249dae..838a841d 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -178,6 +178,12 @@ bool QQuickControlPrivate::acceptTouch(const QTouchEvent::TouchPoint &point) return true; } + // If the control is on a Flickable that has a pressDelay, then the press is never + // sent as a touch event, therefore we need to check for this case. + if (touchId == -1 && pressWasTouch && point.state() == Qt::TouchPointReleased && + point.pos() == previousPressPos) { + return true; + } return false; } #endif @@ -213,6 +219,8 @@ void QQuickControlPrivate::handleRelease(const QPointF &) if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease()) setActiveFocus(q, Qt::MouseFocusReason); touchId = -1; + pressWasTouch = false; + previousPressPos = QPointF(); } void QQuickControlPrivate::handleUngrab() @@ -2103,6 +2111,10 @@ void QQuickControl::mousePressEvent(QMouseEvent *event) { Q_D(QQuickControl); d->handlePress(event->localPos()); + if (event->source() == Qt::MouseEventSynthesizedByQt) { + d->pressWasTouch = true; + d->previousPressPos = event->localPos(); + } event->accept(); } diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h index a657307b..1b59f86d 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -224,7 +224,9 @@ public: bool explicitHoverEnabled = false; #endif bool resizingBackground = false; + bool pressWasTouch = false; int touchId = -1; + QPointF previousPressPos; qreal padding = 0; qreal horizontalPadding = 0; qreal verticalPadding = 0; diff --git a/tests/auto/qquickcontrol/data/flickable.qml b/tests/auto/qquickcontrol/data/flickable.qml new file mode 100644 index 00000000..f3a1c381 --- /dev/null +++ b/tests/auto/qquickcontrol/data/flickable.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.14 +import QtQuick.Controls 2.14 + +ApplicationWindow { + width: 400 + height: 400 + + property alias flickable: flickable + property alias button: button + + Flickable { + id: flickable + width: 300 + height: 400 + pressDelay: 50 + Button { + id: button + text: "This is a test button" + } + } +} diff --git a/tests/auto/qquickcontrol/qquickcontrol.pro b/tests/auto/qquickcontrol/qquickcontrol.pro new file mode 100644 index 00000000..8641343d --- /dev/null +++ b/tests/auto/qquickcontrol/qquickcontrol.pro @@ -0,0 +1,14 @@ +CONFIG += testcase +TARGET = tst_qquickcontrol +SOURCES += tst_qquickcontrol.cpp + +macos:CONFIG -= app_bundle + +QT += core-private gui-private qml-private quick-private testlib quicktemplates2-private + +include (../shared/util.pri) + +TESTDATA = data/* + +OTHER_FILES += \ + data/*.qml diff --git a/tests/auto/qquickcontrol/tst_qquickcontrol.cpp b/tests/auto/qquickcontrol/tst_qquickcontrol.cpp new file mode 100644 index 00000000..c8d34756 --- /dev/null +++ b/tests/auto/qquickcontrol/tst_qquickcontrol.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include "../shared/util.h" +#include "../shared/visualtestutil.h" +#include "../shared/qtest_quickcontrols.h" +#include +#include + +using namespace QQuickVisualTestUtil; + +class tst_QQuickControl : public QQmlDataTest +{ + Q_OBJECT + +private slots: + void initTestCase(); + void flickable(); + +private: + struct TouchDeviceDeleter + { + static inline void cleanup(QTouchDevice *device) + { + QWindowSystemInterface::unregisterTouchDevice(device); + delete device; + } + }; + + QScopedPointer touchDevice; +}; + + +void tst_QQuickControl::initTestCase() +{ + QQmlDataTest::initTestCase(); + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); + + touchDevice.reset(new QTouchDevice); + touchDevice->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(touchDevice.data()); +} + +void tst_QQuickControl::flickable() +{ + // Check that when a Button that is inside a Flickable with a pressDelay + // still gets the released and clicked signals sent due to the fact that + // Flickable sends a mouse event for the delay and not a touch event + QQuickApplicationHelper helper(this, QStringLiteral("flickable.qml")); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickButton *button = window->property("button").value(); + QVERIFY(button); + + QSignalSpy buttonPressedSpy(button, SIGNAL(pressed())); + QVERIFY(buttonPressedSpy.isValid()); + + QSignalSpy buttonReleasedSpy(button, SIGNAL(released())); + QVERIFY(buttonReleasedSpy.isValid()); + + QSignalSpy buttonClickedSpy(button, SIGNAL(clicked())); + QVERIFY(buttonClickedSpy.isValid()); + + QTest::touchEvent(window, touchDevice.data()).press(0, QPoint(button->width() / 2, button->height() / 2)); + QTRY_COMPARE(buttonPressedSpy.count(), 1); + QTest::touchEvent(window, touchDevice.data()).release(0, QPoint(button->width() / 2, button->height() / 2)); + QTRY_COMPARE(buttonReleasedSpy.count(), 1); + QTRY_COMPARE(buttonClickedSpy.count(), 1); +} + +QTEST_QUICKCONTROLS_MAIN(tst_QQuickControl) + +#include "tst_qquickcontrol.moc" -- cgit v1.2.3