aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
authorTarja Sundqvist <tarja.sundqvist@qt.io>2022-05-16 18:16:38 +0300
committerTarja Sundqvist <tarja.sundqvist@qt.io>2022-05-16 18:16:38 +0300
commitae66ecf0f95c79d730190b92e641c0410d5d6896 (patch)
tree5e5ff0c1f08148a7a421581ba0907314aa90d6a3 /tests/auto/quick
parent04ea6df18a2b06efd133a4f1b13c2e38817279ae (diff)
parent53086eaf2ffb5fc1c360cf13f3d87e8d5f2a7b6f (diff)
Merge remote-tracking branch 'origin/tqtc/lts-5.15.5' into tqtc/lts-5.15-opensourcev5.15.5-lts-lgpl
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml39
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp55
-rw-r--r--tests/auto/quick/qquickpincharea/data/draggablePinchArea.qml70
-rw-r--r--tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp66
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp78
-rw-r--r--tests/auto/quick/scenegraph/data/render_AlphaOverlapRebuild.qml115
-rw-r--r--tests/auto/quick/scenegraph/data/widebtn1.pngbin0 -> 1969 bytes
-rw-r--r--tests/auto/quick/scenegraph/data/widebtn2.pngbin0 -> 1965 bytes
-rw-r--r--tests/auto/quick/scenegraph/tst_scenegraph.cpp4
9 files changed, 423 insertions, 4 deletions
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml
new file mode 100644
index 0000000000..1c18133f92
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+Item {
+ id: root
+ width: 100
+ height: 100
+ property int tapCount: 0
+ TapHandler {
+ onTapped: { ++root.tapCount }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
index 419afed3ac..52cef6248f 100644
--- a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
@@ -71,15 +71,25 @@ private slots:
void buttonsMultiTouch();
void componentUserBehavioralOverride();
void rightLongPressIgnoreWheel();
+ void nonTopLevelParentWindow();
private:
- void createView(QScopedPointer<QQuickView> &window, const char *fileName);
+ void createView(QScopedPointer<QQuickView> &window, const char *fileName,
+ QWindow *parent = nullptr);
QTouchDevice *touchDevice;
+ void mouseEvent(QEvent::Type type, Qt::MouseButton button, const QPoint &point,
+ QWindow *targetWindow, QWindow *mapToWindow);
};
-void tst_TapHandler::createView(QScopedPointer<QQuickView> &window, const char *fileName)
+void tst_TapHandler::createView(QScopedPointer<QQuickView> &window, const char *fileName,
+ QWindow *parent)
{
- window.reset(new QQuickView);
+ window.reset(new QQuickView(parent));
+ if (parent) {
+ parent->show();
+ QVERIFY(QTest::qWaitForWindowActive(parent));
+ }
+
window->setSource(testFileUrl(fileName));
QTRY_COMPARE(window->status(), QQuickView::Ready);
QQuickViewTestUtil::centerOnScreen(window.data());
@@ -90,6 +100,20 @@ void tst_TapHandler::createView(QScopedPointer<QQuickView> &window, const char *
QVERIFY(window->rootObject() != nullptr);
}
+void tst_TapHandler::mouseEvent(QEvent::Type type, Qt::MouseButton button, const QPoint &point,
+ QWindow *targetWindow, QWindow *mapToWindow)
+{
+ QVERIFY(targetWindow);
+ QVERIFY(mapToWindow);
+ auto buttons = button;
+ if (type == QEvent::MouseButtonRelease) {
+ buttons = Qt::NoButton;
+ }
+ QMouseEvent me(type, point, mapToWindow->mapToGlobal(point), button, buttons,
+ Qt::KeyboardModifiers());
+ QVERIFY(qApp->notify(targetWindow, &me));
+}
+
void tst_TapHandler::initTestCase()
{
// This test assumes that we don't get synthesized mouse events from QGuiApplication
@@ -745,6 +769,31 @@ void tst_TapHandler::rightLongPressIgnoreWheel()
QCOMPARE(tappedSpy.count(), 0);
}
+void tst_TapHandler::nonTopLevelParentWindow() // QTBUG-91716
+{
+ QScopedPointer<QQuickWindow> parentWindowPtr(new QQuickWindow);
+ auto parentWindow = parentWindowPtr.get();
+ parentWindow->setGeometry(400, 400, 250, 250);
+
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "simpleTapHandler.qml", parentWindow);
+ auto window = windowPtr.get();
+ window->setGeometry(10, 10, 100, 100);
+
+ QQuickItem *root = window->rootObject();
+
+ auto p1 = QPoint(20, 20);
+ mouseEvent(QEvent::MouseButtonPress, Qt::LeftButton, p1, window, parentWindow);
+ mouseEvent(QEvent::MouseButtonRelease, Qt::LeftButton, p1, window, parentWindow);
+
+ QCOMPARE(root->property("tapCount").toInt(), 1);
+
+ QTest::touchEvent(window, touchDevice).press(0, p1, parentWindow).commit();
+ QTest::touchEvent(window, touchDevice).release(0, p1, parentWindow).commit();
+
+ QCOMPARE(root->property("tapCount").toInt(), 2);
+}
+
QTEST_MAIN(tst_TapHandler)
#include "tst_qquicktaphandler.moc"
diff --git a/tests/auto/quick/qquickpincharea/data/draggablePinchArea.qml b/tests/auto/quick/qquickpincharea/data/draggablePinchArea.qml
new file mode 100644
index 0000000000..3acf67b4b6
--- /dev/null
+++ b/tests/auto/quick/qquickpincharea/data/draggablePinchArea.qml
@@ -0,0 +1,70 @@
+import QtQuick 2.12
+
+Rectangle {
+ id: root
+ width: 600
+ height: 600
+
+ Rectangle {
+ objectName: "paContainer"
+ width: parent.width -100
+ height: parent.height - 100
+ border.color: "black"
+ anchors.centerIn: parent
+ transformOrigin: Item.Center
+
+ Rectangle {
+ width: 300
+ height: 300
+ color: "tomato"
+ PinchArea {
+ id: pa
+ anchors.fill: parent
+ pinch.target: parent
+ pinch.minimumScale: 0.5
+ pinch.maximumScale: 2
+ pinch.minimumRotation: -360
+ pinch.maximumRotation: 360
+ pinch.dragAxis: Pinch.XAndYAxis
+ pinch.minimumX: -100
+ pinch.maximumX: 300
+ pinch.minimumY: -100
+ pinch.maximumY: 300
+ }
+
+
+ Text { text: "this way up" }
+ }
+ }
+
+ // only for touch feedback / troubleshooting
+ Item {
+ id: glassPane
+ z: 10000
+ anchors.fill: parent
+
+ PointHandler {
+ id: ph1
+ target: Rectangle {
+ parent: glassPane
+ color: "green"
+ visible: ph1.active
+ x: ph1.point.position.x - width / 2
+ y: ph1.point.position.y - height / 2
+ width: 20; height: width; radius: width / 2
+ }
+ }
+
+ PointHandler {
+ id: ph2
+ target: Rectangle {
+ parent: glassPane
+ color: "blue"
+ visible: ph2.active
+ x: ph2.point.position.x - width / 2
+ y: ph2.point.position.y - height / 2
+ width: 20; height: width; radius: width / 2
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
index 5b7108d96b..367df96118 100644
--- a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
+++ b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
@@ -52,6 +52,8 @@ private slots:
void cancel();
void transformedPinchArea_data();
void transformedPinchArea();
+ void dragTransformedPinchArea_data();
+ void dragTransformedPinchArea();
private:
QQuickView *createView();
@@ -586,6 +588,70 @@ void tst_QQuickPinchArea::transformedPinchArea()
}
}
+void tst_QQuickPinchArea::dragTransformedPinchArea_data()
+{
+ QTest::addColumn<int>("rotation");
+ QTest::addColumn<QPoint>("p1");
+ QTest::addColumn<QPoint>("p2");
+ QTest::addColumn<QPoint>("delta");
+
+ QTest::newRow("unrotated")
+ << 0 << QPoint(100, 100) << QPoint(200, 100) << QPoint(40, 40);
+ QTest::newRow("20 deg")
+ << 20 << QPoint(100, 100) << QPoint(200, 100) << QPoint(40, 40);
+ QTest::newRow("90 deg")
+ << 90 << QPoint(100, 100) << QPoint(200, 100) << QPoint(0, 40);
+ QTest::newRow("180 deg")
+ << 180 << QPoint(100, 100) << QPoint(200, 100) << QPoint(40, 0);
+ QTest::newRow("225 deg")
+ << 210 << QPoint(200, 200) << QPoint(300, 200) << QPoint(80, 80);
+}
+
+void tst_QQuickPinchArea::dragTransformedPinchArea() // QTBUG-63673
+{
+ QFETCH(int, rotation);
+ QFETCH(QPoint, p1);
+ QFETCH(QPoint, p2);
+ QFETCH(QPoint, delta);
+ const int threshold = qApp->styleHints()->startDragDistance();
+
+ QQuickView *view = createView();
+ QScopedPointer<QQuickView> scope(view);
+ view->setSource(testFileUrl("draggablePinchArea.qml"));
+ view->show();
+ QVERIFY(QTest::qWaitForWindowExposed(view));
+ QVERIFY(view->rootObject());
+ QQuickPinchArea *pinchArea = view->rootObject()->findChild<QQuickPinchArea*>();
+ QVERIFY(pinchArea);
+ QQuickItem *pinchAreaTarget = pinchArea->parentItem();
+ QVERIFY(pinchAreaTarget);
+ QQuickItem *pinchAreaContainer = pinchAreaTarget->parentItem();
+ QVERIFY(pinchAreaContainer);
+ pinchAreaContainer->setRotation(rotation);
+
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(view, device);
+ // start pinch
+ pinchSequence.press(1, pinchArea->mapToScene(p1).toPoint(), view)
+ .press(2, pinchArea->mapToScene(p2).toPoint(), view).commit();
+ QQuickTouchUtils::flush(view);
+ pinchSequence.move(1, pinchArea->mapToScene(p1 + QPoint(threshold, threshold)).toPoint(), view)
+ .move(2, pinchArea->mapToScene(p2 + QPoint(threshold, threshold)).toPoint(), view).commit();
+ QQuickTouchUtils::flush(view);
+ pinchSequence.move(1, pinchArea->mapToScene(p1 + delta).toPoint(), view)
+ .move(2, pinchArea->mapToScene(p2 + delta).toPoint(), view).commit();
+ QQuickTouchUtils::flush(view);
+ QCOMPARE(pinchArea->pinch()->active(), true);
+ auto error = delta - QPoint(threshold, threshold) -
+ pinchAreaTarget->position().toPoint(); // expect 0, 0
+ QVERIFY(qAbs(error.x()) <= 1);
+ QVERIFY(qAbs(error.y()) <= 1);
+
+ // release pinch
+ pinchSequence.release(1, p1, view).release(2, p2, view).commit();
+ QQuickTouchUtils::flush(view);
+ QCOMPARE(pinchArea->pinch()->active(), false);
+}
+
QQuickView *tst_QQuickPinchArea::createView()
{
QQuickView *window = new QQuickView(nullptr);
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index d14c37d8e3..6d37fb44e3 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -169,6 +169,8 @@ private slots:
void checkTableviewInsideAsyncLoader();
void hideRowsAndColumns_data();
void hideRowsAndColumns();
+ void hideAndShowFirstColumn();
+ void hideAndShowFirstRow();
void checkThatRevisionedPropertiesCannotBeUsedInOldImports();
void checkSyncView_rootView_data();
void checkSyncView_rootView();
@@ -2413,6 +2415,82 @@ void tst_QQuickTableView::hideRowsAndColumns()
QVERIFY(!columnsToHideList.contains(column));
}
+void tst_QQuickTableView::hideAndShowFirstColumn()
+{
+ // Check that if we hide the first column, it will move
+ // the second column to the origin of the viewport. Then check
+ // that if we show the first column again, it will reappear at
+ // the origin of the viewport, and as such, pushing the second
+ // column to the right of it.
+ LOAD_TABLEVIEW("hiderowsandcolumns.qml");
+
+ const int modelSize = 5;
+ auto model = TestModelAsVariant(modelSize, modelSize);
+ tableView->setModel(model);
+
+ // Start by making the first column hidden
+ const auto columnsToHideList = QList<int>() << 0;
+ view->rootObject()->setProperty("columnsToHide", QVariant::fromValue(columnsToHideList));
+
+ WAIT_UNTIL_POLISHED;
+
+ const int expectedColumnCount = modelSize - columnsToHideList.count();
+ QCOMPARE(tableViewPrivate->loadedColumns.count(), expectedColumnCount);
+ QCOMPARE(tableViewPrivate->leftColumn(), 1);
+ QCOMPARE(tableView->contentX(), 0);
+ QCOMPARE(tableViewPrivate->loadedTableOuterRect.x(), 0);
+
+ // Make the first column in the model visible again
+ const auto emptyList = QList<int>();
+ view->rootObject()->setProperty("columnsToHide", QVariant::fromValue(emptyList));
+ tableView->forceLayout();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedColumns.count(), modelSize);
+ QCOMPARE(tableViewPrivate->leftColumn(), 0);
+ QCOMPARE(tableView->contentX(), 0);
+ QCOMPARE(tableViewPrivate->loadedTableOuterRect.x(), 0);
+}
+
+void tst_QQuickTableView::hideAndShowFirstRow()
+{
+ // Check that if we hide the first row, it will move
+ // the second row to the origin of the viewport. Then check
+ // that if we show the first row again, it will reappear at
+ // the origin of the viewport, and as such, pushing the second
+ // row below it.
+ LOAD_TABLEVIEW("hiderowsandcolumns.qml");
+
+ const int modelSize = 5;
+ auto model = TestModelAsVariant(modelSize, modelSize);
+ tableView->setModel(model);
+
+ // Start by making the first row hidden
+ const auto rowsToHideList = QList<int>() << 0;
+ view->rootObject()->setProperty("rowsToHide", QVariant::fromValue(rowsToHideList));
+
+ WAIT_UNTIL_POLISHED;
+
+ const int expectedRowsCount = modelSize - rowsToHideList.count();
+ QCOMPARE(tableViewPrivate->loadedRows.count(), expectedRowsCount);
+ QCOMPARE(tableViewPrivate->topRow(), 1);
+ QCOMPARE(tableView->contentY(), 0);
+ QCOMPARE(tableViewPrivate->loadedTableOuterRect.y(), 0);
+
+ // Make the first row in the model visible again
+ const auto emptyList = QList<int>();
+ view->rootObject()->setProperty("rowsToHide", QVariant::fromValue(emptyList));
+ tableView->forceLayout();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedRows.count(), modelSize);
+ QCOMPARE(tableViewPrivate->topRow(), 0);
+ QCOMPARE(tableView->contentY(), 0);
+ QCOMPARE(tableViewPrivate->loadedTableOuterRect.y(), 0);
+}
+
void tst_QQuickTableView::checkThatRevisionedPropertiesCannotBeUsedInOldImports()
{
// Check that if you use a QQmlAdaptorModel together with a Repeater, the
diff --git a/tests/auto/quick/scenegraph/data/render_AlphaOverlapRebuild.qml b/tests/auto/quick/scenegraph/data/render_AlphaOverlapRebuild.qml
new file mode 100644
index 0000000000..f06be8f553
--- /dev/null
+++ b/tests/auto/quick/scenegraph/data/render_AlphaOverlapRebuild.qml
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.15
+
+/*
+ QTBUG-92984.
+
+ Have three Image (with semi-transparency) and two semi-transparent
+ Rectangle elements, and so all in the alpha render list, with images that
+ are big enough to not get atlased. (meaning the underlying nodes never get
+ merged, but the nodes for the Rectangle elements might)
+
+ Lay them out vertically below each other, with the two Rectangles on top of
+ the second and third Images, respectively. Then change (swap) the source
+ property of the Images. This triggers a rebuild in the batch renderer.
+
+ Verify that the results are still correct, i.e. that the two Rectangle
+ elements do not get merged. An incorrect result would be having the third
+ Image rendered on top of the corresponding Rectangle due the two Rectangles
+ (incorrectly) being in one merged batch. The Image should always be below,
+ regardless of which nodes get changed, invalidated, and how batches get
+ rebuilt.
+
+ The base-final sample set 1 just verifies that the Image changes from the
+ blueish to greenish. The important part is the second set of samples: this
+ checks that the red(ish) rectangle is still on top of the third Image. With
+ incorrect merging behavior the second final result would be the same as the
+ first final one (i.e. the "background" Image rendered, incorrectly, on top
+ of the Rectangle).
+
+ #samples: 4
+ PixelPos R G B Error-tolerance
+ #base: 30 115 0.24313 0.30588 0.99607 0.05
+ #base: 30 124 0.847059 0.062745 0.2 0.05
+ #final: 30 115 0.36078 0.99607 0.42745 0.05
+ #final: 30 124 0.870588 0.2 0.0862745 0.05
+*/
+
+RenderTestBase {
+ id: root
+
+ property string selectedItem: "item2"
+
+ Item {
+ width: 150; height: 50
+ Image {
+ width: parent.width
+ objectName: "item1"
+ source: "widebtn1.png"
+ }
+ }
+
+ Item {
+ y: 50; width: 150; height: 50
+ Image {
+ width: parent.width
+ objectName: "item2"
+ source: selectedItem == objectName ? "widebtn2.png" : "widebtn1.png"
+ }
+ Rectangle {
+ anchors.fill: parent
+ anchors.margins: 20
+ color: "red"
+ opacity: 0.8
+ }
+ }
+
+ Item {
+ y: 100; width: 150; height: 50
+ Image {
+ id: img3
+ width: parent.width
+ objectName: "item3"
+ source: selectedItem == objectName ? "widebtn2.png" : "widebtn1.png"
+ }
+ Rectangle {
+ width: parent.width + 50
+ anchors.centerIn: parent
+ height: img3.height - 40
+ color: "red"
+ opacity: 0.8
+ }
+ }
+
+ onEnterFinalStage: {
+ selectedItem = "item3";
+ finalStageComplete = true;
+ }
+}
diff --git a/tests/auto/quick/scenegraph/data/widebtn1.png b/tests/auto/quick/scenegraph/data/widebtn1.png
new file mode 100644
index 0000000000..1150b67a7a
--- /dev/null
+++ b/tests/auto/quick/scenegraph/data/widebtn1.png
Binary files differ
diff --git a/tests/auto/quick/scenegraph/data/widebtn2.png b/tests/auto/quick/scenegraph/data/widebtn2.png
new file mode 100644
index 0000000000..40afe08363
--- /dev/null
+++ b/tests/auto/quick/scenegraph/data/widebtn2.png
Binary files differ
diff --git a/tests/auto/quick/scenegraph/tst_scenegraph.cpp b/tests/auto/quick/scenegraph/tst_scenegraph.cpp
index 12f7efb7d5..cf85e262c0 100644
--- a/tests/auto/quick/scenegraph/tst_scenegraph.cpp
+++ b/tests/auto/quick/scenegraph/tst_scenegraph.cpp
@@ -402,7 +402,9 @@ void tst_SceneGraph::render_data()
<< "render_StackingOrder.qml"
<< "render_ImageFiltering.qml"
<< "render_bug37422.qml"
- << "render_OpacityThroughBatchRoot.qml";
+ << "render_OpacityThroughBatchRoot.qml"
+ << "render_AlphaOverlapRebuild.qml";
+
if (!m_brokenMipmapSupport)
files << "render_Mipmap.qml";