aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@jollamobile.com>2013-08-12 13:28:17 +1000
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-19 02:50:29 +0200
commit566afc2d2e4156712ffec081715f12307cf46628 (patch)
treeb4f6f77c6898077659fee0c9f449b889f2678880
parent180180d19545665efbf0f939778845a44cb92003 (diff)
Dragging MouseArea nested in Flickable does not work with touch to mouse
A MouseArea with a drag target nested in a Flickable does not work. This is due to QQuickWindow calling childMouseEventFilter() twice - once in sendFilteredTouchEvent() and later in sendEvent(). Since childMouseEventFilter() has already been called, deliver the mouse event directly in sendFilteredTouchEvent(). Task-number: QTBUG-32920 Change-Id: I22acee3c66ee6c06e71c9c876fb02dbcb6119a8d Reviewed-by: Andrew den Exter <andrew.den.exter@qinetic.com.au>
-rw-r--r--src/quick/items/qquickflickable.cpp6
-rw-r--r--src/quick/items/qquickwindow.cpp8
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp69
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp13
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp3
5 files changed, 58 insertions, 41 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 46f95f16cb..8fef1c941e 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -982,6 +982,7 @@ void QQuickFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
q->setKeepMouseGrab(stealMouse);
clearDelayedPress();
pressed = true;
+
if (hData.transitionToBounds)
hData.transitionToBounds->stopTransition();
if (vData.transitionToBounds)
@@ -2095,7 +2096,8 @@ bool QQuickFlickable::sendMouseEvent(QQuickItem *item, QMouseEvent *event)
d->lastPosTime = -1;
returnToBounds();
}
- if (event->type() == QEvent::MouseButtonRelease) {
+ if (event->type() == QEvent::MouseButtonRelease || (grabber && grabber->keepMouseGrab() && !grabberDisabled)) {
+ // mouse released, or another item has claimed the grab
d->lastPosTime = -1;
d->clearDelayedPress();
d->stealMouse = false;
@@ -2108,7 +2110,7 @@ bool QQuickFlickable::sendMouseEvent(QQuickItem *item, QMouseEvent *event)
bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e)
{
Q_D(QQuickFlickable);
- if (!isVisible() || !isEnabled())
+ if (!isVisible() || !isEnabled() || !isInteractive())
return QQuickItem::childMouseEventFilter(i, e);
switch (e->type()) {
case QEvent::MouseButtonPress:
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 525c3d1a0e..0ab929f9a7 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -484,7 +484,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
item->grabMouse();
item->grabTouchPoints(QVector<int>() << touchMouseId);
- q->sendEvent(item, mousePress.data());
+ QQuickItemPrivate::get(item)->deliverMouseEvent(mousePress.data());
event->setAccepted(mousePress->isAccepted());
if (!mousePress->isAccepted()) {
touchMouseId = -1;
@@ -497,7 +497,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
if (mousePress->isAccepted() && checkIfDoubleClicked(event->timestamp())) {
QScopedPointer<QMouseEvent> mouseDoubleClick(touchToMouseEvent(QEvent::MouseButtonDblClick, p, event, item));
- q->sendEvent(item, mouseDoubleClick.data());
+ QQuickItemPrivate::get(item)->deliverMouseEvent(mouseDoubleClick.data());
event->setAccepted(mouseDoubleClick->isAccepted());
if (mouseDoubleClick->isAccepted()) {
return true;
@@ -518,7 +518,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
if (p.state() & Qt::TouchPointMoved) {
if (mouseGrabberItem) {
QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseMove, p, event, mouseGrabberItem));
- q->sendEvent(mouseGrabberItem, me.data());
+ QQuickItemPrivate::get(item)->deliverMouseEvent(me.data());
event->setAccepted(me->isAccepted());
if (me->isAccepted()) {
itemForTouchPointId[p.id()] = mouseGrabberItem; // N.B. the mouseGrabberItem may be different after returning from sendEvent()
@@ -548,7 +548,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
touchMouseId = -1;
if (mouseGrabberItem) {
QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseButtonRelease, p, event, mouseGrabberItem));
- q->sendEvent(mouseGrabberItem, me.data());
+ QQuickItemPrivate::get(item)->deliverMouseEvent(me.data());
if (mouseGrabberItem) // might have ungrabbed due to event
mouseGrabberItem->ungrabMouse();
return me->isAccepted();
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index a8055b3467..dd9fa47d81 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -94,9 +94,10 @@ private slots:
void flickTwiceUsingTouches();
void nestedStopAtBounds();
void nestedStopAtBounds_data();
+ void nestedMouseAreaUsingTouch();
private:
- void flickWithTouch(QWindow *window, QTouchDevice *touchDevice);
+ void flickWithTouch(QWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to);
QQmlEngine engine;
};
@@ -1268,13 +1269,13 @@ void tst_qquickflickable::flickTwiceUsingTouches()
QVERIFY(flickable != 0);
QCOMPARE(flickable->contentY(), 0.0f);
- flickWithTouch(window, touchDevice);
+ flickWithTouch(window, touchDevice, QPoint(100, 400), QPoint(100, 240));
qreal contentYAfterFirstFlick = flickable->contentY();
qDebug() << "contentYAfterFirstFlick " << contentYAfterFirstFlick;
QVERIFY(contentYAfterFirstFlick > 50.0f);
- flickWithTouch(window, touchDevice);
+ flickWithTouch(window, touchDevice, QPoint(100, 400), QPoint(100, 240));
// In the original bug, that second flick would cause Flickable to halt immediately
qreal contentYAfterSecondFlick = flickable->contentY();
@@ -1284,34 +1285,19 @@ void tst_qquickflickable::flickTwiceUsingTouches()
delete window;
}
-void tst_qquickflickable::flickWithTouch(QWindow *window, QTouchDevice *touchDevice)
+void tst_qquickflickable::flickWithTouch(QWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to)
{
QTest::touchEvent(window, touchDevice)
- .press(0, QPoint(100, 400), window);
- QTest::qWait(1);
- QTest::touchEvent(window, touchDevice)
- .move(0, QPoint(100, 380), window);
- QTest::qWait(1);
- QTest::touchEvent(window, touchDevice)
- .move(0, QPoint(100, 360), window);
- QTest::qWait(1);
- QTest::touchEvent(window, touchDevice)
- .move(0, QPoint(100, 340), window);
- QTest::qWait(1);
- QTest::touchEvent(window, touchDevice)
- .move(0, QPoint(100, 320), window);
- QTest::qWait(1);
- QTest::touchEvent(window, touchDevice)
- .move(0, QPoint(100, 300), window);
- QTest::qWait(1);
- QTest::touchEvent(window, touchDevice)
- .move(0, QPoint(100, 280), window);
- QTest::qWait(1);
- QTest::touchEvent(window, touchDevice)
- .move(0, QPoint(100, 260), window);
+ .press(0, from, window);
QTest::qWait(1);
+ QPoint diff = to - from;
+ for (int i = 1; i <= 8; ++i) {
+ QTest::touchEvent(window, touchDevice)
+ .move(0, from + i*diff/8, window);
+ QTest::qWait(1);
+ }
QTest::touchEvent(window, touchDevice)
- .release(0, QPoint(100, 240), window);
+ .release(0, to, window);
QTest::qWait(1);
}
@@ -1384,6 +1370,35 @@ void tst_qquickflickable::nestedStopAtBounds()
QTRY_VERIFY(!outer->isMoving());
}
+void tst_qquickflickable::nestedMouseAreaUsingTouch()
+{
+ QTouchDevice *touchDevice = new QTouchDevice;
+ touchDevice->setName("Fake Touchscreen");
+ touchDevice->setType(QTouchDevice::TouchScreen);
+ touchDevice->setCapabilities(QTouchDevice::Position);
+ QWindowSystemInterface::registerTouchDevice(touchDevice);
+
+ QQuickView *window = new QQuickView;
+ window->setSource(testFileUrl("nestedmousearea.qml"));
+ window->show();
+ QVERIFY(window->rootObject() != 0);
+
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
+ QVERIFY(flickable != 0);
+
+ QCOMPARE(flickable->contentY(), 50.0f);
+ flickWithTouch(window, touchDevice, QPoint(100, 300), QPoint(100, 200));
+
+ // flickable should not have moved
+ QCOMPARE(flickable->contentY(), 50.0);
+
+ // draggable item should have moved up
+ QQuickItem *nested = window->rootObject()->findChild<QQuickItem*>("nested");
+ QVERIFY(nested->y() < 100.0);
+
+ delete window;
+}
+
QTEST_MAIN(tst_qquickflickable)
#include "tst_qquickflickable.moc"
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index a582c62701..f92612e411 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -1198,18 +1198,15 @@ void tst_QQuickMouseArea::transformedMouseArea()
foreach (const QPoint &point, points) {
// check hover
QTest::mouseMove(window, point);
- QTest::qWait(10);
- QCOMPARE(mouseArea->property("containsMouse").toBool(), insideTarget);
+ QTRY_COMPARE(mouseArea->property("containsMouse").toBool(), insideTarget);
// check mouse press
QTest::mousePress(window, Qt::LeftButton, 0, point);
- QTest::qWait(10);
- QCOMPARE(mouseArea->property("pressed").toBool(), insideTarget);
+ QTRY_COMPARE(mouseArea->property("pressed").toBool(), insideTarget);
// check mouse release
QTest::mouseRelease(window, Qt::LeftButton, 0, point);
- QTest::qWait(10);
- QCOMPARE(mouseArea->property("pressed").toBool(), false);
+ QTRY_COMPARE(mouseArea->property("pressed").toBool(), false);
}
delete window;
@@ -1514,8 +1511,8 @@ void tst_QQuickMouseArea::nestedStopAtBounds()
QTest::mouseMove(&view, position);
axis += invert ? -threshold : threshold;
QTest::mouseMove(&view, position);
- QCOMPARE(outer->drag()->active(), false);
- QCOMPARE(inner->drag()->active(), true);
+ QTRY_COMPARE(outer->drag()->active(), false);
+ QTRY_COMPARE(inner->drag()->active(), true);
QTest::mouseRelease(&view, Qt::LeftButton, 0, position);
}
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
index 4779942406..6cf0aa4749 100644
--- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -867,6 +867,9 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
QGuiApplication::processEvents();
//QVERIFY(flickable->isMovingHorizontally());
+
+ // Wait for flick to end
+ QTRY_VERIFY(!flickable->isMoving());
qDebug() << "Pos: " << rect->position();
// pinch