diff options
Diffstat (limited to 'tests/auto/quick')
45 files changed, 1094 insertions, 408 deletions
diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp index 233cb33631..872a71011d 100644 --- a/tests/auto/quick/examples/tst_examples.cpp +++ b/tests/auto/quick/examples/tst_examples.cpp @@ -103,6 +103,18 @@ tst_examples::tst_examples() excludedFiles << "views/visualdatamodel/slideshow.qml"; #endif +#ifdef QT_NO_OPENGL + //No support for Particles + excludedFiles << "examples/qml/dynamicscene/dynamicscene.qml"; + excludedFiles << "examples/quick/animation/basics/color-animation.qml"; + excludedFiles << "examples/quick/particles/affectors/content/age.qml"; + excludedFiles << "examples/quick/touchinteraction/multipointtouch/bearwhack.qml"; + excludedFiles << "examples/quick/touchinteraction/multipointtouch/multiflame.qml"; + excludedDirs << "examples/quick/particles"; + // No Support for ShaderEffect + excludedFiles << "src/quick/doc/snippets/qml/animators.qml"; +#endif + } tst_examples::~tst_examples() diff --git a/tests/auto/quick/geometry/tst_geometry.cpp b/tests/auto/quick/geometry/tst_geometry.cpp index 8755e3a1d7..470ce3bd91 100644 --- a/tests/auto/quick/geometry/tst_geometry.cpp +++ b/tests/auto/quick/geometry/tst_geometry.cpp @@ -126,9 +126,9 @@ void GeometryTest::testCustomGeometry() }; static QSGGeometry::Attribute attributes[] = { - { 0, 2, GL_FLOAT, 0, 0}, - { 1, 4, GL_UNSIGNED_BYTE, 0, 0}, - { 2, 4, GL_FLOAT, 0, 0}, + QSGGeometry::Attribute::create(0, 2, QSGGeometry::TypeFloat, false), + QSGGeometry::Attribute::create(1, 4, QSGGeometry::TypeUnsignedByte, false), + QSGGeometry::Attribute::create(2, 4, QSGGeometry::TypeFloat, false) }; static QSGGeometry::AttributeSet set = { 4, 6 * sizeof(float) + 4 * sizeof(unsigned char), attributes }; diff --git a/tests/auto/quick/nodes/tst_nodestest.cpp b/tests/auto/quick/nodes/tst_nodestest.cpp index 16c1174604..63e0aeb324 100644 --- a/tests/auto/quick/nodes/tst_nodestest.cpp +++ b/tests/auto/quick/nodes/tst_nodestest.cpp @@ -31,7 +31,6 @@ #include <QtGui/QOffscreenSurface> #include <QtGui/QOpenGLContext> - #include <QtQuick/qsgnode.h> #include <QtQuick/private/qsgbatchrenderer_p.h> #include <QtQuick/private/qsgnodeupdater_p.h> @@ -76,7 +75,7 @@ private Q_SLOTS: private: QOffscreenSurface *surface; QOpenGLContext *context; - QSGRenderContext *renderContext; + QSGDefaultRenderContext *renderContext; }; void NodesTest::initTestCase() @@ -91,7 +90,8 @@ void NodesTest::initTestCase() QVERIFY(context->create()); QVERIFY(context->makeCurrent(surface)); - renderContext = renderLoop->createRenderContext(renderLoop->sceneGraphContext()); + auto rc = renderLoop->createRenderContext(renderLoop->sceneGraphContext()); + renderContext = static_cast<QSGDefaultRenderContext *>(rc); QVERIFY(renderContext); renderContext->initialize(context); QVERIFY(renderContext->isValid()); @@ -110,7 +110,7 @@ void NodesTest::cleanupTestCase() class DummyRenderer : public QSGBatchRenderer::Renderer { public: - DummyRenderer(QSGRootNode *root, QSGRenderContext *renderContext) + DummyRenderer(QSGRootNode *root, QSGDefaultRenderContext *renderContext) : QSGBatchRenderer::Renderer(renderContext) , changedNode(0) , changedState(0) diff --git a/tests/auto/quick/nokeywords/tst_nokeywords.cpp b/tests/auto/quick/nokeywords/tst_nokeywords.cpp index ffe76cc210..6c94b484ae 100644 --- a/tests/auto/quick/nokeywords/tst_nokeywords.cpp +++ b/tests/auto/quick/nokeywords/tst_nokeywords.cpp @@ -48,13 +48,15 @@ #include <QtQuick/private/qsgadaptationlayer_p.h> #include <QtQuick/private/qsgcontext_p.h> #include <QtQuick/private/qsgcontextplugin_p.h> +#ifndef QT_NO_OPENGL #include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h> #include <QtQuick/private/qsgdefaultglyphnode_p.h> -#include <QtQuick/private/qsgdefaultimagenode_p.h> -#include <QtQuick/private/qsgdefaultrectanglenode_p.h> +#include <QtQuick/private/qsgdefaultinternalimagenode_p.h> +#include <QtQuick/private/qsgdefaultinternalrectanglenode_p.h> #include <QtQuick/private/qsgdepthstencilbuffer_p.h> #include <QtQuick/private/qsgdistancefieldglyphnode_p.h> #include <QtQuick/private/qsgdistancefieldutil_p.h> +#endif #include <QtQuick/private/qsggeometry_p.h> #include <QtQuick/private/qsgnode_p.h> #include <QtQuick/private/qsgnodeupdater_p.h> diff --git a/tests/auto/quick/qquickaccessible/qquickaccessible.pro b/tests/auto/quick/qquickaccessible/qquickaccessible.pro index 02915e8e22..537aad882f 100644 --- a/tests/auto/quick/qquickaccessible/qquickaccessible.pro +++ b/tests/auto/quick/qquickaccessible/qquickaccessible.pro @@ -15,10 +15,3 @@ OTHER_FILES += data/checkbuttons.qml \ data/pushbutton.qml \ data/statictext.qml \ data/ignored.qml \ - -wince*: { - accessneeded.files = $$QT.widgets.plugins/accessible/*.dll - accessneeded.path = accessible - DEPLOYMENT += accessneeded -} - diff --git a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp index b34f58f7c4..34b9fb6b07 100644 --- a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp +++ b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp @@ -179,7 +179,11 @@ void tst_qquickanimatedimage::mirror_running() QImage frame0_expected = frame0.transformed(transform); QImage frame1_expected = frame1.transformed(transform); + if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software) + QSKIP("QTBUG-53823"); QCOMPARE(frame0_flipped, frame0_expected); + if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software) + QSKIP("QTBUG-53823"); QCOMPARE(frame1_flipped, frame1_expected); delete anim; @@ -212,6 +216,8 @@ void tst_qquickanimatedimage::mirror_notRunning() screenshot = window.grabWindow(); screenshot.save("screen.png"); + if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software) + QSKIP("QTBUG-53823"); QCOMPARE(screenshot, expected); // mirroring should not change the current frame or playing status diff --git a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp index 1bd163fc4a..114f906736 100644 --- a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp +++ b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp @@ -47,6 +47,7 @@ private slots: void active(); void state(); void layoutDirection(); + void font(); void inputMethod(); void styleHints(); void cleanup(); @@ -196,6 +197,21 @@ void tst_qquickapplication::layoutDirection() QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight); } +void tst_qquickapplication::font() +{ + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; Item { property font defaultFont: Qt.application.font }", QUrl::fromLocalFile("")); + QQuickItem *item = qobject_cast<QQuickItem *>(component.create()); + QVERIFY(item); + QQuickView view; + item->setParentItem(view.rootObject()); + + QVariant defaultFontProperty = item->property("defaultFont"); + QVERIFY(defaultFontProperty.isValid()); + QCOMPARE(defaultFontProperty.type(), QVariant::Font); + QCOMPARE(defaultFontProperty.value<QFont>(), qApp->font()); +} + void tst_qquickapplication::inputMethod() { // technically not in QQuickApplication, but testing anyway here diff --git a/tests/auto/quick/qquickborderimage/data/mesh.qml b/tests/auto/quick/qquickborderimage/data/mesh.qml new file mode 100644 index 0000000000..203bf25867 --- /dev/null +++ b/tests/auto/quick/qquickborderimage/data/mesh.qml @@ -0,0 +1,22 @@ +import QtQuick 2.8 + +Item { + width: 300 + height: 300 + Image { + id: image + source: "colors.png" + visible: false + } + ShaderEffect { + anchors.fill: parent + property variant source: image + mesh: BorderImageMesh { + border.left: 30 + border.right: 30 + border.top: 30 + border.bottom: 30 + size: image.sourceSize + } + } +} diff --git a/tests/auto/quick/qquickborderimage/data/nonmesh.qml b/tests/auto/quick/qquickborderimage/data/nonmesh.qml new file mode 100644 index 0000000000..7a1830a942 --- /dev/null +++ b/tests/auto/quick/qquickborderimage/data/nonmesh.qml @@ -0,0 +1,11 @@ +import QtQuick 2.8 + +BorderImage { + width: 300 + height: 300 + source: "colors.png" + border.left: 30 + border.right: 30 + border.top: 30 + border.bottom: 30 +} diff --git a/tests/auto/quick/qquickborderimage/qquickborderimage.pro b/tests/auto/quick/qquickborderimage/qquickborderimage.pro index 3e16063559..ba6c01737a 100644 --- a/tests/auto/quick/qquickborderimage/qquickborderimage.pro +++ b/tests/auto/quick/qquickborderimage/qquickborderimage.pro @@ -7,6 +7,7 @@ SOURCES += tst_qquickborderimage.cpp \ ../../shared/testhttpserver.cpp include (../../shared/util.pri) +include (../shared/util.pri) TESTDATA = data/* diff --git a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp index c11ae1e8c9..5d242fab9e 100644 --- a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp +++ b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp @@ -44,6 +44,7 @@ #include "../../shared/testhttpserver.h" #include "../../shared/util.h" +#include "../shared/visualtestutil.h" Q_DECLARE_METATYPE(QQuickImageBase::Status) @@ -75,6 +76,9 @@ private slots: void statusChanges_data(); void sourceSizeChanges(); void progressAndStatusChanges(); +#ifndef QT_NO_OPENGL + void borderImageMesh(); +#endif private: QQmlEngine engine; @@ -242,6 +246,11 @@ void tst_qquickborderimage::mirror() image->setProperty("mirror", true); screenshot = window->grabWindow(); + + window->show(); + QTest::qWaitForWindowExposed(window); + if (window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) + QSKIP("QTBUG-53823"); QCOMPARE(screenshot, srcPixmap); delete window; @@ -574,7 +583,22 @@ void tst_qquickborderimage::progressAndStatusChanges() delete obj; } +#ifndef QT_NO_OPENGL +void tst_qquickborderimage::borderImageMesh() +{ + QQuickView *window = new QQuickView; + window->setSource(testFileUrl("nonmesh.qml")); + window->show(); + QTest::qWaitForWindowExposed(window); + QImage nonmesh = window->grabWindow(); + + window->setSource(testFileUrl("mesh.qml")); + QImage mesh = window->grabWindow(); + + QVERIFY(QQuickVisualTestUtil::compareImages(mesh, nonmesh)); +} +#endif QTEST_MAIN(tst_qquickborderimage) #include "tst_qquickborderimage.moc" diff --git a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml index e49f0ac462..b0fb7fcf8c 100644 --- a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml +++ b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml @@ -31,7 +31,9 @@ TestCase { } function createCanvasObject(data) { - return component.createObject(testCase, data.properties); + var canvas = component.createObject(testCase, data.properties); + waitForRendering(canvas); + return canvas; } function comparePixel(ctx,x,y,r,g,b,a, d) diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml index 93f85107a7..565f906fb1 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml @@ -590,6 +590,7 @@ CanvasTestCase { verify(canvas); canvas.width = 100; canvas.height = 100; + waitForRendering(canvas); var ctx = canvas.getContext("2d"); diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml index 46a038a13c..1f695d7080 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml @@ -667,6 +667,7 @@ CanvasTestCase { var canvas2 = Qt.createQmlObject("import QtQuick 2.0; Canvas{renderTarget:Canvas.Image; renderStrategy:Canvas.Immediate}", canvas); canvas2.width = 100; canvas2.height = 50; + waitForRendering(canvas2); var ctx2 = canvas2.getContext('2d'); ctx2.fillStyle = '#0f0'; ctx2.fillRect(0, 0, 100, 50); diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 96fe97f372..e1678b9acd 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -1138,7 +1138,9 @@ void tst_qquickflickable::flickOnRelease() QTRY_VERIFY(!flickable->isMoving()); #ifdef Q_OS_MAC +# ifndef QT_NO_OPENGL QEXPECT_FAIL("", "QTBUG-26094 stopping on a full pixel doesn't work on OS X", Continue); +# endif #endif // Stop on a full pixel after user interaction QCOMPARE(flickable->contentY(), (qreal)qRound(flickable->contentY())); diff --git a/tests/auto/quick/qquickgraphicsinfo/data/basic.qml b/tests/auto/quick/qquickgraphicsinfo/data/basic.qml new file mode 100644 index 0000000000..6ff3b82cec --- /dev/null +++ b/tests/auto/quick/qquickgraphicsinfo/data/basic.qml @@ -0,0 +1,14 @@ +import QtQuick 2.8 + +Item { + property int api: GraphicsInfo.api + + property int shaderType: GraphicsInfo.shaderType + property int shaderCompilationType: GraphicsInfo.shaderCompilationType + property int shaderSourceType: GraphicsInfo.shaderSourceType + + property int majorVersion: GraphicsInfo.majorVersion + property int minorVersion: GraphicsInfo.minorVersion + property int profile: GraphicsInfo.profile + property int renderableType: GraphicsInfo.renderableType +} diff --git a/tests/auto/quick/qquickgraphicsinfo/qquickgraphicsinfo.pro b/tests/auto/quick/qquickgraphicsinfo/qquickgraphicsinfo.pro new file mode 100644 index 0000000000..a4296ad9a2 --- /dev/null +++ b/tests/auto/quick/qquickgraphicsinfo/qquickgraphicsinfo.pro @@ -0,0 +1,14 @@ +CONFIG += testcase +TARGET = tst_qquickgraphicsinfo +SOURCES += tst_qquickgraphicsinfo.cpp + +TESTDATA = data/* +include(../../shared/util.pri) + +osx:CONFIG -= app_bundle + +QT += quick testlib + +OTHER_FILES += \ + data/basic.qml + diff --git a/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp new file mode 100644 index 0000000000..256fa43d2e --- /dev/null +++ b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> + +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/qsgrendererinterface.h> + +#include "../../shared/util.h" + +#ifndef QT_NO_OPENGL +#include <QtGui/qopenglcontext.h> +#include <QtGui/qsurfaceformat.h> +#endif + +class tst_QQuickGraphicsInfo : public QQmlDataTest +{ + Q_OBJECT + +private slots: + void testProperties(); +}; + +void tst_QQuickGraphicsInfo::testProperties() +{ + QQuickView view; + view.setSource(QUrl::fromLocalFile("data/basic.qml")); + + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QSignalSpy spy(&view, SIGNAL(sceneGraphInitialized())); + spy.wait(); + + QObject* obj = view.rootObject(); + QVERIFY(obj); + + QSGRendererInterface *rif = view.rendererInterface(); + const int expectedAPI = rif ? rif->graphicsApi() : QSGRendererInterface::Unknown; + + QCOMPARE(obj->property("api").toInt(), expectedAPI); + +#ifndef QT_NO_OPENGL + if (expectedAPI == QSGRendererInterface::OpenGL) { + QCOMPARE(obj->property("shaderType").toInt(), int(QSGRendererInterface::GLSL)); + QVERIFY(view.openglContext()); + QSurfaceFormat format = view.openglContext()->format(); + QCOMPARE(obj->property("majorVersion").toInt(), format.majorVersion()); + QCOMPARE(obj->property("minorVersion").toInt(), format.minorVersion()); + QCOMPARE(obj->property("profile").toInt(), static_cast<int>(format.profile())); + QCOMPARE(obj->property("renderableType").toInt(), static_cast<int>(format.renderableType())); + } +#endif +} + +QTEST_MAIN(tst_QQuickGraphicsInfo) + +#include "tst_qquickgraphicsinfo.moc" diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp index 9274a1ac9e..d345163db5 100644 --- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp +++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp @@ -306,6 +306,7 @@ void tst_qquickimage::mirror() qreal width = 300; qreal height = 250; + qreal devicePixelRatio = 1.0; foreach (QQuickImage::FillMode fillMode, fillModes) { #if defined(Q_OS_BLACKBERRY) @@ -325,13 +326,15 @@ void tst_qquickimage::mirror() QImage screenshot = window->grabWindow(); screenshots[fillMode] = screenshot; + devicePixelRatio = window->devicePixelRatio(); } foreach (QQuickImage::FillMode fillMode, fillModes) { QPixmap srcPixmap; QVERIFY(srcPixmap.load(testFile("pattern.png"))); - QPixmap expected(width, height); + QPixmap expected(width * (int)devicePixelRatio, height * (int)devicePixelRatio); + expected.setDevicePixelRatio(devicePixelRatio); expected.fill(); QPainter p_e(&expected); QTransform transform; diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index a087efd6b8..169ef1cbab 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -2698,113 +2698,122 @@ void tst_QQuickItem::childrenRectBottomRightCorner() struct TestListener : public QQuickItemChangeListener { - TestListener(bool remove = false) : remove(remove) { reset(); } - - void itemGeometryChanged(QQuickItem *, const QRectF &newGeometry, const QRectF &) override { ++itemGeometryChanges; value = newGeometry; } - void itemSiblingOrderChanged(QQuickItem *) override { ++itemSiblingOrderChanges; } - void itemVisibilityChanged(QQuickItem *) override { ++itemVisibilityChanges; } - void itemOpacityChanged(QQuickItem *) override { ++itemOpacityChanges; } - void itemRotationChanged(QQuickItem *) override { ++itemRotationChanges; } - void itemImplicitWidthChanged(QQuickItem *) override { ++itemImplicitWidthChanges; } - void itemImplicitHeightChanged(QQuickItem *) override { ++itemImplicitHeightChanges; } + TestListener(bool remove = false) : remove(remove) { } + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange, const QRectF &diff) override + { + record(item, QQuickItemPrivate::Geometry, diff); + } + void itemSiblingOrderChanged(QQuickItem *item) override + { + record(item, QQuickItemPrivate::SiblingOrder); + } + void itemVisibilityChanged(QQuickItem *item) override + { + record(item, QQuickItemPrivate::Visibility); + } + void itemOpacityChanged(QQuickItem *item) override + { + record(item, QQuickItemPrivate::Opacity); + } + void itemRotationChanged(QQuickItem *item) override + { + record(item, QQuickItemPrivate::Rotation); + } + void itemImplicitWidthChanged(QQuickItem *item) override + { + record(item, QQuickItemPrivate::ImplicitWidth); + } + void itemImplicitHeightChanged(QQuickItem *item) override + { + record(item, QQuickItemPrivate::ImplicitHeight); + } void itemDestroyed(QQuickItem *item) override { - ++itemDestructions; - // QTBUG-53453 - if (remove) - QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed); + record(item, QQuickItemPrivate::Destroyed); } void itemChildAdded(QQuickItem *item, QQuickItem *child) override { - ++itemChildAdditions; - value = QVariant::fromValue(child); - // QTBUG-53453 - if (remove) - QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Children); + record(item, QQuickItemPrivate::Children, QVariant::fromValue(child)); } void itemChildRemoved(QQuickItem *item, QQuickItem *child) override { - ++itemChildRemovals; - value = QVariant::fromValue(child); - // QTBUG-53453 - if (remove) - QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Children); + record(item, QQuickItemPrivate::Children, QVariant::fromValue(child)); } void itemParentChanged(QQuickItem *item, QQuickItem *parent) override { - ++itemParentChanges; - value = QVariant::fromValue(parent); - // QTBUG-53453 - if (remove) - QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Parent); + record(item, QQuickItemPrivate::Parent, QVariant::fromValue(parent)); } QQuickAnchorsPrivate *anchorPrivate() override { return nullptr; } - void reset() + void record(QQuickItem *item, QQuickItemPrivate::ChangeType change, const QVariant &value = QVariant()) + { + changes += change; + values[change] = value; + // QTBUG-54732 + if (remove) + QQuickItemPrivate::get(item)->removeItemChangeListener(this, change); + } + + int count(QQuickItemPrivate::ChangeType change) const + { + return changes.count(change); + } + + QVariant value(QQuickItemPrivate::ChangeType change) const { - value = QVariant(); - itemGeometryChanges = 0; - itemSiblingOrderChanges = 0; - itemVisibilityChanges = 0; - itemOpacityChanges = 0; - itemDestructions = 0; - itemChildAdditions = 0; - itemChildRemovals = 0; - itemParentChanges = 0; - itemRotationChanges = 0; - itemImplicitWidthChanges = 0; - itemImplicitHeightChanges = 0; + return values.value(change); } bool remove; - QVariant value; - int itemGeometryChanges; - int itemSiblingOrderChanges; - int itemVisibilityChanges; - int itemOpacityChanges; - int itemDestructions; - int itemChildAdditions; - int itemChildRemovals; - int itemParentChanges; - int itemRotationChanges; - int itemImplicitWidthChanges; - int itemImplicitHeightChanges; + QList<QQuickItemPrivate::ChangeType> changes; + QHash<QQuickItemPrivate::ChangeType, QVariant> values; }; void tst_QQuickItem::changeListener() { - QQuickItem item; + QQuickWindow window; + window.show(); + QTest::qWaitForWindowExposed(&window); + + QQuickItem *item = new QQuickItem; TestListener itemListener; - QQuickItemPrivate::get(&item)->addItemChangeListener(&itemListener, QQuickItemPrivate::Geometry | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | - QQuickItemPrivate::Opacity | QQuickItemPrivate::Rotation); + QQuickItemPrivate::get(item)->addItemChangeListener(&itemListener, QQuickItemPrivate::ChangeTypes(0xffff)); + + item->setImplicitWidth(10); + QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitWidth), 1); + QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 1); + QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,10,0))); - item.setImplicitWidth(50); - QCOMPARE(itemListener.itemImplicitWidthChanges, 1); - QCOMPARE(itemListener.itemGeometryChanges, 1); - QCOMPARE(itemListener.value, QVariant(QRectF(0,0,50,0))); + item->setImplicitHeight(20); + QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitHeight), 1); + QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 2); + QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,0,20))); - item.setImplicitHeight(50); - QCOMPARE(itemListener.itemImplicitHeightChanges, 1); - QCOMPARE(itemListener.itemGeometryChanges, 2); - QCOMPARE(itemListener.value, QVariant(QRectF(0,0,50,50))); + item->setWidth(item->width() + 30); + QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 3); + QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,30,0))); - item.setWidth(100); - QCOMPARE(itemListener.itemGeometryChanges, 3); - QCOMPARE(itemListener.value, QVariant(QRectF(0,0,100,50))); + item->setHeight(item->height() + 40); + QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 4); + QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,0,40))); - item.setHeight(100); - QCOMPARE(itemListener.itemGeometryChanges, 4); - QCOMPARE(itemListener.value, QVariant(QRectF(0,0,100,100))); + item->setOpacity(0.5); + QCOMPARE(itemListener.count(QQuickItemPrivate::Opacity), 1); - item.setOpacity(0.5); - QCOMPARE(itemListener.itemOpacityChanges, 1); + item->setRotation(90); + QCOMPARE(itemListener.count(QQuickItemPrivate::Rotation), 1); - item.setRotation(90); - QCOMPARE(itemListener.itemRotationChanges, 1); + item->setParentItem(window.contentItem()); + QCOMPARE(itemListener.count(QQuickItemPrivate::Parent), 1); - QQuickItem *parent = new QQuickItem; + item->setVisible(false); + QCOMPARE(itemListener.count(QQuickItemPrivate::Visibility), 1); + + QQuickItemPrivate::get(item)->removeItemChangeListener(&itemListener, QQuickItemPrivate::ChangeTypes(0xffff)); + + QQuickItem *parent = new QQuickItem(window.contentItem()); TestListener parentListener; QQuickItemPrivate::get(parent)->addItemChangeListener(&parentListener, QQuickItemPrivate::Children); @@ -2816,52 +2825,79 @@ void tst_QQuickItem::changeListener() QQuickItemPrivate::get(child2)->addItemChangeListener(&child2Listener, QQuickItemPrivate::Parent | QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::Destroyed); child1->setParentItem(parent); - QCOMPARE(parentListener.itemChildAdditions, 1); - QCOMPARE(parentListener.value, QVariant::fromValue(child1)); - QCOMPARE(child1Listener.itemParentChanges, 1); - QCOMPARE(child1Listener.value, QVariant::fromValue(parent)); + QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 1); + QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child1)); + QCOMPARE(child1Listener.count(QQuickItemPrivate::Parent), 1); + QCOMPARE(child1Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue(parent)); child2->setParentItem(parent); - QCOMPARE(parentListener.itemChildAdditions, 2); - QCOMPARE(parentListener.value, QVariant::fromValue(child2)); - QCOMPARE(child2Listener.itemParentChanges, 1); - QCOMPARE(child2Listener.value, QVariant::fromValue(parent)); + QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 2); + QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child2)); + QCOMPARE(child2Listener.count(QQuickItemPrivate::Parent), 1); + QCOMPARE(child2Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue(parent)); child2->stackBefore(child1); - QCOMPARE(child1Listener.itemSiblingOrderChanges, 1); - QCOMPARE(child2Listener.itemSiblingOrderChanges, 1); + QCOMPARE(child1Listener.count(QQuickItemPrivate::SiblingOrder), 1); + QCOMPARE(child2Listener.count(QQuickItemPrivate::SiblingOrder), 1); child1->setParentItem(nullptr); - QCOMPARE(parentListener.itemChildRemovals, 1); - QCOMPARE(parentListener.value, QVariant::fromValue(child1)); - QCOMPARE(child1Listener.itemParentChanges, 2); - QCOMPARE(child1Listener.value, QVariant::fromValue<QQuickItem *>(nullptr)); + QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 3); + QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child1)); + QCOMPARE(child1Listener.count(QQuickItemPrivate::Parent), 2); + QCOMPARE(child1Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue<QQuickItem *>(nullptr)); delete child1; - QCOMPARE(child1Listener.itemDestructions, 1); + QCOMPARE(child1Listener.count(QQuickItemPrivate::Destroyed), 1); delete child2; - QCOMPARE(parentListener.itemChildRemovals, 2); - QCOMPARE(parentListener.value, QVariant::fromValue(child2)); - QCOMPARE(child2Listener.itemParentChanges, 2); - QCOMPARE(child2Listener.value, QVariant::fromValue<QQuickItem *>(nullptr)); - QCOMPARE(child2Listener.itemDestructions, 1); + QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 4); + QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child2)); + QCOMPARE(child2Listener.count(QQuickItemPrivate::Parent), 2); + QCOMPARE(child2Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue<QQuickItem *>(nullptr)); + QCOMPARE(child2Listener.count(QQuickItemPrivate::Destroyed), 1); QQuickItemPrivate::get(parent)->removeItemChangeListener(&parentListener, QQuickItemPrivate::Children); QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); - // QTBUG-53453: all listeners should get invoked even if they remove themselves while iterating the listeners + // QTBUG-54732: all listeners should get invoked even if they remove themselves while iterating the listeners QList<TestListener *> listeners; for (int i = 0; i < 5; ++i) listeners << new TestListener(true); + // itemVisibilityChanged x 5 + foreach (TestListener *listener, listeners) + QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::Visibility); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); + parent->setVisible(false); + foreach (TestListener *listener, listeners) + QCOMPARE(listener->count(QQuickItemPrivate::Visibility), 1); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); + + // itemRotationChanged x 5 + foreach (TestListener *listener, listeners) + QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::Rotation); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); + parent->setRotation(90); + foreach (TestListener *listener, listeners) + QCOMPARE(listener->count(QQuickItemPrivate::Rotation), 1); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); + + // itemOpacityChanged x 5 + foreach (TestListener *listener, listeners) + QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::Opacity); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); + parent->setOpacity(0.5); + foreach (TestListener *listener, listeners) + QCOMPARE(listener->count(QQuickItemPrivate::Opacity), 1); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); + // itemChildAdded() x 5 foreach (TestListener *listener, listeners) QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::Children); QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); child1 = new QQuickItem(parent); foreach (TestListener *listener, listeners) - QCOMPARE(listener->itemChildAdditions, 1); + QCOMPARE(listener->count(QQuickItemPrivate::Children), 1); QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); // itemParentChanged() x 5 @@ -2870,9 +2906,36 @@ void tst_QQuickItem::changeListener() QCOMPARE(QQuickItemPrivate::get(child1)->changeListeners.count(), listeners.count()); child1->setParentItem(nullptr); foreach (TestListener *listener, listeners) - QCOMPARE(listener->itemParentChanges, 1); + QCOMPARE(listener->count(QQuickItemPrivate::Parent), 1); QCOMPARE(QQuickItemPrivate::get(child1)->changeListeners.count(), 0); + // itemImplicitWidthChanged() x 5 + foreach (TestListener *listener, listeners) + QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::ImplicitWidth); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); + parent->setImplicitWidth(parent->implicitWidth() + 1); + foreach (TestListener *listener, listeners) + QCOMPARE(listener->count(QQuickItemPrivate::ImplicitWidth), 1); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); + + // itemImplicitHeightChanged() x 5 + foreach (TestListener *listener, listeners) + QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::ImplicitHeight); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); + parent->setImplicitHeight(parent->implicitHeight() + 1); + foreach (TestListener *listener, listeners) + QCOMPARE(listener->count(QQuickItemPrivate::ImplicitHeight), 1); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); + + // itemGeometryChanged() x 5 + foreach (TestListener *listener, listeners) + QQuickItemPrivate::get(parent)->addItemChangeListener(listener, QQuickItemPrivate::Geometry); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); + parent->setWidth(parent->width() + 1); + foreach (TestListener *listener, listeners) + QCOMPARE(listener->count(QQuickItemPrivate::Geometry), 1); + QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); + // itemChildRemoved() x 5 child1->setParentItem(parent); foreach (TestListener *listener, listeners) @@ -2880,7 +2943,7 @@ void tst_QQuickItem::changeListener() QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); delete child1; foreach (TestListener *listener, listeners) - QCOMPARE(listener->itemChildRemovals, 1); + QCOMPARE(listener->count(QQuickItemPrivate::Children), 2); QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); // itemDestroyed() x 5 @@ -2889,7 +2952,7 @@ void tst_QQuickItem::changeListener() QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); delete parent; foreach (TestListener *listener, listeners) - QCOMPARE(listener->itemDestructions, 1); + QCOMPARE(listener->count(QQuickItemPrivate::Destroyed), 1); } // QTBUG-13893 @@ -3215,7 +3278,7 @@ void tst_QQuickItem::grab() QVERIFY(root); QQuickItem *item = root->findChild<QQuickItem *>("myItem"); QVERIFY(item); - +#ifndef QT_NO_OPENGL { // Default size (item is 100x100) QSharedPointer<QQuickItemGrabResult> result = item->grabToImage(); QSignalSpy spy(result.data(), SIGNAL(ready())); @@ -3236,7 +3299,7 @@ void tst_QQuickItem::grab() QCOMPARE(image.pixel(0, 0), qRgb(255, 0, 0)); QCOMPARE(image.pixel(49, 49), qRgb(0, 0, 255)); } - +#endif } void tst_QQuickItem::isAncestorOf() diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp index 92b7196919..2576a1b0fc 100644 --- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp +++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp @@ -30,6 +30,7 @@ #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> +#include <QtQuick/qsgrendererinterface.h> #include <QtGui/qopenglcontext.h> #include <QtGui/qopenglfunctions.h> @@ -60,9 +61,10 @@ private slots: void initTestCase() Q_DECL_OVERRIDE; void layerEnabled(); void layerSmooth(); +#ifndef QT_NO_OPENGL void layerMipmap(); void layerEffect(); - +#endif void layerVisibility_data(); void layerVisibility(); @@ -90,17 +92,20 @@ private: bool m_isMesaSoftwareRasterizer; int m_mesaVersion; + bool m_isOpenGLRenderer; }; tst_QQuickItemLayer::tst_QQuickItemLayer() : m_isMesaSoftwareRasterizer(false) , m_mesaVersion(0) + , m_isOpenGLRenderer(true) { } void tst_QQuickItemLayer::initTestCase() { QQmlDataTest::initTestCase(); +#ifndef QT_NO_OPENGL QWindow window; QOpenGLContext context; window.setSurfaceType(QWindow::OpenGLSurface); @@ -129,6 +134,13 @@ void tst_QQuickItemLayer::initTestCase() m_mesaVersion = QT_VERSION_CHECK(major, minor, patch); } } + window.create(); +#endif + QQuickView view; + view.showNormal(); + QTest::qWaitForWindowExposed(&view); + if (view.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL) + m_isOpenGLRenderer = false; } // The test draws a red and a blue box next to each other and tests that the @@ -165,8 +177,7 @@ void tst_QQuickItemLayer::layerEnabled() QVERIFY(fb.pixel(0, 0) != fb.pixel(0, fb.height() - 1)); } - - +#ifndef QT_NO_OPENGL // The test draws a one pixel wide line and scales it down by more than a a factor 2 // If mipmpping works, the pixels should be gray, not white or black @@ -192,8 +203,7 @@ void tst_QQuickItemLayer::layerEffect() QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0)); QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0xff, 0)); } - - +#endif // The test draws a rectangle and verifies that there is padding on each side // as the source rect spans outside the item. The padding is verified using @@ -203,6 +213,9 @@ void tst_QQuickItemLayer::layerSourceRect() if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QImage fb = runTest("SourceRect.qml"); // Check that the edges are converted to blue @@ -223,6 +236,10 @@ void tst_QQuickItemLayer::layerIsTextureProvider() { if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QImage fb = runTest("TextureProvider.qml"); QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0)); QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0xff, 0)); @@ -256,6 +273,9 @@ void tst_QQuickItemLayer::layerVisibility() if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QFETCH(bool, visible); QFETCH(bool, effect); QFETCH(qreal, opacity); @@ -304,6 +324,9 @@ void tst_QQuickItemLayer::layerZOrder() if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QFETCH(bool, effect); QQuickView view; @@ -338,6 +361,9 @@ void tst_QQuickItemLayer::changeZOrder() if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QFETCH(bool, layered); QFETCH(bool, effect); @@ -405,6 +431,10 @@ void tst_QQuickItemLayer::changeSamplerName() { if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QImage fb = runTest("SamplerNameChange.qml"); QCOMPARE(fb.pixel(0, 0), qRgb(0, 0, 0xff)); } @@ -413,6 +443,9 @@ void tst_QQuickItemLayer::itemEffect() { if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QImage fb = runTest("ItemEffect.qml"); QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0)); QCOMPARE(fb.pixel(199, 0), qRgb(0xff, 0, 0)); @@ -448,6 +481,9 @@ void tst_QQuickItemLayer::textureMirroring() { QFETCH(int, mirroring); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QQuickView view; view.setSource(testFileUrl("TextureMirroring.qml")); diff --git a/tests/auto/quick/qquicklistview/BLACKLIST b/tests/auto/quick/qquicklistview/BLACKLIST index 269696ce8c..d259c11219 100644 --- a/tests/auto/quick/qquicklistview/BLACKLIST +++ b/tests/auto/quick/qquicklistview/BLACKLIST @@ -2,3 +2,6 @@ * [enforceRange_withoutHighlight] osx +#QTBUG-53863 +[populateTransitions] +opensuse-42.1 diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index fe22a238b2..77af4796b6 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -213,7 +213,7 @@ void tst_QQuickLoader::sourceOrComponent_data() QTest::newRow("source with encoded subdir binding") << "source" << "source: encodeURIComponent('subdir/Test.qml')\n" << testFileUrl("subdir/Test.qml") << ""; QTest::newRow("sourceComponent") << "component" << "Component { id: comp; Rectangle { width: 100; height: 50 } }\n sourceComponent: comp\n" << QUrl() << ""; QTest::newRow("invalid source") << "source" << "source: 'IDontExist.qml'\n" << testFileUrl("IDontExist.qml") - << QString(testFileUrl("IDontExist.qml").toString() + ": File not found"); + << QString(testFileUrl("IDontExist.qml").toString() + ": No such file or directory"); } void tst_QQuickLoader::clear() @@ -748,7 +748,7 @@ void tst_QQuickLoader::initialPropertyValuesError_data() << (QStringList() << QString(testFileUrl("initialPropertyValues.error.1.qml").toString() + ":6:5: QML Loader: setSource: value is not an object")); QTest::newRow("nonexistent source url") << testFileUrl("initialPropertyValues.error.2.qml") - << (QStringList() << QString(testFileUrl("NonexistentSourceComponent.qml").toString() + ": File not found")); + << (QStringList() << QString(testFileUrl("NonexistentSourceComponent.qml").toString() + ": No such file or directory")); QTest::newRow("invalid source url") << testFileUrl("initialPropertyValues.error.3.qml") << (QStringList() << QString(testFileUrl("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error")); @@ -901,7 +901,7 @@ void tst_QQuickLoader::asynchronous_data() << QStringList(); QTest::newRow("Non-existent component") << testFileUrl("IDoNotExist.qml") - << (QStringList() << QString(testFileUrl("IDoNotExist.qml").toString() + ": File not found")); + << (QStringList() << QString(testFileUrl("IDoNotExist.qml").toString() + ": No such file or directory")); QTest::newRow("Invalid component") << testFileUrl("InvalidSourceComponent.qml") << (QStringList() << QString(testFileUrl("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error")); diff --git a/tests/auto/quick/qquickmousearea/data/qtbug54019.qml b/tests/auto/quick/qquickmousearea/data/qtbug54019.qml new file mode 100644 index 0000000000..75cca2691a --- /dev/null +++ b/tests/auto/quick/qquickmousearea/data/qtbug54019.qml @@ -0,0 +1,21 @@ +import QtQuick 2.7 + +Item { + width: 200 + height: 200 + MouseArea { + id: ma + property string str: "foo!" + width: 150; height: 150 + hoverEnabled: true + + Rectangle { + anchors.fill: parent + color: ma.containsMouse ? "lightsteelblue" : "gray" + } + Text { + text: ma.str + textFormat: Text.PlainText // consequently Text does not care about hover events + } + } +} diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index aa1474df91..9c627ad69c 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -29,6 +29,7 @@ #include <QtTest/QtTest> #include <QtTest/QSignalSpy> #include <QtQuick/private/qquickdrag_p.h> +#include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquickmousearea_p.h> #include <QtQuick/private/qquickrectangle_p.h> #include <private/qquickflickable_p.h> @@ -107,6 +108,7 @@ private slots: void hoverPropagation(); void hoverVisible(); void hoverAfterPress(); + void subtreeHoverEnabled(); void disableAfterPress(); void onWheel(); void transformedMouseArea_data(); @@ -125,6 +127,9 @@ private slots: void ignoreBySource(); private: + int startDragDistance() const { + return QGuiApplication::styleHints()->startDragDistance(); + } void acceptedButton_data(); void rejectedButton_data(); QTouchDevice *device; @@ -320,7 +325,8 @@ void tst_QQuickMouseArea::dragging() QVERIFY(!drag->active()); - QTest::mousePress(&window, button, 0, QPoint(100,100)); + QPoint p = QPoint(100,100); + QTest::mousePress(&window, button, 0, p); QVERIFY(!drag->active()); QCOMPARE(blackRect->x(), 50.0); @@ -331,18 +337,32 @@ void tst_QQuickMouseArea::dragging() // The item is moved relative to the position of the mouse when the drag // was triggered, this prevents a sudden change in position when the drag // threshold is exceeded. - QTest::mouseMove(&window, QPoint(111,111), 50); - QTest::mouseMove(&window, QPoint(116,116), 50); - QTest::mouseMove(&window, QPoint(122,122), 50); + int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); + + // move the minimum distance to activate drag + p += QPoint(dragThreshold + 1, dragThreshold + 1); + QTest::mouseMove(&window, p); + QVERIFY(!drag->active()); + + // from here on move the item + p += QPoint(1, 1); + QTest::mouseMove(&window, p); + QTRY_VERIFY(drag->active()); + // on macOS the cursor movement is going through a native event which + // means that it can actually take some time to show + QTRY_COMPARE(blackRect->x(), 50.0 + 1); + QCOMPARE(blackRect->y(), 50.0 + 1); + + p += QPoint(10, 10); + QTest::mouseMove(&window, p); QTRY_VERIFY(drag->active()); QTRY_COMPARE(blackRect->x(), 61.0); QCOMPARE(blackRect->y(), 61.0); - QTest::mouseRelease(&window, button, 0, QPoint(122,122)); - + QTest::mouseRelease(&window, button, 0, p); QTRY_VERIFY(!drag->active()); - QCOMPARE(blackRect->x(), 61.0); + QTRY_COMPARE(blackRect->x(), 61.0); QCOMPARE(blackRect->y(), 61.0); } @@ -531,15 +551,18 @@ void tst_QQuickMouseArea::cancelDragging() QVERIFY(!drag->active()); - QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100)); + QPoint p = QPoint(100,100); + QTest::mousePress(&window, Qt::LeftButton, 0, p); QVERIFY(!drag->active()); QCOMPARE(blackRect->x(), 50.0); QCOMPARE(blackRect->y(), 50.0); - QTest::mouseMove(&window, QPoint(111,111), 50); - QTest::mouseMove(&window, QPoint(116,116), 50); - QTest::mouseMove(&window, QPoint(122,122), 50); + p += QPoint(startDragDistance() + 1, 0); + QTest::mouseMove(&window, p); + + p += QPoint(11, 11); + QTest::mouseMove(&window, p); QTRY_VERIFY(drag->active()); QTRY_COMPARE(blackRect->x(), 61.0); @@ -574,7 +597,8 @@ void tst_QQuickMouseArea::setDragOnPressed() QQuickItem *target = mouseArea->findChild<QQuickItem*>("target"); QVERIFY(target); - QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100)); + QPoint p = QPoint(100, 100); + QTest::mousePress(&window, Qt::LeftButton, 0, p); QQuickDrag *drag = mouseArea->drag(); QVERIFY(drag); @@ -586,19 +610,17 @@ void tst_QQuickMouseArea::setDragOnPressed() // First move event triggers drag, second is acted upon. // This is due to possibility of higher stacked area taking precedence. - QTest::mouseMove(&window, QPoint(111,102)); - QTest::qWait(50); - QTest::mouseMove(&window, QPoint(122,122)); - QTest::qWait(50); + p += QPoint(startDragDistance() + 1, 0); + QTest::mouseMove(&window, p); - QVERIFY(drag->active()); - QCOMPARE(target->x(), 61.0); + p += QPoint(11, 0); + QTest::mouseMove(&window, p); + QTRY_VERIFY(drag->active()); + QTRY_COMPARE(target->x(), 61.0); QCOMPARE(target->y(), 50.0); - QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(122,122)); - QTest::qWait(50); - - QVERIFY(!drag->active()); + QTest::mouseRelease(&window, Qt::LeftButton, 0, p); + QTRY_VERIFY(!drag->active()); QCOMPARE(target->x(), 61.0); QCOMPARE(target->y(), 50.0); } @@ -791,14 +813,14 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate() QGuiApplication::sendEvent(&window, &pressEvent); - QVERIFY(window.rootObject()->property("pressed").toBool()); + QTRY_VERIFY(window.rootObject()->property("pressed").toBool()); QVERIFY(!window.rootObject()->property("canceled").toBool()); QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease); QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks); if (doubleClick) { QGuiApplication::sendEvent(&window, &releaseEvent); - QVERIFY(!window.rootObject()->property("pressed").toBool()); + QTRY_VERIFY(!window.rootObject()->property("pressed").toBool()); QVERIFY(!window.rootObject()->property("canceled").toBool()); QCOMPARE(window.rootObject()->property("released").toInt(), ++expectedRelease); QCOMPARE(window.rootObject()->property("clicked").toInt(), ++expectedClicks); @@ -807,7 +829,7 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate() QMouseEvent pressEvent2(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); QGuiApplication::sendEvent(&window, &pressEvent2); - QVERIFY(window.rootObject()->property("pressed").toBool()); + QTRY_VERIFY(window.rootObject()->property("pressed").toBool()); QVERIFY(!window.rootObject()->property("canceled").toBool()); QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease); QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks); @@ -819,23 +841,21 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate() secondWindow->setProperty("visible", true); QTest::qWaitForWindowExposed(secondWindow); - QVERIFY(!window.rootObject()->property("pressed").toBool()); + QTRY_VERIFY(!window.rootObject()->property("pressed").toBool()); QVERIFY(window.rootObject()->property("canceled").toBool()); QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease); QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks); //press again QGuiApplication::sendEvent(&window, &pressEvent); - QVERIFY(window.rootObject()->property("pressed").toBool()); + QTRY_VERIFY(window.rootObject()->property("pressed").toBool()); QVERIFY(!window.rootObject()->property("canceled").toBool()); QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease); QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks); - QTest::qWait(200); - //release QGuiApplication::sendEvent(&window, &releaseEvent); - QVERIFY(!window.rootObject()->property("pressed").toBool()); + QTRY_VERIFY(!window.rootObject()->property("pressed").toBool()); QVERIFY(!window.rootObject()->property("canceled").toBool()); QCOMPARE(window.rootObject()->property("released").toInt(), ++expectedRelease); QCOMPARE(window.rootObject()->property("clicked").toInt(), ++expectedClicks); @@ -993,48 +1013,60 @@ void tst_QQuickMouseArea::preventStealing() QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*))); - QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(80, 80)); + QPoint p = QPoint(80, 80); + QTest::mousePress(&window, Qt::LeftButton, 0, p); // Without preventStealing, mouse movement over MouseArea would // cause the Flickable to steal mouse and trigger content movement. - QTest::mouseMove(&window,QPoint(69,69)); - QTest::mouseMove(&window,QPoint(58,58)); - QTest::mouseMove(&window,QPoint(47,47)); + p += QPoint(-startDragDistance() * 2, -startDragDistance() * 2); + QTest::mouseMove(&window, p); + p += QPoint(-10, -10); + QTest::mouseMove(&window, p); + p += QPoint(-10, -10); + QTest::mouseMove(&window, p); + p += QPoint(-10, -10); + QTest::mouseMove(&window, p); - // We should have received all three move events - QCOMPARE(mousePositionSpy.count(), 3); + // We should have received all four move events + QTRY_COMPARE(mousePositionSpy.count(), 4); + mousePositionSpy.clear(); QVERIFY(mouseArea->pressed()); // Flickable content should not have moved. QCOMPARE(flickable->contentX(), 0.); QCOMPARE(flickable->contentY(), 0.); - QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(47, 47)); + QTest::mouseRelease(&window, Qt::LeftButton, 0, p); // Now allow stealing and confirm Flickable does its thing. window.rootObject()->setProperty("stealing", false); - QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(80, 80)); + p = QPoint(80, 80); + QTest::mousePress(&window, Qt::LeftButton, 0, p); // Without preventStealing, mouse movement over MouseArea would // cause the Flickable to steal mouse and trigger content movement. - QTest::mouseMove(&window,QPoint(69,69)); - QTest::mouseMove(&window,QPoint(58,58)); - QTest::mouseMove(&window,QPoint(47,47)); + p += QPoint(-startDragDistance() * 2, -startDragDistance() * 2); + QTest::mouseMove(&window, p); + p += QPoint(-10, -10); + QTest::mouseMove(&window, p); + p += QPoint(-10, -10); + QTest::mouseMove(&window, p); + p += QPoint(-10, -10); + QTest::mouseMove(&window, p); // We should only have received the first move event - QCOMPARE(mousePositionSpy.count(), 4); + QTRY_COMPARE(mousePositionSpy.count(), 1); // Our press should be taken away QVERIFY(!mouseArea->pressed()); - // Flickable content should have moved. + // Flickable swallows the first move, then moves 2*10 px + QTRY_COMPARE(flickable->contentX(), 20.); + QCOMPARE(flickable->contentY(), 20.); - QCOMPARE(flickable->contentX(), 11.); - QCOMPARE(flickable->contentY(), 11.); - - QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(50, 50)); + QTest::mouseRelease(&window, Qt::LeftButton, 0, p); } void tst_QQuickMouseArea::clickThrough() @@ -1286,6 +1318,26 @@ void tst_QQuickMouseArea::hoverAfterPress() QCOMPARE(mouseArea->hovered(), false); } +void tst_QQuickMouseArea::subtreeHoverEnabled() +{ + QQuickView window; + QByteArray errorMessage; + QVERIFY2(initView(window, testFileUrl("qtbug54019.qml"), true, &errorMessage), errorMessage.constData()); + QQuickItem *root = window.rootObject(); + QVERIFY(root != 0); + + QQuickMouseArea *mouseArea = root->findChild<QQuickMouseArea*>(); + QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(root); + QVERIFY(mouseArea != 0); + QTest::mouseMove(&window, QPoint(10, 160)); + QCOMPARE(mouseArea->hovered(), false); + QVERIFY(rootPrivate->subtreeHoverEnabled); + QTest::mouseMove(&window, QPoint(10, 10)); + QCOMPARE(mouseArea->hovered(), true); + QTest::mouseMove(&window, QPoint(160, 10)); + QCOMPARE(mouseArea->hovered(), false); +} + void tst_QQuickMouseArea::disableAfterPress() { QQuickView window; @@ -1310,9 +1362,8 @@ void tst_QQuickMouseArea::disableAfterPress() QCOMPARE(blackRect, drag->target()); QVERIFY(!drag->active()); - - QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100)); - + QPoint p = QPoint(100,100); + QTest::mousePress(&window, Qt::LeftButton, 0, p); QTRY_COMPARE(mousePressSpy.count(), 1); QVERIFY(!drag->active()); @@ -1322,22 +1373,24 @@ void tst_QQuickMouseArea::disableAfterPress() // First move event triggers drag, second is acted upon. // This is due to possibility of higher stacked area taking precedence. - QTest::mouseMove(&window, QPoint(111,111)); - QTest::qWait(50); - QTest::mouseMove(&window, QPoint(122,122)); + p += QPoint(startDragDistance() + 1, 0); + QTest::mouseMove(&window, p); + p += QPoint(11, 11); + QTest::mouseMove(&window, p); QTRY_COMPARE(mousePositionSpy.count(), 2); - QVERIFY(drag->active()); - QCOMPARE(blackRect->x(), 61.0); + QTRY_VERIFY(drag->active()); + QTRY_COMPARE(blackRect->x(), 61.0); QCOMPARE(blackRect->y(), 61.0); mouseArea->setEnabled(false); // move should still be acted upon - QTest::mouseMove(&window, QPoint(133,133)); - QTest::qWait(50); - QTest::mouseMove(&window, QPoint(144,144)); + p += QPoint(11, 11); + QTest::mouseMove(&window, p); + p += QPoint(11, 11); + QTest::mouseMove(&window, p); QTRY_COMPARE(mousePositionSpy.count(), 4); @@ -1348,7 +1401,7 @@ void tst_QQuickMouseArea::disableAfterPress() QVERIFY(mouseArea->pressed()); QVERIFY(mouseArea->hovered()); - QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(144,144)); + QTest::mouseRelease(&window, Qt::LeftButton, 0, p); QTRY_COMPARE(mouseReleaseSpy.count(), 1); @@ -1605,36 +1658,39 @@ void tst_QQuickMouseArea::changeAxis() QVERIFY(!drag->active()); // Start a diagonal drag - QTest::mousePress(&view, Qt::LeftButton, 0, QPoint(100, 100)); + QPoint p = QPoint(100, 100); + QTest::mousePress(&view, Qt::LeftButton, 0, p); QVERIFY(!drag->active()); QCOMPARE(blackRect->x(), 50.0); QCOMPARE(blackRect->y(), 50.0); - QTest::mouseMove(&view, QPoint(111, 111)); - QTest::qWait(50); - QTest::mouseMove(&view, QPoint(122, 122)); - + p += QPoint(startDragDistance() + 1, startDragDistance() + 1); + QTest::mouseMove(&view, p); + p += QPoint(11, 11); + QTest::mouseMove(&view, p); QTRY_VERIFY(drag->active()); - QCOMPARE(blackRect->x(), 61.0); + QTRY_COMPARE(blackRect->x(), 61.0); QCOMPARE(blackRect->y(), 61.0); QCOMPARE(drag->axis(), QQuickDrag::XAndYAxis); /* When blackRect.x becomes bigger than 75, the drag axis is changed to * Drag.YAxis by the QML code. Verify that this happens, and that the drag * movement is effectively constrained to the Y axis. */ - QTest::mouseMove(&view, QPoint(144, 144)); + p += QPoint(22, 22); + QTest::mouseMove(&view, p); QTRY_COMPARE(blackRect->x(), 83.0); QTRY_COMPARE(blackRect->y(), 83.0); QTRY_COMPARE(drag->axis(), QQuickDrag::YAxis); - QTest::mouseMove(&view, QPoint(155, 155)); + p += QPoint(11, 11); + QTest::mouseMove(&view, p); QTRY_COMPARE(blackRect->y(), 94.0); QCOMPARE(blackRect->x(), 83.0); - QTest::mouseRelease(&view, Qt::LeftButton, 0, QPoint(155, 155)); + QTest::mouseRelease(&view, Qt::LeftButton, 0, p); QTRY_VERIFY(!drag->active()); QCOMPARE(blackRect->x(), 83.0); @@ -1684,11 +1740,17 @@ void tst_QQuickMouseArea::moveAndReleaseWithoutPress() QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100)); + // the press was not accepted, make sure there is no move or release event QTest::mouseMove(&window, QPoint(110,110), 50); - QTRY_COMPARE(root->property("hadMove").toBool(), false); + + // use qwait here because we want to make sure an event does NOT happen + // the test fails if the default state changes, while it shouldn't + QTest::qWait(100); + QCOMPARE(root->property("hadMove").toBool(), false); QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(110,110)); - QTRY_COMPARE(root->property("hadRelease").toBool(), false); + QTest::qWait(100); + QCOMPARE(root->property("hadRelease").toBool(), false); } void tst_QQuickMouseArea::nestedStopAtBounds_data() @@ -1840,33 +1902,41 @@ void tst_QQuickMouseArea::ignoreBySource() QVERIFY(flickable); // MouseArea should grab the press because it's interested in non-synthesized mouse events - QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(80, 80)); + QPoint p = QPoint(80, 80); + QTest::mousePress(&window, Qt::LeftButton, 0, p); QVERIFY(window.mouseGrabberItem() == mouseArea); // That was a real mouse event QVERIFY(root->property("lastEventSource").toInt() == Qt::MouseEventNotSynthesized); // Flickable content should not move - QTest::mouseMove(&window,QPoint(69,69)); - QTest::mouseMove(&window,QPoint(58,58)); - QTest::mouseMove(&window,QPoint(47,47)); + p -= QPoint(startDragDistance() + 1, startDragDistance() + 1); + QTest::mouseMove(&window, p); + p -= QPoint(11, 11); + QTest::mouseMove(&window, p); + p -= QPoint(11, 11); + QTest::mouseMove(&window, p); QCOMPARE(flickable->contentX(), 0.); QCOMPARE(flickable->contentY(), 0.); - QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(47, 47)); + QTest::mouseRelease(&window, Qt::LeftButton, 0, p); // Now try touch events and confirm that MouseArea ignores them, while Flickable does its thing - - QTest::touchEvent(&window, device).press(0, QPoint(80, 80), &window); + p = QPoint(80, 80); + QTest::touchEvent(&window, device).press(0, p, &window); QQuickTouchUtils::flush(&window); QVERIFY(window.mouseGrabberItem() != mouseArea); // That was a fake mouse event QCOMPARE(root->property("lastEventSource").toInt(), int(Qt::MouseEventSynthesizedByQt)); - QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window); - QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window); - QTest::touchEvent(&window, device).move(0, QPoint(47,47), &window); + p -= QPoint(startDragDistance() + 1, startDragDistance() + 1); + QTest::touchEvent(&window, device).move(0, p, &window); + p -= QPoint(11, 11); + QTest::touchEvent(&window, device).move(0, p, &window); + p -= QPoint(11, 11); + QTest::touchEvent(&window, device).move(0, p, &window); + QQuickTouchUtils::flush(&window); QCOMPARE(window.mouseGrabberItem(), flickable); - QTest::touchEvent(&window, device).release(0, QPoint(47,47), &window); + QTest::touchEvent(&window, device).release(0, p, &window); QQuickTouchUtils::flush(&window); // Flickable content should have moved @@ -1881,15 +1951,19 @@ void tst_QQuickMouseArea::ignoreBySource() // MouseArea should ignore the press because it's interested in synthesized mouse events - QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(80, 80)); + p = QPoint(80, 80); + QTest::mousePress(&window, Qt::LeftButton, 0, p); QVERIFY(window.mouseGrabberItem() != mouseArea); // That was a real mouse event QVERIFY(root->property("lastEventSource").toInt() == Qt::MouseEventNotSynthesized); // Flickable content should move - QTest::mouseMove(&window,QPoint(69,69)); - QTest::mouseMove(&window,QPoint(58,58)); - QTest::mouseMove(&window,QPoint(47,47)); + p -= QPoint(startDragDistance() + 1, startDragDistance() + 1); + QTest::mouseMove(&window, p); + p -= QPoint(11, 11); + QTest::mouseMove(&window, p); + p -= QPoint(11, 11); + QTest::mouseMove(&window, p); QTRY_VERIFY(flickable->contentX() > 1); QVERIFY(flickable->contentY() > 1); @@ -1898,13 +1972,16 @@ void tst_QQuickMouseArea::ignoreBySource() flickable->setContentY(0); // Now try touch events and confirm that MouseArea gets them, while Flickable doesn't - - QTest::touchEvent(&window, device).press(0, QPoint(80, 80), &window); + p = QPoint(80, 80); + QTest::touchEvent(&window, device).press(0, p, &window); QQuickTouchUtils::flush(&window); QCOMPARE(window.mouseGrabberItem(), mouseArea); - QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window); - QTest::touchEvent(&window, device).move(0, QPoint(69,69), &window); - QTest::touchEvent(&window, device).move(0, QPoint(47,47), &window); + p -= QPoint(startDragDistance() + 1, startDragDistance() + 1); + QTest::touchEvent(&window, device).move(0, p, &window); + p -= QPoint(11, 11); + QTest::touchEvent(&window, device).move(0, p, &window); + p -= QPoint(11, 11); + QTest::touchEvent(&window, device).move(0, p, &window); QQuickTouchUtils::flush(&window); QCOMPARE(window.mouseGrabberItem(), mouseArea); QTest::touchEvent(&window, device).release(0, QPoint(47,47), &window); diff --git a/tests/auto/quick/qquickpainteditem/tst_qquickpainteditem.cpp b/tests/auto/quick/qquickpainteditem/tst_qquickpainteditem.cpp index 1a04526f61..44d7b40ed9 100644 --- a/tests/auto/quick/qquickpainteditem/tst_qquickpainteditem.cpp +++ b/tests/auto/quick/qquickpainteditem/tst_qquickpainteditem.cpp @@ -32,8 +32,11 @@ #include <QtQuick/qquickview.h> #include <private/qquickitem_p.h> +#ifndef QT_NO_OPENGL #include <private/qsgdefaultpainternode_p.h> - +#else +#include <private/qsgsoftwarepainternode_p.h> +#endif class tst_QQuickPaintedItem: public QObject { Q_OBJECT @@ -70,7 +73,7 @@ public: ++paintRequests; clipRect = painter->clipBoundingRect(); } - +#ifndef QT_NO_OPENGL QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) { paintNode = static_cast<QSGDefaultPainterNode *>(QQuickPaintedItem::updatePaintNode(oldNode, data)); @@ -78,6 +81,15 @@ public: } QSGDefaultPainterNode *paintNode; +#else + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) + { + paintNode = static_cast<QSGSoftwarePainterNode *>(QQuickPaintedItem::updatePaintNode(oldNode, data)); + return paintNode; + } + + QSGSoftwarePainterNode *paintNode; +#endif int paintRequests; QRectF clipRect; }; diff --git a/tests/auto/quick/qquickpincharea/data/pinchproperties.qml b/tests/auto/quick/qquickpincharea/data/pinchproperties.qml index 37d706fc8e..c5daf6cbfe 100644 --- a/tests/auto/quick/qquickpincharea/data/pinchproperties.qml +++ b/tests/auto/quick/qquickpincharea/data/pinchproperties.qml @@ -2,7 +2,7 @@ import QtQuick 2.0 Rectangle { id: whiteRect property variant center - property real scale + property real scale: -1.0 property int pointCount: 0 property bool pinchActive: false width: 240; height: 320 diff --git a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp index aee35b4b90..1d7273f6df 100644 --- a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp +++ b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp @@ -286,6 +286,7 @@ void tst_QQuickPinchArea::pan() QPoint p1(80, 80); QPoint p2(100, 100); { + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device); pinchSequence.press(0, p1, window).commit(); QQuickTouchUtils::flush(window); @@ -293,23 +294,63 @@ void tst_QQuickPinchArea::pan() // we have to reuse the same pinchSequence object. pinchSequence.stationary(0).press(1, p2, window).commit(); QQuickTouchUtils::flush(window); - p1 += QPoint(10,10); - p2 += QPoint(10,10); - pinchSequence.move(0, p1,window).move(1, p2,window).commit(); + QVERIFY(!root->property("pinchActive").toBool()); + QCOMPARE(root->property("scale").toReal(), -1.0); + + p1 += QPoint(dragThreshold - 1, 0); + p2 += QPoint(dragThreshold - 1, 0); + pinchSequence.move(0, p1, window).move(1, p2, window).commit(); QQuickTouchUtils::flush(window); + // movement < dragThreshold: pinch not yet active + QVERIFY(!root->property("pinchActive").toBool()); + QCOMPARE(root->property("scale").toReal(), -1.0); - QCOMPARE(root->property("scale").toReal(), 1.0); + // exactly the dragThreshold: pinch starts + p1 += QPoint(1, 0); + p2 += QPoint(1, 0); + pinchSequence.move(0, p1, window).move(1, p2, window).commit(); + QQuickTouchUtils::flush(window); QVERIFY(root->property("pinchActive").toBool()); + QCOMPARE(root->property("scale").toReal(), 1.0); - p1 += QPoint(10,10); - p2 += QPoint(10,10); - pinchSequence.move(0, p1,window).move(1, p2,window).commit(); + // Calculation of the center point is tricky at first: + // center point of the two touch points in item coordinates: + // scene coordinates: (80, 80) + (dragThreshold, 0), (100, 100) + (dragThreshold, 0) + // = ((180+dT)/2, 180/2) = (90+dT, 90) + // item coordinates: (scene) - (50, 50) = (40+dT, 40) + QCOMPARE(root->property("center").toPointF(), QPointF(40 + dragThreshold, 40)); + // pan started, but no actual movement registered yet: + // blackrect starts at 50,50 + QCOMPARE(blackRect->x(), 50.0); + QCOMPARE(blackRect->y(), 50.0); + + p1 += QPoint(10, 0); + p2 += QPoint(10, 0); + pinchSequence.move(0, p1, window).move(1, p2, window).commit(); QQuickTouchUtils::flush(window); - } + QCOMPARE(root->property("center").toPointF(), QPointF(40 + 10 + dragThreshold, 40)); + QCOMPARE(blackRect->x(), 60.0); + QCOMPARE(blackRect->y(), 50.0); - QCOMPARE(root->property("center").toPointF(), QPointF(60, 60)); // blackrect is at 50,50 - QCOMPARE(blackRect->x(), 60.0); - QCOMPARE(blackRect->y(), 60.0); + p1 += QPoint(0, 10); + p2 += QPoint(0, 10); + pinchSequence.move(0, p1, window).move(1, p2, window).commit(); + QQuickTouchUtils::flush(window); + // next big surprise: the center is in item local coordinates and the item was just + // moved 10 to the right... which offsets the center point 10 to the left + QCOMPARE(root->property("center").toPointF(), QPointF(40 + 10 - 10 + dragThreshold, 40 + 10)); + QCOMPARE(blackRect->x(), 60.0); + QCOMPARE(blackRect->y(), 60.0); + + p1 += QPoint(10, 10); + p2 += QPoint(10, 10); + pinchSequence.move(0, p1, window).move(1, p2, window).commit(); + QQuickTouchUtils::flush(window); + // now the item moved again, thus the center point of the touch is moved in total by (10, 10) + QCOMPARE(root->property("center").toPointF(), QPointF(50 + dragThreshold, 50)); + QCOMPARE(blackRect->x(), 70.0); + QCOMPARE(blackRect->y(), 70.0); + } // pan x beyond bound p1 += QPoint(100,100); @@ -318,7 +359,7 @@ void tst_QQuickPinchArea::pan() QQuickTouchUtils::flush(window); QCOMPARE(blackRect->x(), 140.0); - QCOMPARE(blackRect->y(), 160.0); + QCOMPARE(blackRect->y(), 170.0); QTest::touchEvent(window, device).release(0, p1, window).release(1, p2, window); QQuickTouchUtils::flush(window); diff --git a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp index 483cdf7a41..fe33dbd4d8 100644 --- a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp +++ b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp @@ -30,16 +30,16 @@ #include <QList> #include <QByteArray> -#include <private/qquickshadereffect_p.h> - +#include <private/qquickopenglshadereffect_p.h> +#include <QMatrix4x4> #include <QtQuick/QQuickView> +#include <QtQml/QQmlEngine> #include "../../shared/util.h" - class TestShaderEffect : public QQuickShaderEffect { Q_OBJECT - Q_PROPERTY(QVariant source READ dummyRead NOTIFY dummyChanged) + Q_PROPERTY(QVariant source READ dummyRead NOTIFY sourceChanged) Q_PROPERTY(QVariant _0aA9zZ READ dummyRead NOTIFY dummyChanged) Q_PROPERTY(QVariant x86 READ dummyRead NOTIFY dummyChanged) Q_PROPERTY(QVariant X READ dummyRead NOTIFY dummyChanged) @@ -48,17 +48,18 @@ class TestShaderEffect : public QQuickShaderEffect public: QMatrix4x4 mat4x4Read() const { return QMatrix4x4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1); } QVariant dummyRead() const { return QVariant(); } - bool isConnected(const QMetaMethod &signal) const { return m_signals.contains(signal); } + + int signalsConnected = 0; protected: - void connectNotify(const QMetaMethod &signal) { m_signals.append(signal); } - void disconnectNotify(const QMetaMethod &signal) { m_signals.removeOne(signal); } + void connectNotify(const QMetaMethod &) { ++signalsConnected; } + void disconnectNotify(const QMetaMethod &) { --signalsConnected; } signals: void dummyChanged(); + void sourceChanged(); private: - QList<QMetaMethod> m_signals; }; class tst_qquickshadereffect : public QQmlDataTest @@ -84,12 +85,13 @@ private: TexCoordPresent = 0x02, MatrixPresent = 0x04, OpacityPresent = 0x08, - PropertyPresent = 0x10 + SourcePresent = 0x10 }; }; tst_qquickshadereffect::tst_qquickshadereffect() { + qmlRegisterType<TestShaderEffect>("ShaderEffectTest", 1, 0, "TestShaderEffect"); } void tst_qquickshadereffect::initTestCase() @@ -122,7 +124,7 @@ void tst_qquickshadereffect::lookThroughShaderCode_data() "void main() { \n" " gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity; \n" "}") - << (VertexPresent | TexCoordPresent | MatrixPresent | OpacityPresent | PropertyPresent); + << (VertexPresent | TexCoordPresent | MatrixPresent | OpacityPresent | SourcePresent); QTest::newRow("empty") << QByteArray(" ") // one space -- if completely empty, default will be used instead. @@ -135,14 +137,14 @@ void tst_qquickshadereffect::lookThroughShaderCode_data() "attribute highp vec4 qt_Vertex;\n" "// attribute highp vec2 qt_MultiTexCoord0;") << QByteArray("uniform int source; // uniform lowp float qt_Opacity;") - << (VertexPresent | PropertyPresent); + << (VertexPresent | SourcePresent); QTest::newRow("inside block comments") << QByteArray("/*uniform highp mat4 qt_Matrix;\n" "*/attribute highp vec4 qt_Vertex;\n" "/*/attribute highp vec2 qt_MultiTexCoord0;//**/") << QByteArray("/**/uniform int source; /* uniform lowp float qt_Opacity; */") - << (VertexPresent | PropertyPresent); + << (VertexPresent | SourcePresent); QTest::newRow("inside preprocessor directive") << QByteArray("#define uniform\nhighp mat4 qt_Matrix;\n" @@ -150,7 +152,7 @@ void tst_qquickshadereffect::lookThroughShaderCode_data() "#if\\\nattribute highp vec2 qt_MultiTexCoord0;") << QByteArray("uniform int source;\n" " # undef uniform lowp float qt_Opacity;") - << (VertexPresent | PropertyPresent); + << (VertexPresent | SourcePresent); QTest::newRow("line comments between") @@ -158,21 +160,21 @@ void tst_qquickshadereffect::lookThroughShaderCode_data() "attribute//\nhighp//\nvec4//\nqt_Vertex;\n" " //*/ uniform \n attribute //\\ \n highp //// \n vec2 //* \n qt_MultiTexCoord0;") << QByteArray("uniform// lowp float qt_Opacity;\nsampler2D source;") - << (VertexPresent | TexCoordPresent | MatrixPresent | PropertyPresent); + << (VertexPresent | TexCoordPresent | MatrixPresent | SourcePresent); QTest::newRow("block comments between") << QByteArray("uniform/*foo*/highp/*/bar/*/mat4/**//**/qt_Matrix;\n" "attribute/**/highp/**/vec4/**/qt_Vertex;\n" " /* * */ attribute /*///*/ highp /****/ vec2 /**/ qt_MultiTexCoord0;") << QByteArray("uniform/*/ uniform//lowp/*float qt_Opacity;*/sampler2D source;") - << (VertexPresent | TexCoordPresent | MatrixPresent | PropertyPresent); + << (VertexPresent | TexCoordPresent | MatrixPresent | SourcePresent); QTest::newRow("preprocessor directive between") << QByteArray("uniform\n#foo\nhighp\n#bar\nmat4\n#baz\\\nblimey\nqt_Matrix;\n" "attribute\n#\nhighp\n#\nvec4\n#\nqt_Vertex;\n" " #uniform \n attribute \n # foo \n highp \n # bar \n vec2 \n#baz \n qt_MultiTexCoord0;") << QByteArray("uniform\n#if lowp float qt_Opacity;\nsampler2D source;") - << (VertexPresent | TexCoordPresent | MatrixPresent | PropertyPresent); + << (VertexPresent | TexCoordPresent | MatrixPresent | SourcePresent); QTest::newRow("newline between") << QByteArray("uniform\nhighp\nmat4\nqt_Matrix\n;\n" @@ -180,7 +182,7 @@ void tst_qquickshadereffect::lookThroughShaderCode_data() " \n attribute \n highp \n vec2 \n qt_Multi\nTexCoord0 \n ;") << QByteArray("uniform\nsampler2D\nsource;" "uniform lowp float qt_Opacity;") - << (VertexPresent | MatrixPresent | OpacityPresent | PropertyPresent); + << (VertexPresent | MatrixPresent | OpacityPresent | SourcePresent); QTest::newRow("extra characters #1") @@ -221,28 +223,28 @@ void tst_qquickshadereffect::lookThroughShaderCode_data() "attribute highp qt_MultiTexCoord0;\n") << QByteArray("uniform lowp float qt_Opacity;\n" "uniform mediump float source;\n") - << (MatrixPresent | OpacityPresent | PropertyPresent); + << (MatrixPresent | OpacityPresent | SourcePresent); QTest::newRow("property name #1") << QByteArray("uniform highp vec3 _0aA9zZ;") << QByteArray(" ") - << int(PropertyPresent); + << int(SourcePresent); QTest::newRow("property name #2") << QByteArray("uniform mediump vec2 x86;") << QByteArray(" ") - << int(PropertyPresent); + << int(SourcePresent); QTest::newRow("property name #3") << QByteArray("uniform lowp float X;") << QByteArray(" ") - << int(PropertyPresent); + << int(SourcePresent); QTest::newRow("property name #4") << QByteArray("uniform highp mat4 mat4x4;") << QByteArray(" ") - << int(PropertyPresent); + << int(SourcePresent); } void tst_qquickshadereffect::lookThroughShaderCode() @@ -251,9 +253,11 @@ void tst_qquickshadereffect::lookThroughShaderCode() QFETCH(QByteArray, fragmentShader); QFETCH(int, presenceFlags); - TestShaderEffect item; - QMetaMethod dummyChangedSignal = QMetaMethod::fromSignal(&TestShaderEffect::dummyChanged); - QVERIFY(!item.isConnected(dummyChangedSignal)); // Nothing connected yet. + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0\nimport ShaderEffectTest 1.0\nTestShaderEffect {}", QUrl()); + QScopedPointer<TestShaderEffect> item(qobject_cast<TestShaderEffect*>(component.create())); + QCOMPARE(item->signalsConnected, 1); QString expected; if ((presenceFlags & VertexPresent) == 0) @@ -265,12 +269,12 @@ void tst_qquickshadereffect::lookThroughShaderCode() if ((presenceFlags & OpacityPresent) == 0) expected += "Warning: Shaders are missing reference to \'qt_Opacity\'.\n"; - item.setVertexShader(vertexShader); - item.setFragmentShader(fragmentShader); - QCOMPARE(item.parseLog(), expected); + item->setVertexShader(vertexShader); + item->setFragmentShader(fragmentShader); + QCOMPARE(item->parseLog(), expected); // If the uniform was successfully parsed, the notify signal has been connected to an update slot. - QCOMPARE(item.isConnected(dummyChangedSignal), (presenceFlags & PropertyPresent) != 0); + QCOMPARE(item->signalsConnected, (presenceFlags & SourcePresent) ? 2 : 1); } void tst_qquickshadereffect::deleteSourceItem() diff --git a/tests/auto/quick/qquicktext/BLACKLIST b/tests/auto/quick/qquicktext/BLACKLIST index 223d8feb67..f400af1d10 100644 --- a/tests/auto/quick/qquicktext/BLACKLIST +++ b/tests/auto/quick/qquicktext/BLACKLIST @@ -4,3 +4,5 @@ * [lineLaidOutRelayout] msvc-2015 +[fontSizeMode] +opensuse-42.1 diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index 5ee811fd37..6f7d494255 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -147,8 +147,9 @@ private slots: void padding(); - void zeroWidthAndElidedDoesntRender(); + void hintingPreference(); + void zeroWidthAndElidedDoesntRender(); private: QStringList standard; @@ -4150,6 +4151,33 @@ void tst_qquicktext::padding() delete root; } +void tst_qquicktext::hintingPreference() +{ + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; + QQmlComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->font().hintingPreference(), (int)QFont::PreferDefaultHinting); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.hintingPreference: Font.PreferNoHinting }"; + QQmlComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->font().hintingPreference(), (int)QFont::PreferNoHinting); + + delete textObject; + } +} + + void tst_qquicktext::zeroWidthAndElidedDoesntRender() { // Tests QTBUG-34990 diff --git a/tests/auto/quick/qquicktextedit/BLACKLIST b/tests/auto/quick/qquicktextedit/BLACKLIST index 297146195b..492d81531a 100644 --- a/tests/auto/quick/qquicktextedit/BLACKLIST +++ b/tests/auto/quick/qquicktextedit/BLACKLIST @@ -1,6 +1,2 @@ [mouseSelection] * -[undo] -* -[undo_keypressevents] -* diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index b7bfc357f3..3c899c1e34 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -108,6 +108,7 @@ private slots: void selectionOnFocusOut(); void focusOnPress(); void selection(); + void overwriteMode(); void isRightToLeft_data(); void isRightToLeft(); void keySelection(); @@ -1467,6 +1468,74 @@ void tst_qquicktextedit::selection() QVERIFY(textEditObject->selectedText().isNull()); } +void tst_qquicktextedit::overwriteMode() +{ + QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true; }"; + QQmlComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create()); + QVERIFY(textEdit != 0); + + QSignalSpy spy(textEdit, SIGNAL(overwriteModeChanged(bool))); + + QQuickWindow window; + textEdit->setParentItem(window.contentItem()); + window.show(); + window.requestActivate(); + QTest::qWaitForWindowActive(&window); + + QVERIFY(textEdit->hasActiveFocus()); + + textEdit->setOverwriteMode(true); + QCOMPARE(spy.count(), 1); + QCOMPARE(true, textEdit->overwriteMode()); + textEdit->setOverwriteMode(false); + QCOMPARE(spy.count(), 2); + QCOMPARE(false, textEdit->overwriteMode()); + + QVERIFY(!textEdit->overwriteMode()); + QString insertString = "Some first text"; + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + + QCOMPARE(textEdit->text(), QString("Some first text")); + + textEdit->setOverwriteMode(true); + QCOMPARE(spy.count(), 3); + textEdit->setCursorPosition(5); + + insertString = "shiny"; + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + QCOMPARE(textEdit->text(), QString("Some shiny text")); + + textEdit->setCursorPosition(textEdit->text().length()); + QTest::keyClick(&window, Qt::Key_Enter); + + textEdit->setOverwriteMode(false); + QCOMPARE(spy.count(), 4); + + insertString = "Second paragraph"; + + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + QCOMPARE(textEdit->lineCount(), 2); + + textEdit->setCursorPosition(15); + + QCOMPARE(textEdit->cursorPosition(), 15); + + textEdit->setOverwriteMode(true); + QCOMPARE(spy.count(), 5); + + insertString = " blah"; + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + QCOMPARE(textEdit->lineCount(), 2); + + QCOMPARE(textEdit->text(), QString("Some shiny text blah\nSecond paragraph")); +} + void tst_qquicktextedit::isRightToLeft_data() { QTest::addColumn<QString>("text"); diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 18ccd81633..942eb67563 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -105,6 +105,7 @@ private slots: void wrap(); void selection(); void persistentSelection(); + void overwriteMode(); void isRightToLeft_data(); void isRightToLeft(); void moveCursorSelection_data(); @@ -780,6 +781,48 @@ void tst_qquicktextinput::persistentSelection() QCOMPARE(input->property("selected").toString(), QLatin1String("ell")); } +void tst_qquicktextinput::overwriteMode() +{ + QString componentStr = "import QtQuick 2.0\nTextInput { focus: true; }"; + QQmlComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(textInputComponent.create()); + QVERIFY(textInput != 0); + + QSignalSpy spy(textInput, SIGNAL(overwriteModeChanged(bool))); + + QQuickWindow window; + textInput->setParentItem(window.contentItem()); + window.show(); + window.requestActivate(); + QTest::qWaitForWindowActive(&window); + + QVERIFY(textInput->hasActiveFocus()); + + textInput->setOverwriteMode(true); + QCOMPARE(spy.count(), 1); + QCOMPARE(true, textInput->overwriteMode()); + textInput->setOverwriteMode(false); + QCOMPARE(spy.count(), 2); + QCOMPARE(false, textInput->overwriteMode()); + + QVERIFY(!textInput->overwriteMode()); + QString insertString = "Some first text"; + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + + QCOMPARE(textInput->text(), QString("Some first text")); + + textInput->setOverwriteMode(true); + QCOMPARE(spy.count(), 3); + textInput->setCursorPosition(5); + + insertString = "shiny"; + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + QCOMPARE(textInput->text(), QString("Some shiny text")); +} + void tst_qquicktextinput::isRightToLeft_data() { QTest::addColumn<QString>("text"); diff --git a/tests/auto/quick/qquickview/tst_qquickview.cpp b/tests/auto/quick/qquickview/tst_qquickview.cpp index 05922ae20f..fa9192edb4 100644 --- a/tests/auto/quick/qquickview/tst_qquickview.cpp +++ b/tests/auto/quick/qquickview/tst_qquickview.cpp @@ -36,6 +36,30 @@ #include <QtCore/QDebug> #include <QtQml/qqmlengine.h> +class SizeChangesListener : public QObject, public QVector<QSize> +{ + Q_OBJECT +public: + explicit SizeChangesListener(QQuickItem *item); +private slots: + void onSizeChanged(); +private: + QQuickItem *item; + +}; + +SizeChangesListener::SizeChangesListener(QQuickItem *item) : + item(item) +{ + connect(item, &QQuickItem::widthChanged, this, &SizeChangesListener::onSizeChanged); + connect(item, &QQuickItem::heightChanged, this, &SizeChangesListener::onSizeChanged); +} + +void SizeChangesListener::onSizeChanged() +{ + append(QSize(item->width(), item->height())); +} + class tst_QQuickView : public QQmlDataTest { Q_OBJECT @@ -127,7 +151,6 @@ void tst_QQuickView::resizemodeitem() QCOMPARE(item->width(), 80.0); QCOMPARE(item->height(), 100.0); QTRY_COMPARE(view->size(), QSize(80, 100)); - QCOMPARE(view->size(), QSize(80, 100)); QCOMPARE(view->size(), view->sizeHint()); // size update from root object disabled @@ -139,8 +162,16 @@ void tst_QQuickView::resizemodeitem() QCOMPARE(QSize(item->width(), item->height()), view->sizeHint()); // size update from view + QCoreApplication::processEvents(); // make sure the last resize events are gone + SizeChangesListener sizeListener(item); view->resize(QSize(200,300)); QTRY_COMPARE(item->width(), 200.0); + + for (int i = 0; i < sizeListener.count(); ++i) { + // Check that we have the correct geometry on all signals + QCOMPARE(sizeListener.at(i), view->size()); + } + QCOMPARE(item->height(), 300.0); QCOMPARE(view->size(), QSize(200, 300)); QCOMPARE(view->size(), view->sizeHint()); diff --git a/tests/auto/quick/qquickwindow/qquickwindow.pro b/tests/auto/quick/qquickwindow/qquickwindow.pro index f0d287f30f..05093ba8e0 100644 --- a/tests/auto/quick/qquickwindow/qquickwindow.pro +++ b/tests/auto/quick/qquickwindow/qquickwindow.pro @@ -7,7 +7,7 @@ include(../shared/util.pri) macx:CONFIG -= app_bundle -QT += core-private gui-private qml-private quick-private testlib +QT += core-private qml-private quick-private testlib TESTDATA = data/* diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index 1365e8b751..d9bdf47041 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -40,10 +40,11 @@ #include "../shared/visualtestutil.h" #include "../shared/viewtestutil.h" #include <QSignalSpy> -#include <qpa/qwindowsysteminterface.h> #include <private/qquickwindow_p.h> #include <private/qguiapplication_p.h> #include <QRunnable> +#include <QOpenGLFunctions> +#include <QSGRendererInterface> struct TouchEventData { QEvent::Type type; @@ -273,25 +274,18 @@ class tst_qquickwindow : public QQmlDataTest Q_OBJECT public: tst_qquickwindow() + : touchDevice(QTest::createTouchDevice()) + , touchDeviceWithVelocity(QTest::createTouchDevice()) { QQuickWindow::setDefaultAlphaBuffer(true); + touchDeviceWithVelocity->setCapabilities(QTouchDevice::Position | QTouchDevice::Velocity); } private slots: - void initTestCase() - { - QQmlDataTest::initTestCase(); - touchDevice = new QTouchDevice; - touchDevice->setType(QTouchDevice::TouchScreen); - QWindowSystemInterface::registerTouchDevice(touchDevice); - touchDeviceWithVelocity = new QTouchDevice; - touchDeviceWithVelocity->setType(QTouchDevice::TouchScreen); - touchDeviceWithVelocity->setCapabilities(QTouchDevice::Position | QTouchDevice::Velocity); - QWindowSystemInterface::registerTouchDevice(touchDeviceWithVelocity); - } void cleanup(); - +#ifndef QT_NO_OPENGL void openglContextCreatedSignal(); +#endif void aboutToStopSignal(); void constantUpdates(); @@ -372,14 +366,14 @@ private: QTouchDevice *touchDevice; QTouchDevice *touchDeviceWithVelocity; }; - +#ifndef QT_NO_OPENGL Q_DECLARE_METATYPE(QOpenGLContext *); - +#endif void tst_qquickwindow::cleanup() { QVERIFY(QGuiApplication::topLevelWindows().isEmpty()); } - +#ifndef QT_NO_OPENGL void tst_qquickwindow::openglContextCreatedSignal() { qRegisterMetaType<QOpenGLContext *>(); @@ -391,12 +385,15 @@ void tst_qquickwindow::openglContextCreatedSignal() window.show(); QTest::qWaitForWindowExposed(&window); + if (window.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL) + QSKIP("Skipping OpenGL context test due to not running with OpenGL"); + QVERIFY(spy.size() > 0); QVariant ctx = spy.at(0).at(0); QCOMPARE(qvariant_cast<QOpenGLContext *>(ctx), window.openglContext()); } - +#endif void tst_qquickwindow::aboutToStopSignal() { QQuickWindow window; @@ -438,8 +435,7 @@ void tst_qquickwindow::constantUpdatesOnWindow_data() window.setGeometry(100, 100, 300, 200); window.show(); QTest::qWaitForWindowExposed(&window); - bool threaded = window.openglContext()->thread() != QGuiApplication::instance()->thread(); - + const bool threaded = QQuickWindowPrivate::get(&window)->context->thread() != QGuiApplication::instance()->thread(); if (threaded) { QTest::newRow("blocked, beforeRender") << true << QByteArray(SIGNAL(beforeRendering())); QTest::newRow("blocked, afterRender") << true << QByteArray(SIGNAL(afterRendering())); @@ -1229,13 +1225,14 @@ void tst_qquickwindow::headless() QVERIFY(QTest::qWaitForWindowExposed(window)); QVERIFY(window->isVisible()); - bool threaded = window->openglContext()->thread() != QThread::currentThread(); - + const bool threaded = QQuickWindowPrivate::get(window)->context->thread() != QThread::currentThread(); QSignalSpy initialized(window, SIGNAL(sceneGraphInitialized())); QSignalSpy invalidated(window, SIGNAL(sceneGraphInvalidated())); // Verify that the window is alive and kicking - QVERIFY(window->openglContext() != 0); + QVERIFY(window->isSceneGraphInitialized()); + + const bool isGL = window->rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL; // Store the visual result QImage originalContent = window->grabWindow(); @@ -1245,15 +1242,16 @@ void tst_qquickwindow::headless() window->releaseResources(); if (threaded) { - QTRY_COMPARE(invalidated.size(), 1); - QVERIFY(!window->openglContext()); + QTRY_VERIFY(invalidated.size() >= 1); + if (isGL) + QVERIFY(!window->isSceneGraphInitialized()); } - +#ifndef QT_NO_OPENGL if (QGuiApplication::platformName() == QLatin1String("windows") && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) { QSKIP("Crashes on Windows/ANGLE, QTBUG-42967"); } - +#endif // Destroy the native windowing system buffers window->destroy(); QVERIFY(!window->handle()); @@ -1264,7 +1262,8 @@ void tst_qquickwindow::headless() if (threaded) QTRY_COMPARE(initialized.size(), 1); - QVERIFY(window->openglContext() != 0); + + QVERIFY(window->isSceneGraphInitialized()); // Verify that the visual output is the same QImage newContent = window->grabWindow(); @@ -1285,8 +1284,7 @@ void tst_qquickwindow::noUpdateWhenNothingChanges() // the initial expose with a second expose or more. Let these go // through before we let the test continue. QTest::qWait(100); - - if (window.openglContext()->thread() == QGuiApplication::instance()->thread()) { + if (QQuickWindowPrivate::get(&window)->context->thread() == QGuiApplication::instance()->thread()) { QSKIP("Only threaded renderloop implements this feature"); return; } @@ -1593,7 +1591,6 @@ void tst_qquickwindow::hideThenDelete() QSignalSpy *openglDestroyed = 0; QSignalSpy *sgInvalidated = 0; - bool threaded = false; { QQuickWindow window; @@ -1608,9 +1605,13 @@ void tst_qquickwindow::hideThenDelete() window.show(); QTest::qWaitForWindowExposed(&window); - threaded = window.openglContext()->thread() != QThread::currentThread(); + const bool threaded = QQuickWindowPrivate::get(&window)->context->thread() != QGuiApplication::instance()->thread(); + const bool isGL = window.rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL; +#ifndef QT_NO_OPENGL + if (isGL) + openglDestroyed = new QSignalSpy(window.openglContext(), SIGNAL(aboutToBeDestroyed())); +#endif - openglDestroyed = new QSignalSpy(window.openglContext(), SIGNAL(aboutToBeDestroyed())); sgInvalidated = new QSignalSpy(&window, SIGNAL(sceneGraphInvalidated())); window.hide(); @@ -1618,6 +1619,9 @@ void tst_qquickwindow::hideThenDelete() QTRY_VERIFY(!window.isExposed()); if (threaded) { + if (!isGL) + QSKIP("Skipping persistency verification due to not running with OpenGL"); + if (!persistentSG) { QVERIFY(sgInvalidated->size() > 0); if (!persistentGL) @@ -1632,7 +1636,10 @@ void tst_qquickwindow::hideThenDelete() } QVERIFY(sgInvalidated->size() > 0); - QVERIFY(openglDestroyed->size() > 0); +#ifndef QT_NO_OPENGL + if (openglDestroyed) + QVERIFY(openglDestroyed->size() > 0); +#endif } void tst_qquickwindow::showHideAnimate() @@ -2029,6 +2036,9 @@ void tst_qquickwindow::defaultSurfaceFormat() window.show(); QVERIFY(QTest::qWaitForWindowExposed(&window)); + if (window.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL) + QSKIP("Skipping OpenGL context test due to not running with OpenGL"); + const QSurfaceFormat reqFmt = window.requestedFormat(); QCOMPARE(format.swapInterval(), reqFmt.swapInterval()); QCOMPARE(format.redBufferSize(), reqFmt.redBufferSize()); @@ -2037,12 +2047,13 @@ void tst_qquickwindow::defaultSurfaceFormat() QCOMPARE(format.profile(), reqFmt.profile()); QCOMPARE(int(format.options()), int(reqFmt.options())); +#ifndef QT_NO_OPENGL // Depth and stencil should be >= what has been requested. For real. But use // the context since the window's surface format is only partially updated // on most platforms. QVERIFY(window.openglContext()->format().depthBufferSize() >= 16); QVERIFY(window.openglContext()->format().stencilBufferSize() >= 8); - +#endif QSurfaceFormat::setDefaultFormat(savedDefaultFormat); } @@ -2091,7 +2102,7 @@ public: } static int deleted; }; - +#ifndef QT_NO_OPENGL class GlRenderJob : public QRunnable { public: @@ -2113,7 +2124,7 @@ public: QMutex *mutex; QWaitCondition *condition; }; - +#endif int RenderJob::deleted = 0; void tst_qquickwindow::testRenderJob() @@ -2162,25 +2173,29 @@ void tst_qquickwindow::testRenderJob() QTRY_COMPARE(RenderJob::deleted, 1); QCOMPARE(completedJobs.size(), 1); - // Do a synchronized GL job. - GLubyte readPixel[4] = {0, 0, 0, 0}; - GlRenderJob *glJob = new GlRenderJob(readPixel); - if (window.openglContext()->thread() != QThread::currentThread()) { - QMutex mutex; - QWaitCondition condition; - glJob->mutex = &mutex; - glJob->condition = &condition; - mutex.lock(); - window.scheduleRenderJob(glJob, QQuickWindow::NoStage); - condition.wait(&mutex); - mutex.unlock(); - } else { - window.scheduleRenderJob(glJob, QQuickWindow::NoStage); +#ifndef QT_NO_OPENGL + if (window.rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL) { + // Do a synchronized GL job. + GLubyte readPixel[4] = {0, 0, 0, 0}; + GlRenderJob *glJob = new GlRenderJob(readPixel); + if (window.openglContext()->thread() != QThread::currentThread()) { + QMutex mutex; + QWaitCondition condition; + glJob->mutex = &mutex; + glJob->condition = &condition; + mutex.lock(); + window.scheduleRenderJob(glJob, QQuickWindow::NoStage); + condition.wait(&mutex); + mutex.unlock(); + } else { + window.scheduleRenderJob(glJob, QQuickWindow::NoStage); + } + QCOMPARE(int(readPixel[0]), 255); + QCOMPARE(int(readPixel[1]), 0); + QCOMPARE(int(readPixel[2]), 0); + QCOMPARE(int(readPixel[3]), 255); } - QCOMPARE(int(readPixel[0]), 255); - QCOMPARE(int(readPixel[1]), 0); - QCOMPARE(int(readPixel[2]), 0); - QCOMPARE(int(readPixel[3]), 255); +#endif } // Verify that jobs are deleted when window is not rendered at all @@ -2198,7 +2213,6 @@ void tst_qquickwindow::testRenderJob() class EventCounter : public QQuickRectangle { - Q_OBJECT public: EventCounter(QQuickItem *parent = 0) : QQuickRectangle(parent) diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro index 2e43702e7c..70e5b8ef6a 100644 --- a/tests/auto/quick/quick.pro +++ b/tests/auto/quick/quick.pro @@ -2,10 +2,20 @@ TEMPLATE = subdirs PUBLICTESTS += \ geometry \ - rendernode \ qquickpixmapcache -qtHaveModule(widgets): PUBLICTESTS += nodes +contains(QT_CONFIG, opengl(es1|es2)?) { + PUBLICTESTS += \ + rendernode + qtHaveModule(widgets): PUBLICTESTS += nodes + + QUICKTESTS += \ + qquickanimatedsprite \ + qquickframebufferobject \ + qquickopenglinfo \ + qquickspritesequence \ + qquickshadereffect +} !cross_compile: PRIVATETESTS += examples @@ -39,7 +49,6 @@ QUICKTESTS = \ qquickaccessible \ qquickanchors \ qquickanimatedimage \ - qquickanimatedsprite \ qquickdynamicpropertyanimation \ qquickborderimage \ qquickwindow \ @@ -48,7 +57,7 @@ QUICKTESTS = \ qquickflickable \ qquickflipable \ qquickfocusscope \ - qquickframebufferobject \ + qquickgraphicsinfo \ qquickgridview \ qquickimage \ qquickitem \ @@ -58,16 +67,13 @@ QUICKTESTS = \ qquickloader \ qquickmousearea \ qquickmultipointtoucharea \ - qquickopenglinfo \ qquickpainteditem \ qquickpathview \ qquickpincharea \ qquickpositioners \ qquickrectangle \ qquickrepeater \ - qquickshadereffect \ qquickshortcut \ - qquickspritesequence \ qquicktext \ qquicktextdocument \ qquicktextedit \ diff --git a/tests/auto/quick/rendernode/tst_rendernode.cpp b/tests/auto/quick/rendernode/tst_rendernode.cpp index 782ebf5aee..e15649e62c 100644 --- a/tests/auto/quick/rendernode/tst_rendernode.cpp +++ b/tests/auto/quick/rendernode/tst_rendernode.cpp @@ -66,12 +66,12 @@ private slots: class ClearNode : public QSGRenderNode { public: - virtual StateFlags changedStates() + StateFlags changedStates() const override { return ColorState; } - virtual void render(const RenderState &) + void render(const RenderState *) override { // If clip has been set, scissoring will make sure the right area is cleared. QOpenGLContext::currentContext()->functions()->glClearColor(color.redF(), color.greenF(), color.blueF(), 1.0f); @@ -122,13 +122,13 @@ class MessUpNode : public QSGRenderNode, protected QOpenGLFunctions public: MessUpNode() : initialized(false) { } - virtual StateFlags changedStates() + StateFlags changedStates() const override { return StateFlags(DepthState) | StencilState | ScissorState | ColorState | BlendState - | CullState | ViewportState; + | CullState | ViewportState | RenderTargetState; } - virtual void render(const RenderState &) + void render(const RenderState *) override { if (!initialized) { initializeOpenGLFunctions(); @@ -152,6 +152,9 @@ public: glGetIntegerv(GL_FRONT_FACE, &frontFace); glFrontFace(frontFace == GL_CW ? GL_CCW : GL_CW); glEnable(GL_CULL_FACE); + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); } bool initialized; @@ -212,16 +215,18 @@ void tst_rendernode::renderOrder() QSKIP("This test does not work at display depths < 24"); QImage fb = runTest("RenderOrder.qml"); - QCOMPARE(fb.width(), 200); - QCOMPARE(fb.height(), 200); + QQuickView v; + int devicePixelRatio = static_cast<int>(v.devicePixelRatio()); + QCOMPARE(fb.width(), 200 * devicePixelRatio); + QCOMPARE(fb.height(), 200 * devicePixelRatio); - QCOMPARE(fb.pixel(50, 50), qRgb(0xff, 0xff, 0xff)); - QCOMPARE(fb.pixel(50, 150), qRgb(0xff, 0xff, 0xff)); - QCOMPARE(fb.pixel(150, 50), qRgb(0x00, 0x00, 0xff)); + QCOMPARE(fb.pixel(50 * devicePixelRatio, 50 * devicePixelRatio), qRgb(0xff, 0xff, 0xff)); + QCOMPARE(fb.pixel(50 * devicePixelRatio, 150 * devicePixelRatio), qRgb(0xff, 0xff, 0xff)); + QCOMPARE(fb.pixel(150 * devicePixelRatio, 50 * devicePixelRatio), qRgb(0x00, 0x00, 0xff)); QByteArray errorMessage; - QVERIFY2(fuzzyCompareColor(fb.pixel(150, 150), qRgb(0x7f, 0x7f, 0xff), &errorMessage), - msgColorMismatchAt(errorMessage, 150, 150).constData()); + QVERIFY2(fuzzyCompareColor(fb.pixel(150 * devicePixelRatio, 150 * devicePixelRatio), qRgb(0x7f, 0x7f, 0xff), &errorMessage), + msgColorMismatchAt(errorMessage, 150 * devicePixelRatio, 150 * devicePixelRatio).constData()); } /* The test uses a number of nested rectangles with clipping @@ -257,8 +262,8 @@ void tst_rendernode::messUpState() class StateRecordingRenderNode : public QSGRenderNode { public: - StateFlags changedStates() { return StateFlags(-1); } - void render(const RenderState &) { + StateFlags changedStates() const override { return StateFlags(-1); } + void render(const RenderState *) override { matrices[name] = *matrix(); } diff --git a/tests/auto/quick/scenegraph/scenegraph.pro b/tests/auto/quick/scenegraph/scenegraph.pro index 320228bd08..40ff7750cc 100644 --- a/tests/auto/quick/scenegraph/scenegraph.pro +++ b/tests/auto/quick/scenegraph/scenegraph.pro @@ -3,6 +3,7 @@ TARGET = tst_scenegraph SOURCES += tst_scenegraph.cpp include (../../shared/util.pri) +include (../shared/util.pri) macx:CONFIG -= app_bundle diff --git a/tests/auto/quick/scenegraph/tst_scenegraph.cpp b/tests/auto/quick/scenegraph/tst_scenegraph.cpp index 1cca56a876..791bcb215a 100644 --- a/tests/auto/quick/scenegraph/tst_scenegraph.cpp +++ b/tests/auto/quick/scenegraph/tst_scenegraph.cpp @@ -28,17 +28,25 @@ #include <qtest.h> +#ifndef QT_NO_OPENGL #include <QOffscreenSurface> #include <QOpenGLContext> #include <QOpenGLFunctions> +#endif #include <QtQuick> #include <QtQml> +#ifndef QT_NO_OPENGL #include <private/qopenglcontext_p.h> +#endif + #include <private/qsgcontext_p.h> #include <private/qsgrenderloop_p.h> +#include "../shared/visualtestutil.h" + +using namespace QQuickVisualTestUtil; class PerPixelRect : public QQuickItem { @@ -96,9 +104,9 @@ private slots: void render_data(); void render(); - +#ifndef QT_NO_OPENGL void hideWithOtherContext(); - +#endif void createTextureFromImage_data(); void createTextureFromImage(); @@ -118,6 +126,7 @@ void tst_SceneGraph::initTestCase() QSGRenderLoop *loop = QSGRenderLoop::instance(); qDebug() << "RenderLoop: " << loop; +#ifndef QT_NO_OPENGL QOpenGLContext context; context.setFormat(loop->sceneGraphContext()->defaultSurfaceFormat()); context.create(); @@ -150,6 +159,7 @@ void tst_SceneGraph::initTestCase() qDebug() << "Broken Mipmap: " << m_brokenMipmapSupport; context.doneCurrent(); +#endif } QQuickView *createView(const QString &file, QWindow *parent = 0, int x = -1, int y = -1, int w = -1, int h = -1) @@ -175,12 +185,17 @@ QImage showAndGrab(const QString &file, int w, int h) // Assumes the images are opaque white... bool containsSomethingOtherThanWhite(const QImage &image) { - Q_ASSERT(image.format() == QImage::Format_ARGB32_Premultiplied - || image.format() == QImage::Format_RGB32); - int w = image.width(); - int h = image.height(); + QImage img; + if (image.format() != QImage::Format_ARGB32_Premultiplied + || image.format() != QImage::Format_RGB32) + img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + else + img = image; + + int w = img.width(); + int h = img.height(); for (int y=0; y<h; ++y) { - const uint *pixels = (const uint *) image.constScanLine(y); + const uint *pixels = (const uint *) img.constScanLine(y); for (int x=0; x<w; ++x) if (pixels[x] != 0xffffffff) return true; @@ -188,44 +203,6 @@ bool containsSomethingOtherThanWhite(const QImage &image) return false; } -// When running on native Nvidia graphics cards on linux, the -// distance field glyph pixels have a measurable, but not visible -// pixel error. Use a custom compare function to avoid -// -// This was GT-216 with the ubuntu "nvidia-319" driver package. -// llvmpipe does not show the same issue. -// -bool compareImages(const QImage &ia, const QImage &ib) -{ - if (ia.size() != ib.size()) - qDebug() << "images are of different size" << ia.size() << ib.size(); - Q_ASSERT(ia.size() == ib.size()); - Q_ASSERT(ia.format() == ib.format()); - - int w = ia.width(); - int h = ia.height(); - const int tolerance = 5; - for (int y=0; y<h; ++y) { - const uint *as= (const uint *) ia.constScanLine(y); - const uint *bs= (const uint *) ib.constScanLine(y); - for (int x=0; x<w; ++x) { - uint a = as[x]; - uint b = bs[x]; - - // No tolerance for error in the alpha. - if ((a & 0xff000000) != (b & 0xff000000)) - return false; - if (qAbs(qRed(a) - qRed(b)) > tolerance) - return false; - if (qAbs(qRed(a) - qRed(b)) > tolerance) - return false; - if (qAbs(qRed(a) - qRed(b)) > tolerance) - return false; - } - } - return true; -} - void tst_SceneGraph::manyWindows_data() { QTest::addColumn<QString>("file"); @@ -251,24 +228,26 @@ void tst_SceneGraph::manyWindows_data() QTest::newRow("rects,subwindow,sharing") << QStringLiteral("manyWindows_rects.qml") << false << true; } +#ifndef QT_NO_OPENGL struct ShareContextResetter { public: ~ShareContextResetter() { qt_gl_set_global_share_context(0); } }; +#endif void tst_SceneGraph::manyWindows() { QFETCH(QString, file); QFETCH(bool, toplevel); QFETCH(bool, shared); - +#ifndef QT_NO_OPENGL QOpenGLContext sharedGLContext; ShareContextResetter cleanup; // To avoid dangling pointer in case of test-failure. if (shared) { QVERIFY(sharedGLContext.create()); qt_gl_set_global_share_context(&sharedGLContext); } - +#endif QScopedPointer<QWindow> parent; if (!toplevel) { parent.reset(new QWindow()); @@ -457,6 +436,13 @@ void tst_SceneGraph::render_data() void tst_SceneGraph::render() { + QQuickView dummy; + dummy.show(); + QTest::qWaitForWindowExposed(&dummy); + if (dummy.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL) + QSKIP("Skipping complex rendering tests due to not running with OpenGL"); + dummy.hide(); + QFETCH(QString, file); QFETCH(QList<Sample>, baseStage); QFETCH(QList<Sample>, finalStage); @@ -499,6 +485,7 @@ void tst_SceneGraph::render() } } +#ifndef QT_NO_OPENGL // Testcase for QTBUG-34898. We make another context current on another surface // in the GUI thread and hide the QQuickWindow while the other context is // current on the other window. @@ -519,6 +506,9 @@ void tst_SceneGraph::hideWithOtherContext() view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); + if (view.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL) + QSKIP("Skipping OpenGL context test due to not running with OpenGL"); + renderingOnMainThread = view.openglContext()->thread() == QGuiApplication::instance()->thread(); // Make the local context current on the local window... @@ -531,6 +521,7 @@ void tst_SceneGraph::hideWithOtherContext() // GL calls to a new frame (see QOpenGLContext docs). QVERIFY(!renderingOnMainThread || QOpenGLContext::currentContext() != &context); } +#endif void tst_SceneGraph::createTextureFromImage_data() { @@ -556,6 +547,10 @@ void tst_SceneGraph::createTextureFromImage() QFETCH(bool, expectedAlpha); QQuickView view; + view.show(); + QTest::qWaitForWindowExposed(&view); + QTRY_VERIFY(view.isSceneGraphInitialized()); + QScopedPointer<QSGTexture> texture(view.createTextureFromImage(image, (QQuickWindow::CreateTextureOptions) flags)); QCOMPARE(texture->hasAlphaChannel(), expectedAlpha); } diff --git a/tests/auto/quick/shared/visualtestutil.cpp b/tests/auto/quick/shared/visualtestutil.cpp index 3e18c83ee2..eabfe5368b 100644 --- a/tests/auto/quick/shared/visualtestutil.cpp +++ b/tests/auto/quick/shared/visualtestutil.cpp @@ -61,3 +61,38 @@ void QQuickVisualTestUtil::dumpTree(QQuickItem *parent, int depth) } } +// A custom compare function to avoid issues such as: +// When running on native Nvidia graphics cards on linux, the +// distance field glyph pixels have a measurable, but not visible +// pixel error. This was GT-216 with the ubuntu "nvidia-319" driver package. +// llvmpipe does not show the same issue. +bool QQuickVisualTestUtil::compareImages(const QImage &ia, const QImage &ib) +{ + if (ia.size() != ib.size()) + qDebug() << "images are of different size" << ia.size() << ib.size(); + Q_ASSERT(ia.size() == ib.size()); + Q_ASSERT(ia.format() == ib.format()); + + int w = ia.width(); + int h = ia.height(); + const int tolerance = 5; + for (int y=0; y<h; ++y) { + const uint *as= (const uint *) ia.constScanLine(y); + const uint *bs= (const uint *) ib.constScanLine(y); + for (int x=0; x<w; ++x) { + uint a = as[x]; + uint b = bs[x]; + + // No tolerance for error in the alpha. + if ((a & 0xff000000) != (b & 0xff000000)) + return false; + if (qAbs(qRed(a) - qRed(b)) > tolerance) + return false; + if (qAbs(qRed(a) - qRed(b)) > tolerance) + return false; + if (qAbs(qRed(a) - qRed(b)) > tolerance) + return false; + } + } + return true; +} diff --git a/tests/auto/quick/shared/visualtestutil.h b/tests/auto/quick/shared/visualtestutil.h index 2b377a4bab..2daf86cd83 100644 --- a/tests/auto/quick/shared/visualtestutil.h +++ b/tests/auto/quick/shared/visualtestutil.h @@ -96,6 +96,8 @@ namespace QQuickVisualTestUtil items << qobject_cast<QQuickItem*>(findItem<T>(parent, objectName, indexes[i])); return items; } + + bool compareImages(const QImage &ia, const QImage &ib); } #define QQUICK_VERIFY_POLISH(item) \ diff --git a/tests/auto/quick/touchmouse/touchmouse.pro b/tests/auto/quick/touchmouse/touchmouse.pro index 0df9bc53d3..49818bb399 100644 --- a/tests/auto/quick/touchmouse/touchmouse.pro +++ b/tests/auto/quick/touchmouse/touchmouse.pro @@ -1,7 +1,7 @@ CONFIG += testcase TARGET = tst_touchmouse -QT += core-private gui-private qml-private quick-private testlib +QT += core-private qml-private quick-private testlib macx:CONFIG -= app_bundle diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp index 15d7ffd9d9..dc70081f09 100644 --- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp +++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp @@ -37,7 +37,6 @@ #include <QtQuick/private/qquickmultipointtoucharea_p.h> #include <QtQuick/private/qquickpincharea_p.h> #include <QtQuick/private/qquickflickable_p.h> -#include <qpa/qwindowsysteminterface.h> #include <private/qquickwindow_p.h> @@ -132,7 +131,7 @@ class tst_TouchMouse : public QQmlDataTest Q_OBJECT public: tst_TouchMouse() - :device(0) + :device(QTest::createTouchDevice()) {} private slots: @@ -191,11 +190,6 @@ void tst_TouchMouse::initTestCase() QQmlDataTest::initTestCase(); qmlRegisterType<EventItem>("Qt.test", 1, 0, "EventItem"); - if (!device) { - device = new QTouchDevice; - device->setType(QTouchDevice::TouchScreen); - QWindowSystemInterface::registerTouchDevice(device); - } } void tst_TouchMouse::simpleTouchEvent() @@ -256,8 +250,7 @@ void tst_TouchMouse::simpleTouchEvent() QCOMPARE(eventItem1->eventList.size(), 2); QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin); QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress); - QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window); - QCOMPARE(windowPriv->mouseGrabberItem, eventItem1); + QCOMPARE(window->mouseGrabberItem(), eventItem1); QPoint localPos = eventItem1->mapFromScene(p1).toPoint(); QPoint globalPos = window->mapToGlobal(p1); @@ -580,7 +573,7 @@ void tst_TouchMouse::buttonOnFlickable() QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window); QCOMPARE(windowPriv->touchMouseId, 0); QCOMPARE(windowPriv->itemForTouchPointId[0], eventItem1); - QCOMPARE(windowPriv->mouseGrabberItem, eventItem1); + QCOMPARE(window->mouseGrabberItem(), eventItem1); p1 += QPoint(0, -10); QPoint p2 = p1 + QPoint(0, -10); @@ -598,7 +591,7 @@ void tst_TouchMouse::buttonOnFlickable() QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchUpdate); QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseMove); - QCOMPARE(windowPriv->mouseGrabberItem, flickable); + QCOMPARE(window->mouseGrabberItem(), flickable); QCOMPARE(windowPriv->touchMouseId, 0); QCOMPARE(windowPriv->itemForTouchPointId[0], flickable); QVERIFY(flickable->isMovingVertically()); @@ -665,7 +658,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window); QCOMPARE(windowPriv->touchMouseId, 0); QCOMPARE(windowPriv->itemForTouchPointId[0], eventItem1); - QCOMPARE(windowPriv->mouseGrabberItem, eventItem1); + QCOMPARE(window->mouseGrabberItem(), eventItem1); p1 += QPoint(0, -10); QPoint p2 = p1 + QPoint(0, -10); @@ -681,7 +674,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() // flickable should have the mouse grab, and have moved the itemForTouchPointId // for the touchMouseId to the new grabber. - QCOMPARE(windowPriv->mouseGrabberItem, flickable); + QCOMPARE(window->mouseGrabberItem(), flickable); QCOMPARE(windowPriv->touchMouseId, 0); QCOMPARE(windowPriv->itemForTouchPointId[0], flickable); @@ -1098,8 +1091,8 @@ void tst_TouchMouse::mouseOnFlickableOnPinch() QQuickTouchUtils::flush(window); QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window); - qDebug() << "Mouse Grabber: " << windowPriv->mouseGrabberItem << " itemForTouchPointId: " << windowPriv->itemForTouchPointId; - QCOMPARE(windowPriv->mouseGrabberItem, flickable); + qDebug() << "Mouse Grabber: " << window->mouseGrabberItem() << " itemForTouchPointId: " << windowPriv->itemForTouchPointId; + QCOMPARE(window->mouseGrabberItem(), flickable); // Add a second finger, this should lead to stealing p1 = QPoint(40, 100); |