diff options
Diffstat (limited to 'tests/auto/quickwidgets/qquickwidget')
6 files changed, 181 insertions, 3 deletions
diff --git a/tests/auto/quickwidgets/qquickwidget/BLACKLIST b/tests/auto/quickwidgets/qquickwidget/BLACKLIST index 095e9ee484..8b5585a41e 100644 --- a/tests/auto/quickwidgets/qquickwidget/BLACKLIST +++ b/tests/auto/quickwidgets/qquickwidget/BLACKLIST @@ -1,5 +1,12 @@ [tabKey] opensuse-42.3 opensuse-leap +macos-12 [enterLeave] macos +[focusOnClickInProxyWidget] +macos-12 +[focusPreserved] +macos-12 +[synthMouseFromTouch] +macos-12 diff --git a/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt b/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt index 5afe445cff..233fae553b 100644 --- a/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt +++ b/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt @@ -7,6 +7,12 @@ ## tst_qquickwidget Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qquickwidget LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + # Collect test data file(GLOB_RECURSE test_data_glob RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/tests/auto/quickwidgets/qquickwidget/data/activeFocusOnTab.qml b/tests/auto/quickwidgets/qquickwidget/data/activeFocusOnTab.qml index 11bbfdd90e..65f017b1b1 100644 --- a/tests/auto/quickwidgets/qquickwidget/data/activeFocusOnTab.qml +++ b/tests/auto/quickwidgets/qquickwidget/data/activeFocusOnTab.qml @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only import QtQuick 2.1 diff --git a/tests/auto/quickwidgets/qquickwidget/data/noActiveFocusOnTab.qml b/tests/auto/quickwidgets/qquickwidget/data/noActiveFocusOnTab.qml index 2168d29831..3fb6e5b7b1 100644 --- a/tests/auto/quickwidgets/qquickwidget/data/noActiveFocusOnTab.qml +++ b/tests/auto/quickwidgets/qquickwidget/data/noActiveFocusOnTab.qml @@ -1,5 +1,5 @@ // Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only import QtQuick 2.1 diff --git a/tests/auto/quickwidgets/qquickwidget/data/tapHandler.qml b/tests/auto/quickwidgets/qquickwidget/data/tapHandler.qml new file mode 100644 index 0000000000..fe3d1925e5 --- /dev/null +++ b/tests/auto/quickwidgets/qquickwidget/data/tapHandler.qml @@ -0,0 +1,11 @@ +import QtQuick + +Rectangle { + width: 100 + height: 100 + color: th.pressed ? "steelblue" : "beige" + + TapHandler { + id: th + } +} diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp index 8316625d87..3d5cb6e3b0 100644 --- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp +++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <qtest.h> #include <qtesttouch.h> @@ -11,8 +11,10 @@ #include <QtQuick/qquickitem.h> #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquickmousearea_p.h> +#include <QtQuick/private/qquicktaphandler_p.h> #include <QtQuickTemplates2/private/qquickbutton_p.h> #include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> #include <QtGui/QWindow> #include <QtGui/QScreen> #include <QtGui/QImage> @@ -23,6 +25,7 @@ #include <QtGui/qstylehints.h> #include <QtWidgets/QBoxLayout> #include <QtWidgets/QLabel> +#include <QtWidgets/private/qapplication_p.h> #include <QtQuickWidgets/QQuickWidget> @@ -127,6 +130,8 @@ private slots: void synthMouseFromTouch(); void touchTapMouseArea(); void touchTapButton(); + void touchTapHandler_data(); + void touchTapHandler(); void touchMultipleWidgets(); void tabKey(); void resizeOverlay(); @@ -135,6 +140,9 @@ private slots: #if QT_CONFIG(graphicsview) void focusOnClickInProxyWidget(); #endif + void focusPreserved(); + void accessibilityHandlesViewChange(); + void cleanupRhi(); private: QPointingDevice *device = QTest::createTouchDevice(); @@ -678,11 +686,54 @@ void tst_qquickwidget::touchTapButton() QTRY_VERIFY(rootItem->property("wasClicked").toBool()); } +void tst_qquickwidget::touchTapHandler_data() +{ + QTest::addColumn<bool>("guiSynthMouse"); // AA_SynthesizeMouseForUnhandledTouchEvents + QTest::addColumn<QQuickTapHandler::GesturePolicy>("gesturePolicy"); + + // QTest::newRow("nosynth: passive grab") << false << QQuickTapHandler::DragThreshold; // still failing + QTest::newRow("nosynth: exclusive grab") << false << QQuickTapHandler::ReleaseWithinBounds; + QTest::newRow("allowsynth: passive grab") << true << QQuickTapHandler::DragThreshold; // QTBUG-113558 + QTest::newRow("allowsynth: exclusive grab") << true << QQuickTapHandler::ReleaseWithinBounds; +} + +void tst_qquickwidget::touchTapHandler() +{ + QFETCH(bool, guiSynthMouse); + QFETCH(QQuickTapHandler::GesturePolicy, gesturePolicy); + + QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, guiSynthMouse); + QQuickWidget quick; + if (!quick.testAttribute(Qt::WA_AcceptTouchEvents)) + QSKIP("irrelevant on non-touch platforms"); + + quick.setSource(testFileUrl("tapHandler.qml")); + quick.show(); + QVERIFY(QTest::qWaitForWindowExposed(&quick)); + + QQuickItem *rootItem = quick.rootObject(); + QVERIFY(rootItem); + QQuickTapHandler *th = rootItem->findChild<QQuickTapHandler *>(); + QVERIFY(th); + th->setGesturePolicy(gesturePolicy); + QSignalSpy tappedSpy(th, &QQuickTapHandler::tapped); + + const QPoint p(50, 50); + QTest::touchEvent(&quick, device).press(0, p, &quick); + QTRY_COMPARE(th->isPressed(), true); + QTest::touchEvent(&quick, device).release(0, p, &quick); + QTRY_COMPARE(tappedSpy.size(), 1); + QCOMPARE(th->isPressed(), false); +} + void tst_qquickwidget::touchMultipleWidgets() { QWidget window; QQuickWidget *leftQuick = new QQuickWidget; leftQuick->setSource(testFileUrl("button.qml")); + if (!leftQuick->testAttribute(Qt::WA_AcceptTouchEvents)) + QSKIP("irrelevant on non-touch platforms"); + QQuickWidget *rightQuick = new QQuickWidget; rightQuick->setSource(testFileUrl("button.qml")); @@ -939,6 +990,109 @@ void tst_qquickwidget::focusOnClickInProxyWidget() } #endif +void tst_qquickwidget::focusPreserved() +{ + SKIP_IF_NO_WINDOW_ACTIVATION + if (QGuiApplication::platformName() == "android") + QSKIP("Test doesn't exit cleanly on Android and generates many warnings - QTBUG-112696"); + + QScopedPointer<QWidget> widget(new QWidget()); + QScopedPointer<QQuickWidget> quick(new QQuickWidget()); + QQuickItem *root = new QQuickItem(); // will be owned by quick after setContent + QScopedPointer<QQuickItem> content(new QQuickItem()); + content->setActiveFocusOnTab(true); + content->setFocus(true); + quick->setFocusPolicy(Qt::StrongFocus); + quick->setContent(QUrl(), nullptr, root); + root->setFlag(QQuickItem::ItemHasContents); + content->setParentItem(root); + + quick->setGeometry(0, 0, 200, 200); + quick->show(); + quick->setFocus(); + quick->activateWindow(); + QVERIFY(QTest::qWaitForWindowExposed(quick.get())); + QTRY_VERIFY(quick->hasFocus()); + QTRY_VERIFY(content->hasFocus()); + QTRY_VERIFY(content->hasActiveFocus()); + + widget->show(); + widget->setFocus(); + widget->activateWindow(); + QVERIFY(QTest::qWaitForWindowExposed(widget.get())); + QTRY_VERIFY(widget->hasFocus()); + + quick->setParent(widget.get()); + + quick->show(); + quick->setFocus(); + quick->activateWindow(); + QTRY_VERIFY(quick->hasFocus()); + QTRY_VERIFY(content->hasFocus()); + QTRY_VERIFY(content->hasActiveFocus()); +} + +/* + Reparenting the QQuickWidget recreates the offscreen QQuickWindow. + Since the accessible interface that is cached for the QQuickWidget dispatches + all calls to the offscreen QQuickWindow, it must fix itself when the offscreen + view changes. QTBUG-108226 +*/ +void tst_qquickwidget::accessibilityHandlesViewChange() +{ + if (QGuiApplication::platformName() == "offscreen") + QSKIP("Doesn't test anything on offscreen platform."); + if (QGuiApplication::platformName() == "android") + QSKIP("Test doesn't exit cleanly on Android and generates many warnings - QTBUG-112696"); + + QWidget window; + + QPointer<QQuickWindow> backingScene; + + QQuickWidget *childView = new QQuickWidget(&window); + childView->setSource(testFileUrl("rectangle.qml")); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + backingScene = childView->quickWindow(); + QVERIFY(backingScene); + + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(childView); + QVERIFY(iface); + (void)iface->child(0); + + std::unique_ptr<QQuickWidget> quickWidget(childView); + childView->setParent(nullptr); + childView->show(); + QVERIFY(QTest::qWaitForWindowExposed(childView)); + QVERIFY(!backingScene); // the old QQuickWindow should be gone now + QVERIFY(childView->quickWindow()); // long live the new QQuickWindow + + iface = QAccessible::queryAccessibleInterface(childView); + QVERIFY(iface); + // this would crash if QAccessibleQuickWidget hadn't repaired itself to + // delegate calls to the new (or at least not the old, destroyed) QQuickWindow. + (void)iface->child(0); +} + +class CreateDestroyWidget : public QWidget +{ +public: + using QWidget::create; + using QWidget::destroy; +}; + +void tst_qquickwidget::cleanupRhi() +{ + CreateDestroyWidget topLevel; + QQuickWidget quickWidget(&topLevel); + quickWidget.setSource(testFileUrl("rectangle.qml")); + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + + topLevel.destroy(); + topLevel.create(); +} + QTEST_MAIN(tst_qquickwidget) #include "tst_qquickwidget.moc" |