From 3f62886ac84b31c5c8f90205583dc65e811ad20b Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 5 Mar 2012 15:07:27 +1000 Subject: [PATCH] Handle MouseArea.enabled = false after mouse is pressed. Currently this leaves the MouseArea in a broken state, i.e. still in pressed state, and the next press after it is re-enabled is ignored. In this case we now allow subsequent mouse move or release events to continue. Following the release, no further press will be accepted. Change-Id: I65a890da90e2166ad568505fffdbd3db6c97165b Reviewed-by: Andrew den Exter --- src/quick/items/qquickmousearea.cpp | 12 +- .../quick/qquickmousearea/tst_qquickmousearea.cpp | 105 ++++++++++++++++++++ 2 files changed, 111 insertions(+), 6 deletions(-) diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index ec2c980..ef57242 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -697,7 +697,7 @@ void QQuickMouseArea::mousePressEvent(QMouseEvent *event) void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickMouseArea); - if (!d->absorb) { + if (!d->absorb && !d->pressed) { QQuickItem::mouseMoveEvent(event); return; } @@ -783,7 +783,7 @@ void QQuickMouseArea::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickMouseArea); d->stealMouse = false; - if (!d->absorb) { + if (!d->absorb && !d->pressed) { QQuickItem::mouseReleaseEvent(event); } else { d->saveEvent(event); @@ -820,7 +820,7 @@ void QQuickMouseArea::mouseDoubleClickEvent(QMouseEvent *event) void QQuickMouseArea::hoverEnterEvent(QHoverEvent *event) { Q_D(QQuickMouseArea); - if (!d->absorb) { + if (!d->absorb && !d->pressed) { QQuickItem::hoverEnterEvent(event); } else { d->lastPos = event->posF(); @@ -837,7 +837,7 @@ void QQuickMouseArea::hoverEnterEvent(QHoverEvent *event) void QQuickMouseArea::hoverMoveEvent(QHoverEvent *event) { Q_D(QQuickMouseArea); - if (!d->absorb) { + if (!d->absorb && !d->pressed) { QQuickItem::hoverMoveEvent(event); } else { d->lastPos = event->posF(); @@ -854,7 +854,7 @@ void QQuickMouseArea::hoverMoveEvent(QHoverEvent *event) void QQuickMouseArea::hoverLeaveEvent(QHoverEvent *event) { Q_D(QQuickMouseArea); - if (!d->absorb) + if (!d->absorb && !d->pressed) QQuickItem::hoverLeaveEvent(event); else setHovered(false); @@ -935,7 +935,7 @@ bool QQuickMouseArea::sendMouseEvent(QMouseEvent *event) bool QQuickMouseArea::childMouseEventFilter(QQuickItem *i, QEvent *e) { Q_D(QQuickMouseArea); - if (!d->absorb || !isVisible() || !d->drag || !d->drag->filterChildren()) + if (!d->pressed && (!d->absorb || !isVisible() || !d->drag || !d->drag->filterChildren())) return QQuickItem::childMouseEventFilter(i, e); switch (e->type()) { case QEvent::MouseButtonPress: diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index 0fb82a6..4375e83 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -72,6 +72,7 @@ private slots: void hoverPosition(); void hoverPropagation(); void hoverVisible(); + void disableAfterPress(); private: QQuickView *createView(); @@ -801,6 +802,110 @@ void tst_QQuickMouseArea::hoverVisible() delete canvas; } +void tst_QQuickMouseArea::disableAfterPress() +{ + QQuickView *canvas = createView(); + canvas->setSource(testFileUrl("dragging.qml")); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWait(20); + QVERIFY(canvas->rootObject() != 0); + + QQuickMouseArea *mouseArea = canvas->rootObject()->findChild("mouseregion"); + QQuickDrag *drag = mouseArea->drag(); + QVERIFY(mouseArea != 0); + QVERIFY(drag != 0); + + QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*))); + QSignalSpy mousePressSpy(mouseArea, SIGNAL(pressed(QQuickMouseEvent*))); + QSignalSpy mouseReleaseSpy(mouseArea, SIGNAL(released(QQuickMouseEvent*))); + + // target + QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); + QVERIFY(blackRect != 0); + QVERIFY(blackRect == drag->target()); + + QVERIFY(!drag->active()); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); + + QTRY_COMPARE(mousePressSpy.count(), 1); + + QVERIFY(!drag->active()); + QCOMPARE(blackRect->x(), 50.0); + QCOMPARE(blackRect->y(), 50.0); + + // First move event triggers drag, second is acted upon. + // This is due to possibility of higher stacked area taking precedence. + + QTest::mouseMove(canvas, QPoint(111,111)); + QTest::qWait(50); + QTest::mouseMove(canvas, QPoint(122,122)); + + QTRY_COMPARE(mousePositionSpy.count(), 2); + + QVERIFY(drag->active()); + QCOMPARE(blackRect->x(), 72.0); + QCOMPARE(blackRect->y(), 72.0); + + mouseArea->setEnabled(false); + + // move should still be acted upon + QTest::mouseMove(canvas, QPoint(133,133)); + QTest::qWait(50); + QTest::mouseMove(canvas, QPoint(144,144)); + + QTRY_COMPARE(mousePositionSpy.count(), 4); + + QVERIFY(drag->active()); + QCOMPARE(blackRect->x(), 94.0); + QCOMPARE(blackRect->y(), 94.0); + + QVERIFY(mouseArea->pressed()); + QVERIFY(mouseArea->hovered()); + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(144,144)); + + QTRY_COMPARE(mouseReleaseSpy.count(), 1); + + QVERIFY(!drag->active()); + QCOMPARE(blackRect->x(), 94.0); + QCOMPARE(blackRect->y(), 94.0); + + QVERIFY(!mouseArea->pressed()); + QVERIFY(!mouseArea->hovered()); // since hover is not enabled + + // Next press will be ignored + blackRect->setX(50); + blackRect->setY(50); + + mousePressSpy.clear(); + mousePositionSpy.clear(); + mouseReleaseSpy.clear(); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(50); + QCOMPARE(mousePressSpy.count(), 0); + + QTest::mouseMove(canvas, QPoint(111,111)); + QTest::qWait(50); + QTest::mouseMove(canvas, QPoint(122,122)); + QTest::qWait(50); + + QCOMPARE(mousePositionSpy.count(), 0); + + QVERIFY(!drag->active()); + QCOMPARE(blackRect->x(), 50.0); + QCOMPARE(blackRect->y(), 50.0); + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(122,122)); + QTest::qWait(50); + + QCOMPARE(mouseReleaseSpy.count(), 0); + + delete canvas; +} + QTEST_MAIN(tst_QQuickMouseArea) #include "tst_qquickmousearea.moc" -- 1.7.2.5