aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick/qquickwindow/tst_qquickwindow.cpp')
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp685
1 files changed, 478 insertions, 207 deletions
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 05fda64654..1e2553c107 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -1,33 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE: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$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qtest.h>
#include <QDebug>
+#include <QEvent>
#include <QMimeData>
#include <QTouchEvent>
#include <QtQuick/QQuickItem>
@@ -38,9 +14,9 @@
#include <QtQuick/private/qquickrectangle_p.h>
#include <QtQuick/private/qquickloader_p.h>
#include <QtQuick/private/qquickmousearea_p.h>
-#include "../../shared/util.h"
-#include "../shared/visualtestutil.h"
-#include "../shared/viewtestutil.h"
+#include <QtQuickTestUtils/private/qmlutils_p.h>
+#include <QtQuickTestUtils/private/visualtestutils_p.h>
+#include <QtQuickTestUtils/private/viewtestutils_p.h>
#include <QSignalSpy>
#include <private/qquickwindow_p.h>
#include <private/qguiapplication_p.h>
@@ -50,7 +26,8 @@
#include <QQuickRenderControl>
#include <QOperatingSystemVersion>
#include <functional>
-#include <QtGui/private/qrhi_p.h>
+#include <QtGui/private/qeventpoint_p.h>
+#include <rhi/qrhi.h>
#if QT_CONFIG(opengl)
#include <QOpenGLContext>
#endif
@@ -68,16 +45,16 @@ struct TouchEventData {
QList<QEventPoint> touchPoints;
};
-static QMutableEventPoint makeTouchPoint(QQuickItem *item, const QPointF &p, const QPointF &lastPoint = QPointF())
+static QEventPoint makeTouchPoint(QQuickItem *item, const QPointF &p, const QPointF &lastPoint = QPointF())
{
QPointF last = lastPoint.isNull() ? p : lastPoint;
- QMutableEventPoint tp;
+ QEventPoint tp;
- tp.setPosition(p);
- tp.setScenePosition(item->mapToScene(p));
- tp.setGlobalPosition(item->mapToGlobal(p));
- tp.setGlobalLastPosition(item->mapToGlobal(last));
+ QMutableEventPoint::setPosition(tp, p);
+ QMutableEventPoint::setScenePosition(tp, item->mapToScene(p));
+ QMutableEventPoint::setGlobalPosition(tp, item->mapToGlobal(p));
+ QMutableEventPoint::setGlobalLastPosition(tp, item->mapToGlobal(last));
return tp;
}
@@ -86,7 +63,7 @@ static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, QEventPoint::
{
TouchEventData d = { type, nullptr, w, states, touchPoints };
for (auto &pt : d.touchPoints)
- QMutableEventPoint::from(pt).detach();
+ QMutableEventPoint::detach(pt);
return d;
}
static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, QEventPoint::States states,
@@ -211,7 +188,8 @@ public:
QPointF lastMousePos;
QInputDevice::Capabilities lastMouseCapabilityFlags;
- void touchEvent(QTouchEvent *event) {
+ void touchEvent(QTouchEvent *event) override
+ {
if (!acceptTouchEvents) {
event->ignore();
return;
@@ -229,7 +207,8 @@ public:
}
}
- void mousePressEvent(QMouseEvent *e) {
+ void mousePressEvent(QMouseEvent *e) override
+ {
if (!acceptMouseEvents) {
e->ignore();
return;
@@ -239,7 +218,8 @@ public:
lastMouseCapabilityFlags = e->device()->capabilities();
}
- void mouseMoveEvent(QMouseEvent *e) {
+ void mouseMoveEvent(QMouseEvent *e) override
+ {
if (!acceptMouseEvents) {
e->ignore();
return;
@@ -250,7 +230,8 @@ public:
lastMousePos = e->position().toPoint();
}
- void mouseReleaseEvent(QMouseEvent *e) {
+ void mouseReleaseEvent(QMouseEvent *e) override
+ {
if (!acceptMouseEvents) {
e->ignore();
return;
@@ -260,12 +241,14 @@ public:
lastMouseCapabilityFlags = e->device()->capabilities();
}
- void mouseUngrabEvent() {
+ void mouseUngrabEvent() override
+ {
qCDebug(lcTests) << objectName();
++mouseUngrabEventCount;
}
- bool childMouseEventFilter(QQuickItem *item, QEvent *e) {
+ bool childMouseEventFilter(QQuickItem *item, QEvent *e) override
+ {
qCDebug(lcTests) << objectName() << "filtering" << e << "ahead of delivery to" << item->metaObject()->className() << item->objectName();
switch (e->type()) {
case QEvent::MouseButtonPress:
@@ -295,7 +278,8 @@ int TestTouchItem::mouseReleaseNum = 0;
class EventFilter : public QObject
{
public:
- bool eventFilter(QObject *watched, QEvent *event) {
+ bool eventFilter(QObject *watched, QEvent *event) override
+ {
Q_UNUSED(watched);
events.append(event->type());
return false;
@@ -312,37 +296,76 @@ public:
int iterations;
protected:
- QSGNode* updatePaintNode(QSGNode *, UpdatePaintNodeData *){
+ QSGNode* updatePaintNode(QSGNode *, UpdatePaintNodeData *) override
+ {
iterations++;
update();
return nullptr;
}
};
-class MouseRecordingWindow : public QQuickWindow
+class PointerRecordingWindow : public QQuickWindow
{
public:
- explicit MouseRecordingWindow(QWindow *parent = nullptr) : QQuickWindow(parent) { }
+ explicit PointerRecordingWindow(QWindow *parent = nullptr) : QQuickWindow(parent) { }
protected:
+ bool event(QEvent *event) override {
+ if (event->isPointerEvent()) {
+ qCDebug(lcTests) << event;
+ m_events << PointerEvent { event->type(), static_cast<QPointerEvent *>(event)->pointingDevice() };
+ }
+ return QQuickWindow::event(event);
+ }
+
void mousePressEvent(QMouseEvent *event) override {
qCDebug(lcTests) << event;
- m_mouseEvents << event->source();
+ m_mouseEvents << PointerEvent { event->type(), event->pointingDevice() };
QQuickWindow::mousePressEvent(event);
}
void mouseMoveEvent(QMouseEvent *event) override {
qCDebug(lcTests) << event;
- m_mouseEvents << event->source();
+ m_mouseEvents << PointerEvent { event->type(), event->pointingDevice() };
QQuickWindow::mouseMoveEvent(event);
}
void mouseReleaseEvent(QMouseEvent *event) override {
qCDebug(lcTests) << event;
- m_mouseEvents << event->source();
+ m_mouseEvents << PointerEvent { event->type(), event->pointingDevice() };
QQuickWindow::mouseReleaseEvent(event);
}
+ void touchEvent(QTouchEvent * event) override {
+ qCDebug(lcTests) << event;
+ m_touchEvents << PointerEvent { event->type(), event->pointingDevice() };
+ QQuickWindow::touchEvent(event);
+ }
+
+#if QT_CONFIG(tabletevent)
+ void tabletEvent(QTabletEvent * event) override {
+ qCDebug(lcTests) << event;
+ m_tabletEvents << PointerEvent { event->type(), event->pointingDevice() };
+ QQuickWindow::tabletEvent(event);
+ }
+#endif
+
+#if QT_CONFIG(wheelevent)
+ void wheelEvent(QWheelEvent * event) override {
+ qCDebug(lcTests) << event;
+ m_tabletEvents << PointerEvent { event->type(), event->pointingDevice() };
+ QQuickWindow::wheelEvent(event);
+ }
+#endif
+
public:
- QList<Qt::MouseEventSource> m_mouseEvents;
+ struct PointerEvent
+ {
+ QEvent::Type type;
+ const QPointingDevice *device;
+ };
+ QList<PointerEvent> m_events;
+ QList<PointerEvent> m_mouseEvents;
+ QList<PointerEvent> m_touchEvents;
+ QList<PointerEvent> m_tabletEvents;
};
class MouseRecordingItem : public QQuickItem
@@ -394,14 +417,19 @@ class tst_qquickwindow : public QQmlDataTest
Q_OBJECT
public:
tst_qquickwindow()
- : touchDevice(QTest::createTouchDevice())
+ : QQmlDataTest(QT_QMLTEST_DATADIR)
+ , touchDevice(QTest::createTouchDevice())
, touchDeviceWithVelocity(QTest::createTouchDevice(QInputDevice::DeviceType::TouchScreen,
QInputDevice::Capability::Position | QPointingDevice::Capability::Velocity))
+ , tabletStylusDevice(QPointingDevicePrivate::tabletDevice(QInputDevice::DeviceType::Stylus,
+ QPointingDevice::PointerType::Pen,
+ QPointingDeviceUniqueId::fromNumericId(1234567890)))
{
QQuickWindow::setDefaultAlphaBuffer(true);
}
private slots:
+ void initTestCase() override;
void cleanup();
void aboutToStopSignal();
@@ -438,6 +466,7 @@ private slots:
void grab_data();
void grab();
+ void earlyGrab();
void multipleWindows();
void animationsWhileHidden();
@@ -501,8 +530,13 @@ private slots:
void testChildMouseEventFilter_data();
void cleanupGrabsOnRelease();
+ void subclassWithPointerEventVirtualOverrides_data();
+ void subclassWithPointerEventVirtualOverrides();
+
#if QT_CONFIG(shortcut)
void testShortCut();
+ void shortcutOverride_data();
+ void shortcutOverride();
#endif
void rendererInterface();
@@ -510,15 +544,38 @@ private slots:
void rendererInterfaceWithRenderControl_data();
void rendererInterfaceWithRenderControl();
+ void graphicsConfiguration();
+
+ void visibleVsVisibility_data();
+ void visibleVsVisibility();
+
+ void eventTypes();
+
private:
- QPointingDevice *touchDevice;
- QPointingDevice *touchDeviceWithVelocity;
+ QPointingDevice *touchDevice; // TODO make const after fixing QTBUG-107864
+ const QPointingDevice *touchDeviceWithVelocity;
+ const QPointingDevice *tabletStylusDevice;
};
#if QT_CONFIG(opengl)
Q_DECLARE_METATYPE(QOpenGLContext *);
#endif
+void tst_qquickwindow::initTestCase()
+{
+ // for the graphicsConfiguration test
+ qunsetenv("QSG_NO_DEPTH_BUFFER");
+ qunsetenv("QSG_RHI_DEBUG_LAYER");
+ qunsetenv("QSG_RHI_PROFILE");
+ qunsetenv("QSG_RHI_PREFER_SOFTWARE_RENDERER");
+ qunsetenv("QT_DISABLE_SHADER_DISK_CACHE");
+ qunsetenv("QSG_RHI_DISABLE_DISK_CACHE");
+ qunsetenv("QSG_RHI_PIPELINE_CACHE_SAVE");
+ qunsetenv("QSG_RHI_PIPELINE_CACHE_LOAD");
+
+ QQmlDataTest::initTestCase();
+}
+
void tst_qquickwindow::cleanup()
{
QVERIFY(QGuiApplication::topLevelWindows().isEmpty());
@@ -535,7 +592,7 @@ void tst_qquickwindow::aboutToStopSignal()
window.hide();
- QTRY_VERIFY(spy.count() > 0);
+ QTRY_VERIFY(spy.size() > 0);
}
//If the item calls update inside updatePaintNode, it should schedule another sync pass
@@ -551,8 +608,8 @@ void tst_qquickwindow::constantUpdates()
QSignalSpy afterSpy(&window, SIGNAL(afterSynchronizing()));
QTRY_VERIFY(item.iterations > 10);
- QTRY_VERIFY(beforeSpy.count() > 10);
- QTRY_VERIFY(afterSpy.count() > 10);
+ QTRY_VERIFY(beforeSpy.size() > 10);
+ QTRY_VERIFY(afterSpy.size() > 10);
}
void tst_qquickwindow::constantUpdatesOnWindow_data()
@@ -653,7 +710,7 @@ void tst_qquickwindow::touchEvent_basic()
// press single point
touchSeq.press(0, topItem->mapToScene(pos).toPoint(),window).commit();
QQuickTouchUtils::flush(window);
- QTRY_COMPARE(topItem->lastEvent.touchPoints.count(), 1);
+ QTRY_COMPARE(topItem->lastEvent.touchPoints.size(), 1);
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
@@ -667,9 +724,9 @@ void tst_qquickwindow::touchEvent_basic()
touchSeq.press(0, topItem->mapToScene(pos).toPoint(), window)
.press(1, bottomItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
- QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+ QCOMPARE(topItem->lastEvent.touchPoints.size(), 1);
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
- QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
+ QCOMPARE(bottomItem->lastEvent.touchPoints.size(), 1);
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, QEventPoint::State::Pressed, makeTouchPoint(topItem, pos)));
COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, QEventPoint::State::Pressed, makeTouchPoint(bottomItem, pos)));
topItem->reset();
@@ -681,7 +738,7 @@ void tst_qquickwindow::touchEvent_basic()
QQuickTouchUtils::flush(window);
touchSeq.move(0, bottomItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
- QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+ QCOMPARE(topItem->lastEvent.touchPoints.size(), 1);
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, window, QEventPoint::State::Updated,
makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
topItem->reset();
@@ -692,7 +749,7 @@ void tst_qquickwindow::touchEvent_basic()
QQuickTouchUtils::flush(window);
touchSeq.move(0, topItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
- QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
+ QCOMPARE(bottomItem->lastEvent.touchPoints.size(), 1);
COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchUpdate, window, QEventPoint::State::Updated,
makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos), pos)));
bottomItem->reset();
@@ -704,9 +761,9 @@ void tst_qquickwindow::touchEvent_basic()
touchSeq.stationary(0)
.press(1, bottomItem->mapToScene(pos).toPoint(), window).commit();
QQuickTouchUtils::flush(window);
- QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); // received press and then stationary
+ QCOMPARE(topItem->lastEvent.touchPoints.size(), 1); // received press and then stationary
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
- QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
+ QCOMPARE(bottomItem->lastEvent.touchPoints.size(), 1);
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, window, QEventPoint::State::Stationary, makeTouchPoint(topItem, pos)));
COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, QEventPoint::State::Pressed, makeTouchPoint(bottomItem, pos)));
topItem->reset();
@@ -722,7 +779,7 @@ void tst_qquickwindow::touchEvent_basic()
QQuickTouchUtils::flush(window);
touchSeq.release(0, bottomItem->mapToScene(pos).toPoint(),window).commit();
QQuickTouchUtils::flush(window);
- QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+ QCOMPARE(topItem->lastEvent.touchPoints.size(), 1);
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, window, QEventPoint::State::Released,
makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
topItem->reset();
@@ -736,9 +793,9 @@ void tst_qquickwindow::touchEvent_basic()
touchSeq.release(0, bottomItem->mapToScene(pos).toPoint(), window)
.stationary(1).commit();
QQuickTouchUtils::flush(window);
- QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+ QCOMPARE(topItem->lastEvent.touchPoints.size(), 1);
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
- QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
+ QCOMPARE(bottomItem->lastEvent.touchPoints.size(), 1);
// Since qtbase 2692237bb1b0c0f50b7cc5d920eb8ab065063d47, if the point didn't have a different position on release,
// then lastPosition is not changed. So in this case, it still holds the press position. I.e. on release,
// it's the last position that was actually different.
@@ -799,7 +856,7 @@ void tst_qquickwindow::touchEvent_propagation()
// single touch to top item, should be received by middle item
QTest::touchEvent(window, touchDevice).press(0, pointInTopItem, window);
- QTRY_COMPARE(middleItem->lastEvent.touchPoints.count(), 1);
+ QTRY_COMPARE(middleItem->lastEvent.touchPoints.size(), 1);
QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, QEventPoint::State::Pressed,
@@ -809,7 +866,7 @@ void tst_qquickwindow::touchEvent_propagation()
// touch top and middle items, middle item should get both events
QTest::touchEvent(window, touchDevice).press(0, pointInTopItem, window)
.press(1, pointInMiddleItem, window);
- QTRY_COMPARE(middleItem->lastEvent.touchPoints.count(), 2);
+ QTRY_COMPARE(middleItem->lastEvent.touchPoints.size(), 2);
QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, QEventPoint::State::Pressed,
@@ -828,7 +885,7 @@ void tst_qquickwindow::touchEvent_propagation()
// touch top and middle items, bottom item should get all events
QTest::touchEvent(window, touchDevice).press(0, pointInTopItem, window)
.press(1, pointInMiddleItem, window);
- QTRY_COMPARE(bottomItem->lastEvent.touchPoints.count(), 2);
+ QTRY_COMPARE(bottomItem->lastEvent.touchPoints.size(), 2);
QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, QEventPoint::State::Pressed,
@@ -868,12 +925,12 @@ void tst_qquickwindow::touchEvent_propagation()
// middle item is disabled or has 0 opacity, bottom item receives the event
QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
- QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
+ QCOMPARE(bottomItem->lastEvent.touchPoints.size(), 1);
COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, QEventPoint::State::Pressed,
makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos))));
} else {
// middle item ignores event, sends it to the top item (top-most child)
- QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+ QCOMPARE(topItem->lastEvent.touchPoints.size(), 1);
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, window, QEventPoint::State::Pressed,
@@ -919,7 +976,7 @@ void tst_qquickwindow::touchEvent_cancel()
QTest::touchEvent(window, touchDevice).press(0, item->mapToScene(pos).toPoint(), window);
QCoreApplication::processEvents();
- QTRY_COMPARE(item->lastEvent.touchPoints.count(), 1);
+ QTRY_COMPARE(item->lastEvent.touchPoints.size(), 1);
TouchEventData d = makeTouchData(QEvent::TouchBegin, window, QEventPoint::State::Pressed, makeTouchPoint(item, pos));
COMPARE_TOUCH_DATA(item->lastEvent, d);
item->reset();
@@ -1020,13 +1077,13 @@ void tst_qquickwindow::touchEvent_velocity()
item->setPosition(QPointF(50, 50));
item->setSize(QSizeF(150, 150));
- QList<QMutableEventPoint> points;
- QMutableEventPoint tp(1, QEventPoint::State::Pressed);
+ QList<QEventPoint> points;
+ QEventPoint tp(1, QEventPoint::State::Pressed, {}, {});
const QPointF localPos = item->mapToScene(QPointF(10, 10));
const QPointF screenPos = window->mapToGlobal(localPos.toPoint());
- tp.setPosition(localPos);
- tp.setGlobalPosition(screenPos);
- tp.setEllipseDiameters(QSizeF(4, 4));
+ QMutableEventPoint::setPosition(tp, localPos);
+ QMutableEventPoint::setGlobalPosition(tp, screenPos);
+ QMutableEventPoint::setEllipseDiameters(tp, QSizeF(4, 4));
points << tp;
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
@@ -1034,17 +1091,17 @@ void tst_qquickwindow::touchEvent_velocity()
QQuickTouchUtils::flush(window);
QCOMPARE(item->touchEventCount, 1);
- points[0].setState(QEventPoint::State::Updated);
- points[0].setPosition(localPos + QPointF(5, 5));
- points[0].setGlobalPosition(screenPos + QPointF(5, 5));
+ QMutableEventPoint::setState(points[0], QEventPoint::State::Updated);
+ QMutableEventPoint::setPosition(points[0], localPos + QPointF(5, 5));
+ QMutableEventPoint::setGlobalPosition(points[0], screenPos + QPointF(5, 5));
QVector2D velocity(1.5, 2.5);
- points[0].setVelocity(velocity);
+ QMutableEventPoint::setVelocity(points[0], velocity);
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
QCOMPARE(item->touchEventCount, 2);
- QCOMPARE(item->lastEvent.touchPoints.count(), 1);
+ QCOMPARE(item->lastEvent.touchPoints.size(), 1);
QCOMPARE(item->lastVelocity, velocity);
// Now have a transformation on the item and check if position is transformed accordingly.
@@ -1052,8 +1109,8 @@ void tst_qquickwindow::touchEvent_velocity()
// during delivery. If we want it to be transformed, we should add QEventPoint::sceneVelocity
// so that we can keep transforming it repeatedly during Item-localization.)
item->setRotation(90); // clockwise
- points[0].setPosition(points[0].position() + QPointF(5, 5));
- points[0].setGlobalPosition(points[0].globalPosition() + QPointF(5, 5));
+ QMutableEventPoint::setPosition(points[0], points[0].position() + QPointF(5, 5));
+ QMutableEventPoint::setGlobalPosition(points[0], points[0].globalPosition() + QPointF(5, 5));
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
@@ -1063,7 +1120,7 @@ void tst_qquickwindow::touchEvent_velocity()
QPoint itemLocalPosFromEvent = item->lastEvent.touchPoints[0].position().toPoint();
QCOMPARE(itemLocalPos, itemLocalPosFromEvent);
- points[0].setState(QEventPoint::State::Released);
+ QMutableEventPoint::setState(points[0], QEventPoint::State::Released);
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
@@ -1160,28 +1217,28 @@ void tst_qquickwindow::mouseFromTouch_basic()
// the first point in each touch event should generate a synth-mouse event.
item->setAcceptTouchEvents(false);
- QList<QMutableEventPoint> points;
- QMutableEventPoint tp(1, QEventPoint::State::Pressed);
+ QList<QEventPoint> points;
+ QEventPoint tp(1, QEventPoint::State::Pressed, {}, {});
const QPointF localPos = item->mapToScene(QPointF(10, 10));
const QPointF screenPos = window->mapToGlobal(localPos.toPoint());
- tp.setPosition(localPos);
- tp.setGlobalPosition(screenPos);
- tp.setEllipseDiameters(QSizeF(4, 4));
+ QMutableEventPoint::setPosition(tp, localPos);
+ QMutableEventPoint::setGlobalPosition(tp, screenPos);
+ QMutableEventPoint::setEllipseDiameters(tp, QSizeF(4, 4));
points << tp;
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
- points[0].setState(QEventPoint::State::Updated);
- points[0].setPosition(localPos + QPointF(5, 5));
- points[0].setGlobalPosition(screenPos + QPointF(5, 5));
+ QMutableEventPoint::setState(points[0], QEventPoint::State::Updated);
+ QMutableEventPoint::setPosition(points[0], localPos + QPointF(5, 5));
+ QMutableEventPoint::setGlobalPosition(points[0], screenPos + QPointF(5, 5));
QVector2D velocity(1.5, 2.5);
- points[0].setVelocity(velocity);
+ QMutableEventPoint::setVelocity(points[0], velocity);
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
- points[0].setState(QEventPoint::State::Released);
+ QMutableEventPoint::setState(points[0], QEventPoint::State::Released);
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
@@ -1195,19 +1252,20 @@ void tst_qquickwindow::mouseFromTouch_basic()
QCOMPARE(item->lastVelocityFromMouseMove, velocity);
// QVERIFY(item->lastMouseCapabilityFlags.testFlag(QInputDevice::Capability::Velocity)); // TODO
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10); // avoid generating a double-click
// Now the same with a transformation.
item->setRotation(90); // clockwise
- points[0].setState(QEventPoint::State::Pressed);
- points[0].setVelocity(velocity);
- tp.setPosition(localPos);
- tp.setGlobalPosition(screenPos);
+ QMutableEventPoint::setState(points[0], QEventPoint::State::Pressed);
+ QMutableEventPoint::setVelocity(points[0], velocity);
+ QMutableEventPoint::setPosition(tp, localPos);
+ QMutableEventPoint::setGlobalPosition(tp, screenPos);
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
QQuickTouchUtils::flush(window);
- points[0].setState(QEventPoint::State::Updated);
- points[0].setPosition(localPos + QPointF(5, 5));
- points[0].setGlobalPosition(screenPos + QPointF(5, 5));
+ QMutableEventPoint::setState(points[0], QEventPoint::State::Updated);
+ QMutableEventPoint::setPosition(points[0], localPos + QPointF(5, 5));
+ QMutableEventPoint::setGlobalPosition(points[0], screenPos + QPointF(5, 5));
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QGuiApplication::processEvents();
@@ -1215,7 +1273,7 @@ void tst_qquickwindow::mouseFromTouch_basic()
QCOMPARE(item->lastMousePos.toPoint(), item->mapFromScene(points[0].position()).toPoint());
QCOMPARE(item->lastVelocityFromMouseMove, velocity); // Velocity is always in scene coords
- points[0].setState(QEventPoint::State::Released);
+ QMutableEventPoint::setState(points[0], QEventPoint::State::Released);
QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window));
QCoreApplication::processEvents();
@@ -1240,7 +1298,7 @@ void tst_qquickwindow::synthMouseFromTouch()
QFETCH(bool, acceptTouch);
QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, synthMouse);
- QScopedPointer<MouseRecordingWindow> window(new MouseRecordingWindow);
+ QScopedPointer<PointerRecordingWindow> window(new PointerRecordingWindow);
QScopedPointer<MouseRecordingItem> item(new MouseRecordingItem(acceptTouch, nullptr));
item->setParentItem(window->contentItem());
window->resize(250, 250);
@@ -1258,9 +1316,9 @@ void tst_qquickwindow::synthMouseFromTouch()
QTest::touchEvent(window.data(), touchDevice).release(0, p2, window.data());
QQuickTouchUtils::flush(window.data());
- QCOMPARE(item->m_touchEvents.count(), acceptTouch ? 3 : 0);
- QCOMPARE(item->m_mouseEvents.count(), (acceptTouch || !synthMouse) ? 0 : 3);
- QCOMPARE(window->m_mouseEvents.count(), 0);
+ QCOMPARE(item->m_touchEvents.size(), acceptTouch ? 3 : 0);
+ QCOMPARE(item->m_mouseEvents.size(), (acceptTouch || !synthMouse) ? 0 : 3);
+ QCOMPARE(window->m_mouseEvents.size(), 0);
for (const auto &ev : item->m_mouseEvents)
QCOMPARE(ev.source, Qt::MouseEventSynthesizedByQt);
}
@@ -1285,7 +1343,7 @@ void tst_qquickwindow::synthMouseDoubleClickFromTouch()
QFETCH(bool, expectedSynthesizedDoubleClickEvent);
QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
- QScopedPointer<MouseRecordingWindow> window(new MouseRecordingWindow);
+ QScopedPointer<PointerRecordingWindow> window(new PointerRecordingWindow);
QScopedPointer<MouseRecordingItem> item(new MouseRecordingItem(false, nullptr));
item->setParentItem(window->contentItem());
window->resize(250, 250);
@@ -1305,7 +1363,7 @@ void tst_qquickwindow::synthMouseDoubleClickFromTouch()
QTest::touchEvent(window.data(), touchDevice).move(1, p2 + movement, window.data());
QTest::touchEvent(window.data(), touchDevice).release(1, p2 + movement, window.data());
- const int eventCount = item->m_mouseEvents.count();
+ const int eventCount = item->m_mouseEvents.size();
QVERIFY(eventCount >= 2);
const int nDoubleClicks = std::count_if(item->m_mouseEvents.constBegin(), item->m_mouseEvents.constEnd(),
@@ -1518,8 +1576,7 @@ void tst_qquickwindow::grab()
}
QImage content = window.grabWindow();
- QCOMPARE(content.width(), int(window.width() * window.devicePixelRatio()));
- QCOMPARE(content.height(), int(window.height() * window.devicePixelRatio()));
+ QCOMPARE(content.size(), window.size() * window.devicePixelRatio());
if (alpha) {
QCOMPARE((uint) content.convertToFormat(QImage::Format_ARGB32_Premultiplied).pixel(0, 0), (uint) 0x00000000);
@@ -1534,8 +1591,7 @@ void tst_qquickwindow::grab()
// never was renderable before grabbing.
window.hide();
QImage content = window.grabWindow();
- QCOMPARE(content.width(), int(window.width() * window.devicePixelRatio()));
- QCOMPARE(content.height(), int(window.height() * window.devicePixelRatio()));
+ QCOMPARE(content.size(), window.size() * window.devicePixelRatio());
if (alpha) {
QCOMPARE((uint) content.convertToFormat(QImage::Format_ARGB32_Premultiplied).pixel(0, 0), (uint) 0x00000000);
} else {
@@ -1546,8 +1602,7 @@ void tst_qquickwindow::grab()
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
content = window.grabWindow();
- QCOMPARE(content.width(), int(window.width() * window.devicePixelRatio()));
- QCOMPARE(content.height(), int(window.height() * window.devicePixelRatio()));
+ QCOMPARE(content.size(), window.size() * window.devicePixelRatio());
if (alpha) {
QCOMPARE((uint) content.convertToFormat(QImage::Format_ARGB32_Premultiplied).pixel(0, 0), (uint) 0x00000000);
} else {
@@ -1556,6 +1611,39 @@ void tst_qquickwindow::grab()
}
}
+class Grabber : public QObject
+{
+ Q_OBJECT
+public:
+ Q_INVOKABLE void grab(QObject *obj) {
+ QQuickWindow *window = qobject_cast<QQuickWindow *>(obj);
+ images.append(window->grabWindow());
+ }
+ QVector<QImage> images;
+};
+
+void tst_qquickwindow::earlyGrab()
+{
+ if (QGuiApplication::platformName() == QLatin1String("minimal"))
+ QSKIP("Skipping due to grabWindow not functional on minimal platforms");
+
+ qmlRegisterType<Grabber>("Test", 1, 0, "Grabber");
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("earlyGrab.qml"));
+ QScopedPointer<QQuickWindow> window(qobject_cast<QQuickWindow *>(component.create()));
+ QVERIFY(!window.isNull());
+ window->setTitle(QTest::currentTestFunction());
+
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ Grabber *grabber = qobject_cast<Grabber *>(window->findChild<QObject *>("grabber"));
+ QVERIFY(grabber);
+ QCOMPARE(grabber->images.size(), 1);
+ QVERIFY(!grabber->images[0].isNull());
+ QCOMPARE(grabber->images[0].convertToFormat(QImage::Format_RGBX8888).pixel(10, 20), QColor(Qt::red).rgb());
+}
+
void tst_qquickwindow::multipleWindows()
{
QList<QQuickWindow *> windows;
@@ -1658,7 +1746,7 @@ void tst_qquickwindow::headless()
// Verify that the visual output is the same
QImage newContent = window->grabWindow();
QString errorMessage;
- QVERIFY2(QQuickVisualTestUtil::compareImages(newContent, originalContent, &errorMessage),
+ QVERIFY2(QQuickVisualTestUtils::compareImages(newContent, originalContent, &errorMessage),
qPrintable(errorMessage));
}
@@ -1693,7 +1781,7 @@ void tst_qquickwindow::destroyShowWithoutHide()
QImage newContent = window->grabWindow();
QString errorMessage;
- QVERIFY2(QQuickVisualTestUtil::compareImages(newContent, originalContent, &errorMessage),
+ QVERIFY2(QQuickVisualTestUtils::compareImages(newContent, originalContent, &errorMessage),
qPrintable(errorMessage));
}
@@ -1719,19 +1807,19 @@ void tst_qquickwindow::focusObject()
QVERIFY(QTest::qWaitForWindowActive(window));
QCOMPARE(window->contentItem(), window->focusObject());
- QCOMPARE(focusObjectSpy.count(), 1);
+ QCOMPARE(focusObjectSpy.size(), 1);
QQuickItem *item1 = window->findChild<QQuickItem*>("item1");
QVERIFY(item1);
item1->setFocus(true);
QCOMPARE(item1, window->focusObject());
- QCOMPARE(focusObjectSpy.count(), 2);
+ QCOMPARE(focusObjectSpy.size(), 2);
QQuickItem *item2 = window->findChild<QQuickItem*>("item2");
QVERIFY(item2);
item2->setFocus(true);
QCOMPARE(item2, window->focusObject());
- QCOMPARE(focusObjectSpy.count(), 3);
+ QCOMPARE(focusObjectSpy.size(), 3);
// set focus for item in non-focused focus scope and
// ensure focusObject does not change and signal is not emitted
@@ -1739,7 +1827,7 @@ void tst_qquickwindow::focusObject()
QVERIFY(item3);
item3->setFocus(true);
QCOMPARE(item2, window->focusObject());
- QCOMPARE(focusObjectSpy.count(), 3);
+ QCOMPARE(focusObjectSpy.size(), 3);
}
void tst_qquickwindow::focusReason()
@@ -1784,24 +1872,24 @@ void tst_qquickwindow::ignoreUnhandledMouseEvents()
item->setParentItem(window->contentItem());
{
- QMouseEvent me(QEvent::MouseButtonPress, QPointF(50, 50), Qt::LeftButton, Qt::LeftButton,
- Qt::NoModifier);
+ QMouseEvent me(QEvent::MouseButtonPress, QPointF(50, 50), window->mapToGlobal(QPointF(50, 50)),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
me.setAccepted(true);
QVERIFY(QCoreApplication::sendEvent(window, &me));
QVERIFY(!me.isAccepted());
}
{
- QMouseEvent me(QEvent::MouseMove, QPointF(51, 51), Qt::LeftButton, Qt::LeftButton,
- Qt::NoModifier);
+ QMouseEvent me(QEvent::MouseMove, QPointF(51, 51), window->mapToGlobal(QPointF(51, 51)),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
me.setAccepted(true);
QVERIFY(QCoreApplication::sendEvent(window, &me));
QVERIFY(!me.isAccepted());
}
{
- QMouseEvent me(QEvent::MouseButtonRelease, QPointF(51, 51), Qt::LeftButton, Qt::LeftButton,
- Qt::NoModifier);
+ QMouseEvent me(QEvent::MouseButtonRelease, QPointF(51, 51), window->mapToGlobal(QPointF(51, 51)),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
me.setAccepted(true);
QVERIFY(QCoreApplication::sendEvent(window, &me));
QVERIFY(!me.isAccepted());
@@ -2080,6 +2168,10 @@ void tst_qquickwindow::testExpose()
void tst_qquickwindow::requestActivate()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("tst_qquickwindow::requestActivate crashes on Android, see QTBUG-103078.");
+#endif
+
QQmlEngine engine;
QQmlComponent component(&engine);
component.loadUrl(testFileUrl("active.qml"));
@@ -2106,7 +2198,7 @@ void tst_qquickwindow::requestActivate()
QTRY_COMPARE(QGuiApplication::focusWindow(), window1.data());
QVERIFY(window1->isActive());
- QQuickItem *item = QQuickVisualTestUtil::findItem<QQuickItem>(window1->contentItem(), "item1");
+ QQuickItem *item = QQuickVisualTestUtils::findItem<QQuickItem>(window1->contentItem(), "item1");
QVERIFY(item);
//copied from src/qmltest/quicktestevent.cpp
@@ -2115,18 +2207,14 @@ void tst_qquickwindow::requestActivate()
{
QMouseEvent me(QEvent::MouseButtonPress, pos, window1->mapToGlobal(pos), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QSpontaneKeyEvent::setSpontaneous(&me);
- if (!qApp->notify(window1.data(), &me)) {
- QString warning = QString::fromLatin1("Mouse event MousePress not accepted by receiving window");
- QWARN(warning.toLatin1().data());
- }
+ if (!qApp->notify(window1.data(), &me))
+ qWarning("Mouse event MousePress not accepted by receiving window");
}
{
QMouseEvent me = QMouseEvent(QEvent::MouseButtonPress, pos, window1->mapToGlobal(pos), Qt::LeftButton, {}, Qt::NoModifier);
QSpontaneKeyEvent::setSpontaneous(&me);
- if (!qApp->notify(window1.data(), &me)) {
- QString warning = QString::fromLatin1("Mouse event MouseRelease not accepted by receiving window");
- QWARN(warning.toLatin1().data());
- }
+ if (!qApp->notify(window1.data(), &me))
+ qWarning("Mouse event MouseRelease not accepted by receiving window");
}
QTRY_COMPARE(QGuiApplication::focusWindow(), windows.at(0));
@@ -2135,6 +2223,10 @@ void tst_qquickwindow::requestActivate()
void tst_qquickwindow::testWindowVisibilityOrder()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("tst_qquickwindow::testWindowVisibilityOrder crashes on Android, see QTBUG-103078.");
+#endif
+
QQmlEngine engine;
QQmlComponent component(&engine);
component.loadUrl(testFileUrl("windoworder.qml"));
@@ -2252,6 +2344,10 @@ void tst_qquickwindow::unloadSubWindow()
// QTBUG-52573
void tst_qquickwindow::changeVisibilityInCompleted()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("tst_qquickwindow::changeVisibilityInCompleted crashes on Android, see QTBUG-103078.");
+#endif
+
QQmlEngine engine;
QQmlComponent component(&engine);
component.loadUrl(testFileUrl("changeVisibilityInCompleted.qml"));
@@ -2293,7 +2389,7 @@ void tst_qquickwindow::qobjectEventFilter_touch()
// press single point
QTest::touchEvent(&window, touchDevice).press(0, item->mapToScene(pos).toPoint(), &window);
- QCOMPARE(eventFilter.events.count(), 1);
+ QCOMPARE(eventFilter.events.size(), 1);
QCOMPARE(eventFilter.events.first(), (int)QEvent::TouchBegin);
}
@@ -2364,7 +2460,7 @@ void tst_qquickwindow::animatingSignal()
window.show();
QTRY_VERIFY(window.isExposed());
- QTRY_VERIFY(spy.count() > 1);
+ QTRY_VERIFY(spy.size() > 1);
}
void tst_qquickwindow::frameSignals()
@@ -2381,9 +2477,9 @@ void tst_qquickwindow::frameSignals()
QSGRendererInterface *rif = window.rendererInterface();
QVERIFY(rif);
- QTRY_VERIFY(beforeSpy.count() > 1);
- QTRY_VERIFY(afterSpy.count() > 1);
- QTRY_COMPARE(beforeSpy.count(), afterSpy.count());
+ QTRY_VERIFY(beforeSpy.size() > 1);
+ QTRY_VERIFY(afterSpy.size() > 1);
+ QTRY_COMPARE(beforeSpy.size(), afterSpy.size());
}
// QTBUG-36938
@@ -2513,7 +2609,8 @@ public:
~RenderJob() { ++deleted; }
QQuickWindow::RenderStage stage;
QList<QQuickWindow::RenderStage> *list;
- void run() {
+ void run() override
+ {
list->append(stage);
}
static int deleted;
@@ -2697,9 +2794,12 @@ public:
setAcceptHoverEvents(true);
}
- void hoverEnterEvent(QHoverEvent *event) { hoverTimestamps << event->timestamp(); }
- void hoverLeaveEvent(QHoverEvent *event) { hoverTimestamps << event->timestamp(); }
- void hoverMoveEvent(QHoverEvent *event) { hoverTimestamps << event->timestamp(); }
+ void hoverEnterEvent(QHoverEvent *event) override
+ { hoverTimestamps << event->timestamp(); }
+ void hoverLeaveEvent(QHoverEvent *event) override
+ { hoverTimestamps << event->timestamp(); }
+ void hoverMoveEvent(QHoverEvent *event) override
+ { hoverTimestamps << event->timestamp(); }
QList<ulong> hoverTimestamps;
};
@@ -2828,8 +2928,8 @@ void tst_qquickwindow::test_circleMapItem()
mat->setObjectName("Top Item/MouseArea");
mat->setSize(QSizeF(40, 40));
- QSignalSpy bottomSpy(mab, SIGNAL(clicked(QQuickMouseEvent *)));
- QSignalSpy topSpy(mat, SIGNAL(clicked(QQuickMouseEvent *)));
+ QSignalSpy bottomSpy(mab, SIGNAL(clicked(QQuickMouseEvent*)));
+ QSignalSpy topSpy(mat, SIGNAL(clicked(QQuickMouseEvent*)));
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
@@ -2838,15 +2938,15 @@ void tst_qquickwindow::test_circleMapItem()
QPoint pos(50, 50);
QTest::mouseClick(&window, Qt::LeftButton, Qt::KeyboardModifiers(), pos);
- QCOMPARE(topSpy.count(), 1);
- QCOMPARE(bottomSpy.count(), 0);
+ QCOMPARE(topSpy.size(), 1);
+ QCOMPARE(bottomSpy.size(), 0);
// Outside the "Circles" "input area", but on top of the bottomItem rectangle
pos = QPoint(66, 66);
QTest::mouseClick(&window, Qt::LeftButton, Qt::KeyboardModifiers(), pos);
- QCOMPARE(bottomSpy.count(), 1);
- QCOMPARE(topSpy.count(), 1);
+ QCOMPARE(bottomSpy.size(), 1);
+ QCOMPARE(topSpy.size(), 1);
}
void tst_qquickwindow::grabContentItemToImage()
@@ -2892,19 +2992,19 @@ public:
dropAccept = true;
}
- void dragEnterEvent(QDragEnterEvent *event)
+ void dragEnterEvent(QDragEnterEvent *event) override
{
event->setAccepted(enterAccept);
event->setDropAction(enterDropAction);
}
- void dragMoveEvent(QDragMoveEvent *event)
+ void dragMoveEvent(QDragMoveEvent *event) override
{
event->setAccepted(moveAccept);
event->setDropAction(moveDropAction);
}
- void dropEvent(QDropEvent *event)
+ void dropEvent(QDropEvent *event) override
{
event->setAccepted(dropAccept);
event->setDropAction(dropDropAction);
@@ -3199,57 +3299,48 @@ public:
*/
bool testFilterPreConditions() const { return !m_filterNotPreAccepted; }
static QVector<DeliveryRecord> &deliveryList() { return m_deliveryList; }
- static QSet<QEvent::Type> &includedEventTypes()
+ static void setExpectedDeliveryList(const QVector<DeliveryRecord> &v) { m_expectedDeliveryList = v; }
+
+ bool isRelevant(QQuickItem *receiver, QEvent *e)
{
- if (m_includedEventTypes.isEmpty())
- m_includedEventTypes << QEvent::MouseButtonPress;
- return m_includedEventTypes;
+ if (receiver->acceptTouchEvents())
+ return e->type() == QEvent::TouchBegin;
+ return e->type() == QEvent::MouseButtonPress;
}
- static void setExpectedDeliveryList(const QVector<DeliveryRecord> &v) { m_expectedDeliveryList = v; }
protected:
bool childMouseEventFilter(QQuickItem *i, QEvent *e) override
{
+ if (!isRelevant(i, e))
+ return QQuickRectangle::childMouseEventFilter(i, e);
+
appendEvent(this, i, e);
- switch (e->type()) {
- case QEvent::MouseButtonPress:
- if (!e->isAccepted())
- m_filterNotPreAccepted = true;
- e->setAccepted(m_filterAccepts);
- // qCDebug(lcTests) << objectName() << i->objectName();
- return m_filterReturns;
- default:
- break;
- }
- return QQuickRectangle::childMouseEventFilter(i, e);
+ if (!e->isAccepted())
+ m_filterNotPreAccepted = true;
+ e->setAccepted(m_filterAccepts);
+ return m_filterReturns;
}
bool event(QEvent *e) override
{
+ if (!isRelevant(this, e))
+ QQuickRectangle::event(e);
+
appendEvent(nullptr, this, e);
- switch (e->type()) {
- case QEvent::MouseButtonPress:
- // qCDebug(lcTests) << objectName();
- e->setAccepted(m_eventAccepts);
- return true;
- default:
- break;
- }
- return QQuickRectangle::event(e);
+ e->setAccepted(m_eventAccepts);
+ return true;
}
private:
static void appendEvent(QQuickItem *filter, QQuickItem *receiver, QEvent *event) {
- if (includedEventTypes().contains(event->type())) {
- auto record = DeliveryRecord(filter ? filter->objectName() : QString(), receiver ? receiver->objectName() : QString());
- int i = m_deliveryList.count();
- if (m_expectedDeliveryList.count() > i && m_expectedDeliveryList[i] == record)
- qCDebug(lcTests).noquote().nospace() << i << ": " << record;
- else
- qCDebug(lcTests).noquote().nospace() << i << ": " << record
- << ", expected " << (m_expectedDeliveryList.count() > i ? m_expectedDeliveryList[i].toString() : QLatin1String("nothing")) << " <---";
- m_deliveryList << record;
- }
+ auto record = DeliveryRecord(filter ? filter->objectName() : QString(), receiver ? receiver->objectName() : QString());
+ int i = m_deliveryList.size();
+ if (m_expectedDeliveryList.size() > i && m_expectedDeliveryList[i] == record)
+ qCDebug(lcTests).noquote().nospace() << i << ": " << record;
+ else
+ qCDebug(lcTests).noquote().nospace() << i << ": " << record
+ << ", expected " << (m_expectedDeliveryList.size() > i ? m_expectedDeliveryList[i].toString() : QLatin1String("nothing")) << " <---";
+ m_deliveryList << record;
}
bool m_eventAccepts;
bool m_filterReturns;
@@ -3259,12 +3350,10 @@ private:
// list of (filtering-parent . receiver) pairs
static DeliveryRecordVector m_expectedDeliveryList;
static DeliveryRecordVector m_deliveryList;
- static QSet<QEvent::Type> m_includedEventTypes;
};
DeliveryRecordVector EventItem::m_expectedDeliveryList;
DeliveryRecordVector EventItem::m_deliveryList;
-QSet<QEvent::Type> EventItem::m_includedEventTypes;
typedef QVector<const char*> CharStarVector;
@@ -3289,11 +3378,17 @@ void tst_qquickwindow::testChildMouseEventFilter_data()
// r0->r1->r2->r3
//
QTest::addColumn<QPoint>("mousePos");
+ QTest::addColumn<QString>("eventMode");
QTest::addColumn<InputState>("inputState");
QTest::addColumn<DeliveryRecordVector>("expectedDeliveryOrder");
- QTest::newRow("if filtered and rejected, do not deliver it to the item that filtered it")
+ for (const QString &eventMode : {"mouse", "touch", "touchToMouse"}) {
+
+ #define desc(txt) qPrintable(QString("%1 events, ").arg(eventMode) + txt)
+
+ QTest::newRow(desc("if filtered and rejected, do not deliver it to the item that filtered it"))
<< QPoint(100, 100)
+ << eventMode
<< InputState({
// | event() | child mouse filter
// +---------+---------+---------+---------
@@ -3311,8 +3406,9 @@ void tst_qquickwindow::testChildMouseEventFilter_data()
<< DeliveryRecord("r1")
);
- QTest::newRow("no filtering, no accepting")
+ QTest::newRow(desc("no filtering, no accepting"))
<< QPoint(100, 100)
+ << eventMode
<< InputState({
// | event() | child mouse filter
// +---------+---------+---------+---------
@@ -3331,8 +3427,9 @@ void tst_qquickwindow::testChildMouseEventFilter_data()
<< DeliveryRecord("root")
);
- QTest::newRow("all filtering, no accepting")
+ QTest::newRow(desc("all filtering, no accepting"))
<< QPoint(100, 100)
+ << eventMode
<< InputState({
// | event() | child mouse filter
// +---------+---------+---------+---------
@@ -3358,8 +3455,9 @@ void tst_qquickwindow::testChildMouseEventFilter_data()
);
- QTest::newRow("some filtering, no accepting")
+ QTest::newRow(desc("some filtering, no accepting"))
<< QPoint(100, 100)
+ << eventMode
<< InputState({
// | event() | child mouse filter
// +---------+---------+---------+---------
@@ -3383,8 +3481,9 @@ void tst_qquickwindow::testChildMouseEventFilter_data()
<< DeliveryRecord("root")
);
- QTest::newRow("r1 accepts")
+ QTest::newRow(desc("r1 accepts"))
<< QPoint(100, 100)
+ << eventMode
<< InputState({
// | event() | child mouse filter
// +---------+---------+---------+---------
@@ -3406,8 +3505,9 @@ void tst_qquickwindow::testChildMouseEventFilter_data()
<< DeliveryRecord("r1")
);
- QTest::newRow("r1 rejects and filters")
+ QTest::newRow(desc("r1 rejects and filters"))
<< QPoint(100, 100)
+ << eventMode
<< InputState({
// | event() | child mouse filter
// +---------+---------+---------+---------
@@ -3430,12 +3530,13 @@ void tst_qquickwindow::testChildMouseEventFilter_data()
<< DeliveryRecord("r0")
<< DeliveryRecord("root")
);
-
+ }
}
void tst_qquickwindow::testChildMouseEventFilter()
{
QFETCH(QPoint, mousePos);
+ QFETCH(QString, eventMode);
QFETCH(InputState, inputState);
QFETCH(DeliveryRecordVector, expectedDeliveryOrder);
@@ -3450,21 +3551,28 @@ void tst_qquickwindow::testChildMouseEventFilter()
QScopedPointer<EventFilter> rootFilter(new EventFilter);
root->installEventFilter(rootFilter.data());
+ const bool useMouseEvents = eventMode == "mouse";
+ const bool acceptTouchEvents = eventMode == "touch";
+
// Create 4 items; each item a child of the previous item.
EventItem *r[4];
r[0] = new EventItem(root);
r[0]->setColor(QColor(0x404040));
r[0]->setWidth(200);
r[0]->setHeight(200);
+ r[0]->setAcceptTouchEvents(acceptTouchEvents);
r[1] = new EventItem(r[0]);
r[1]->setColor(QColor(0x606060));
+ r[1]->setAcceptTouchEvents(acceptTouchEvents);
r[2] = new EventItem(r[1]);
r[2]->setColor(Qt::red);
+ r[2]->setAcceptTouchEvents(acceptTouchEvents);
r[3] = new EventItem(r[2]);
r[3]->setColor(Qt::green);
+ r[3]->setAcceptTouchEvents(acceptTouchEvents);
for (uint i = 0; i < sizeof(r)/sizeof(EventItem*); ++i) {
r[i]->setEventAccepts(inputState.r[i].eventAccepts);
@@ -3481,13 +3589,17 @@ void tst_qquickwindow::testChildMouseEventFilter()
DeliveryRecordVector &actualDeliveryOrder = EventItem::deliveryList();
actualDeliveryOrder.clear();
- QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, mousePos);
+
+ if (useMouseEvents)
+ QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, mousePos);
+ else
+ QTest::touchEvent(&window, touchDevice).press(0, mousePos, &window);
// Check if event got delivered to the root item. If so, append it to the list of items the event got delivered to
if (rootFilter->events.contains(QEvent::MouseButtonPress))
actualDeliveryOrder.append(DeliveryRecord("root"));
- for (int i = 0; i < qMax(actualDeliveryOrder.count(), expectedDeliveryOrder.count()); ++i) {
+ for (int i = 0; i < qMax(actualDeliveryOrder.size(), expectedDeliveryOrder.size()); ++i) {
const DeliveryRecord expectedNames = expectedDeliveryOrder.value(i);
const DeliveryRecord actualNames = actualDeliveryOrder.value(i);
QCOMPARE(actualNames.toString(), expectedNames.toString());
@@ -3497,8 +3609,11 @@ void tst_qquickwindow::testChildMouseEventFilter()
QVERIFY(item->testFilterPreConditions());
}
- // "restore" mouse state
- QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, mousePos);
+ // "restore" mouse/touch state
+ if (useMouseEvents)
+ QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, mousePos);
+ else
+ QTest::touchEvent(&window, touchDevice).release(0, mousePos, &window);
}
void tst_qquickwindow::cleanupGrabsOnRelease()
@@ -3537,6 +3652,48 @@ void tst_qquickwindow::cleanupGrabsOnRelease()
QCOMPARE(parent->mouseUngrabEventCount, 1);
}
+void tst_qquickwindow::subclassWithPointerEventVirtualOverrides_data()
+{
+ QTest::addColumn<const QPointingDevice *>("device");
+
+ QTest::newRow("mouse click") << QPointingDevice::primaryPointingDevice();
+ QTest::newRow("touch tap") << static_cast<const QPointingDevice*>(touchDevice); // TODO QTBUG-107864
+ QTest::newRow("stylus tap") << tabletStylusDevice;
+}
+
+void tst_qquickwindow::subclassWithPointerEventVirtualOverrides() // QTBUG-97859
+{
+ QFETCH(const QPointingDevice *, device);
+
+ PointerRecordingWindow window;
+ window.resize(250, 250);
+ window.setPosition(100, 100);
+ window.setTitle(QTest::currentTestFunction());
+ window.show();
+ QVERIFY(QTest::qWaitForWindowActive(&window));
+ const QPoint pos(120, 120);
+
+ QQuickTest::pointerPress(device, &window, 0, pos);
+ QQuickTest::pointerRelease(device, &window, 0, pos);
+
+ switch (device->type()) {
+ case QPointingDevice::DeviceType::Mouse:
+ QTRY_COMPARE(window.m_mouseEvents.size(), 3); // separate move before press
+ QCOMPARE(window.m_events.size(), 3);
+ break;
+ case QPointingDevice::DeviceType::TouchScreen:
+ QTRY_COMPARE(window.m_touchEvents.size(), 2);
+ QCOMPARE(window.m_events.size(), 2);
+ break;
+ case QPointingDevice::DeviceType::Stylus:
+ QTRY_COMPARE(window.m_tabletEvents.size(), 2);
+ QVERIFY(window.m_events.size() >= window.m_tabletEvents.size()); // tablet + synth-mouse events
+ break;
+ default:
+ break;
+ }
+}
+
#if QT_CONFIG(shortcut)
void tst_qquickwindow::testShortCut()
{
@@ -3559,6 +3716,39 @@ void tst_qquickwindow::testShortCut()
QVERIFY(eventFilter.events.contains(int(QEvent::ShortcutOverride)));
QVERIFY(window->property("received").value<bool>());
}
+
+void tst_qquickwindow::shortcutOverride_data()
+{
+ QTest::addColumn<Qt::Key>("key");
+ QTest::addColumn<bool>("overridden");
+ QTest::addColumn<bool>("receivedA");
+ QTest::addColumn<bool>("receivedB");
+
+ QTest::addRow("Space") << Qt::Key_Space << false << false << false;
+ QTest::addRow("A") << Qt::Key_A << true << false << false;
+ QTest::addRow("B") << Qt::Key_B << false << false << true;
+}
+
+void tst_qquickwindow::shortcutOverride()
+{
+ QFETCH(Qt::Key, key);
+ QFETCH(bool, overridden);
+ QFETCH(bool, receivedA);
+ QFETCH(bool, receivedB);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("shortcutOverride.qml"));
+
+ QScopedPointer<QWindow> window(qobject_cast<QQuickWindow *>(component.create()));
+ QVERIFY(window);
+ QVERIFY(QTest::qWaitForWindowActive(window.get()));
+
+ QTest::keyPress(window.get(), key);
+ QCOMPARE(window->property("overridden").value<bool>(), overridden);
+ QCOMPARE(window->property("receivedA").value<bool>(), receivedA);
+ QCOMPARE(window->property("receivedB").value<bool>(), receivedB);
+}
#endif
void tst_qquickwindow::rendererInterface()
@@ -3676,10 +3866,9 @@ void tst_qquickwindow::rendererInterfaceWithRenderControl_data()
QTest::newRow("Vulkan") << QSGRendererInterface::VulkanRhi;
#endif
#ifdef Q_OS_WIN
- if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7)
- QTest::newRow("D3D11") << QSGRendererInterface::Direct3D11Rhi;
+ QTest::newRow("D3D11") << QSGRendererInterface::Direct3D11Rhi;
#endif
-#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
+#if QT_CONFIG(metal)
QTest::newRow("Metal") << QSGRendererInterface::MetalRhi;
#endif
}
@@ -3878,6 +4067,88 @@ void tst_qquickwindow::rendererInterfaceWithRenderControl()
QQuickWindow::setGraphicsApi(QSGRendererInterface::Unknown);
}
+void tst_qquickwindow::graphicsConfiguration()
+{
+ QQuickGraphicsConfiguration config;
+ qDebug() << config;
+ QVERIFY(config.isDepthBufferEnabledFor2D());
+ QVERIFY(!config.isDebugLayerEnabled());
+ QVERIFY(!config.isDebugMarkersEnabled());
+ QVERIFY(!config.prefersSoftwareDevice());
+ QVERIFY(config.isAutomaticPipelineCacheEnabled());
+ QVERIFY(config.pipelineCacheSaveFile().isEmpty());
+ QVERIFY(config.pipelineCacheLoadFile().isEmpty());
+
+ QQuickGraphicsConfiguration config2 = config;
+ config.setDebugLayer(true);
+ config.setDepthBufferFor2D(false);
+ QVERIFY(config.isDebugLayerEnabled());
+ QVERIFY(!config2.isDebugLayerEnabled());
+
+ config2 = config;
+ QVERIFY(config2.isDebugLayerEnabled());
+ QVERIFY(!config2.isDepthBufferEnabledFor2D());
+
+ config.setAutomaticPipelineCache(false);
+ config.setPipelineCacheSaveFile(QLatin1String("save"));
+ config.setPipelineCacheLoadFile(QLatin1String("load"));
+ config2 = config;
+ QVERIFY(!config2.isAutomaticPipelineCacheEnabled());
+ QCOMPARE(config2.pipelineCacheSaveFile(), QLatin1String("save"));
+ QCOMPARE(config2.pipelineCacheLoadFile(), QLatin1String("load"));
+
+#if QT_CONFIG(vulkan)
+ QCOMPARE(QQuickGraphicsConfiguration::preferredInstanceExtensions(), QRhiVulkanInitParams::preferredInstanceExtensions());
+#endif
+}
+
+void tst_qquickwindow::visibleVsVisibility_data()
+{
+ QTest::addColumn<QUrl>("qmlfile");
+ QTest::addColumn<bool>("expectVisible");
+ QTest::addColumn<bool>("expectConflictingPropertyWarning");
+
+ QTest::newRow("default invisible") << testFileUrl("window.qml") << false << false;
+ QTest::newRow("just visibility") << testFileUrl("maximized.qml") << true << false;
+ // In these conflicting cases, the 'visibility' property "wins" (see QQuickWindowQmlImpl::setWindowVisibility())
+ QTest::newRow("conflicting invisible") << testFileUrl("conflictingVisibleFalse.qml") << true << true;
+ QTest::newRow("conflicting visible") << testFileUrl("conflictingVisibleTrue.qml") << false << true;
+}
+
+void tst_qquickwindow::visibleVsVisibility()
+{
+ QFETCH(QUrl, qmlfile);
+ QFETCH(bool, expectVisible);
+ QFETCH(bool, expectConflictingPropertyWarning);
+
+ const QString warningMsg = qmlfile.toString() + ":3:1: QML Window: Conflicting properties 'visible' and 'visibility'";
+
+ QTest::failOnWarning(QRegularExpression(".*"));
+ if (expectConflictingPropertyWarning)
+ QTest::ignoreMessage(QtWarningMsg, warningMsg.toUtf8().data());
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(qmlfile);
+ QObject *created = component.create();
+ QScopedPointer<QObject> cleanup(created);
+ QVERIFY(created);
+
+ QQuickWindow *window = qobject_cast<QQuickWindow*>(created);
+ QVERIFY(window);
+ QCOMPARE(window->isVisible(), expectVisible);
+}
+
+void tst_qquickwindow::eventTypes()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("eventTypes.qml"));
+ QObject *created = component.create();
+ QScopedPointer<QObject> cleanup(created);
+ QVERIFY(created);
+}
+
QTEST_MAIN(tst_qquickwindow)
#include "tst_qquickwindow.moc"