aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/handlers/qquickpinchhandler.cpp6
-rw-r--r--src/quick/handlers/qquickpointerdevicehandler.cpp2
-rw-r--r--src/quick/handlers/qquickpointerhandler.cpp3
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp74
4 files changed, 81 insertions, 4 deletions
diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp
index b1dca9a905..fffcc2f848 100644
--- a/src/quick/handlers/qquickpinchhandler.cpp
+++ b/src/quick/handlers/qquickpinchhandler.cpp
@@ -91,6 +91,8 @@ Q_LOGGING_CATEGORY(lcPinchHandler, "qt.quick.handler.pinch")
QQuickPinchHandler::QQuickPinchHandler(QQuickItem *parent)
: QQuickMultiPointHandler(parent, 2)
{
+ // Tell QQuickPointerDeviceHandler::wantsPointerEvent() to ignore button state
+ d_func()->acceptedButtons = Qt::NoButton;
}
/*!
@@ -235,7 +237,7 @@ void QQuickPinchHandler::onActiveChanged()
m_startRotation = t->rotation();
m_startPos = t->position();
} else {
- m_startScale = m_accumulatedScale;
+ m_startScale = 1;
m_startRotation = 0;
}
qCDebug(lcPinchHandler) << "activated with starting scale" << m_startScale << "rotation" << m_startRotation;
@@ -448,7 +450,7 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event)
qCDebug(lcPinchHandler) << "centroid" << centroid().scenePressPosition() << "->" << centroid().scenePosition()
<< ", distance" << m_startDistance << "->" << dist
- << ", startScale" << m_startScale << "->" << m_accumulatedScale
+ << ", scale" << m_startScale << "->" << m_accumulatedScale
<< ", activeRotation" << m_activeRotation
<< ", rotation" << rotation
<< " from " << event->device()->type();
diff --git a/src/quick/handlers/qquickpointerdevicehandler.cpp b/src/quick/handlers/qquickpointerdevicehandler.cpp
index a838f46d83..27f9c3fc36 100644
--- a/src/quick/handlers/qquickpointerdevicehandler.cpp
+++ b/src/quick/handlers/qquickpointerdevicehandler.cpp
@@ -305,7 +305,7 @@ bool QQuickPointerDeviceHandler::wantsPointerEvent(QPointerEvent *event)
return false;
if (d->acceptedModifiers != Qt::KeyboardModifierMask && event->modifiers() != d->acceptedModifiers)
return false;
- // HoverHandler sets acceptedButtons to Qt::NoButton to indicate that button state is irrelevant.
+ // Some handlers (HoverHandler, PinchHandler) set acceptedButtons to Qt::NoButton to indicate that button state is irrelevant.
if (event->pointingDevice()->pointerType() != QPointingDevice::PointerType::Finger &&
acceptedButtons() != Qt::NoButton && event->type() != QEvent::Wheel &&
(static_cast<QSinglePointEvent *>(event)->buttons() & acceptedButtons()) == 0 &&
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp
index f9ae620c75..11c29ee812 100644
--- a/src/quick/handlers/qquickpointerhandler.cpp
+++ b/src/quick/handlers/qquickpointerhandler.cpp
@@ -625,7 +625,8 @@ void QQuickPointerHandler::handlePointerEvent(QPointerEvent *event)
if (wants) {
handlePointerEventImpl(event);
} else {
- setActive(false);
+ if (event->type() != QEvent::NativeGesture)
+ setActive(false);
for (int i = 0; i < event->pointCount(); ++i) {
auto &pt = event->point(i);
if (event->exclusiveGrabber(pt) == this && pt.state() != QEventPoint::Stationary) {
diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
index cd24d8643e..3c46c415f6 100644
--- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp
@@ -50,6 +50,7 @@ private slots:
void pinchProperties();
void scale();
void scaleThreeFingers();
+ void scaleNativeGesture();
void pan();
void dragAxesEnabled_data();
void dragAxesEnabled();
@@ -353,6 +354,79 @@ void tst_QQuickPinchHandler::scaleThreeFingers()
QCOMPARE(pinchHandler->active(), false);
}
+void tst_QQuickPinchHandler::scaleNativeGesture()
+{
+ QQuickView *window = createView();
+ QScopedPointer<QQuickView> scope(window);
+ window->setSource(testFileUrl("pinchproperties.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+ QVERIFY(window->rootObject() != nullptr);
+ qApp->processEvents();
+
+ QQuickPinchHandler *pinchHandler = window->rootObject()->findChild<QQuickPinchHandler*>("pinchHandler");
+ QVERIFY(pinchHandler != nullptr);
+ QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
+ QVERIFY(root != nullptr);
+ QQuickItem *target = window->rootObject()->findChild<QQuickItem*>("blackrect");
+ QVERIFY(target != nullptr);
+
+ QPointF targetPos = target->position();
+ ulong ts = 1;
+
+ // first pinch: scale it up
+ const qreal expectedScale = 1.1;
+ QPointF pinchPos(75, 75);
+ QPointF pinchLocalPos = target->mapFromScene(pinchPos);
+ // target position is adjusted in QQuickItemPrivate::adjustedPosForTransform()
+ // so as to compensate for the change in size, to hold the centroid in place
+ const QPointF expectedPos = targetPos + QPointF( (pinchPos.x() - target->x()) * (expectedScale - 1),
+ (pinchPos.y() - target->y()) * (expectedScale - 1) );
+ QWindowSystemInterface::handleGestureEvent(window, ts++, QPointingDevice::primaryPointingDevice(),
+ Qt::BeginNativeGesture, pinchPos, pinchPos);
+ QWindowSystemInterface::handleGestureEventWithRealValue(window, ts++, QPointingDevice::primaryPointingDevice(),
+ Qt::ZoomNativeGesture, expectedScale - 1, pinchPos, pinchPos);
+ QTRY_COMPARE(target->scale(), expectedScale);
+ QCOMPARE(pinchHandler->active(), true);
+ QCOMPARE(pinchHandler->centroid().position(), pinchLocalPos);
+ QCOMPARE(pinchHandler->centroid().scenePosition(), pinchPos);
+ QVERIFY(qAbs(target->position().x() - expectedPos.x()) < 0.001);
+ QVERIFY(qAbs(target->position().y() - expectedPos.y()) < 0.001);
+ QCOMPARE(pinchHandler->scale(), expectedScale);
+ QCOMPARE(pinchHandler->activeScale(), expectedScale);
+ QCOMPARE(pinchHandler->translation(), QVector2D());
+ QCOMPARE(pinchHandler->rotation(), 0);
+ QWindowSystemInterface::handleGestureEvent(window, ts++, QPointingDevice::primaryPointingDevice(),
+ Qt::EndNativeGesture, pinchPos, pinchPos);
+ QTRY_COMPARE(pinchHandler->active(), false);
+ QCOMPARE(target->scale(), expectedScale);
+ QCOMPARE(pinchHandler->scale(), expectedScale);
+ QCOMPARE(pinchHandler->activeScale(), 1);
+ QCOMPARE(pinchHandler->translation(), QVector2D());
+ QCOMPARE(pinchHandler->rotation(), 0);
+
+ // second pinch at a different position: scale it down to original size again
+ const qreal reverseScale = (1 / expectedScale);
+ pinchPos = QPointF(125, 125);
+ pinchLocalPos = target->mapFromScene(pinchPos);
+ QWindowSystemInterface::handleGestureEvent(window, ts++, QPointingDevice::primaryPointingDevice(),
+ Qt::BeginNativeGesture, pinchPos, pinchPos);
+ QWindowSystemInterface::handleGestureEventWithRealValue(window, ts++, QPointingDevice::primaryPointingDevice(),
+ Qt::ZoomNativeGesture, reverseScale - 1, pinchPos, pinchPos);
+ QTRY_COMPARE(target->scale(), 1);
+ QCOMPARE(pinchHandler->active(), true);
+ QCOMPARE(pinchHandler->centroid().position(), pinchLocalPos);
+ QCOMPARE(pinchHandler->centroid().scenePosition(), pinchPos);
+ QCOMPARE(pinchHandler->scale(), 1);
+ QCOMPARE(pinchHandler->activeScale(), reverseScale);
+ QWindowSystemInterface::handleGestureEvent(window, ts++, QPointingDevice::primaryPointingDevice(),
+ Qt::EndNativeGesture, pinchPos, pinchPos);
+ QTRY_COMPARE(pinchHandler->active(), false);
+ QCOMPARE(target->scale(), 1);
+ QCOMPARE(pinchHandler->scale(), 1);
+ QCOMPARE(pinchHandler->activeScale(), 1);
+}
+
void tst_QQuickPinchHandler::pan()
{
QQuickView *window = createView();