aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@theqtcompany.com>2015-11-30 16:39:15 +0100
committerShawn Rutledge <shawn.rutledge@theqtcompany.com>2015-12-15 07:47:56 +0000
commitfd70c80fe1cac83776cc4730555c8e3dea930c1c (patch)
treeb474775989de996e32ecefb91b3b404aeef78b2e
parentde6352ee937fe84f51c86a834c77e485eaa787b6 (diff)
Fix containsMouse with touch and hoverEnabled
When we synthesize a press/release from touch, the item believes that the mouse never leaves, so if we have several mouse areas, they may all claim that they contain the mouse at the same time. The solution is to synthesize a move back to the actual mouse position. Task-number: QTBUG-40856 Change-Id: I43610d95aa383f847db18b387405b0c4e91cea0f Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
-rw-r--r--src/quick/items/qquickwindow.cpp9
-rw-r--r--tests/auto/quick/touchmouse/data/hoverMouseAreas.qml39
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp89
3 files changed, 137 insertions, 0 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 845fa816c9..e12b22bb00 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -631,6 +631,15 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
if (mouseGrabberItem) {
QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseButtonRelease, p, event, mouseGrabberItem, false));
QCoreApplication::sendEvent(item, me.data());
+
+ if (item->acceptHoverEvents() && p.screenPos() != QGuiApplicationPrivate::lastCursorPosition) {
+ QPointF localMousePos(qInf(), qInf());
+ if (QWindow *w = item->window())
+ localMousePos = item->mapFromScene(w->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition.toPoint()));
+ QMouseEvent mm(QEvent::MouseMove, localMousePos, QGuiApplicationPrivate::lastCursorPosition,
+ Qt::NoButton, Qt::NoButton, event->modifiers());
+ QCoreApplication::sendEvent(item, &mm);
+ }
if (mouseGrabberItem) // might have ungrabbed due to event
mouseGrabberItem->ungrabMouse();
return me->isAccepted();
diff --git a/tests/auto/quick/touchmouse/data/hoverMouseAreas.qml b/tests/auto/quick/touchmouse/data/hoverMouseAreas.qml
new file mode 100644
index 0000000000..1bdd0b3caf
--- /dev/null
+++ b/tests/auto/quick/touchmouse/data/hoverMouseAreas.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.4
+
+Item {
+ width: 500
+ height: 500
+
+ Rectangle {
+ width: 300
+ height: 90
+ color: mouseArea1.containsMouse ? "red" : "grey"
+ x: 100
+ y: 100
+
+ MouseArea {
+ id: mouseArea1
+ objectName: "mouseArea1"
+ anchors.fill: parent
+ hoverEnabled: true
+ onPressed: parent.border.width = 4
+ onReleased: parent.border.width = 0
+ }
+ }
+ Rectangle {
+ width: 300
+ height: 100
+ color: mouseArea2.containsMouse ? "red" : "lightblue"
+ x: 100
+ y: 200
+
+ MouseArea {
+ id: mouseArea2
+ objectName: "mouseArea2"
+ anchors.fill: parent
+ hoverEnabled: true
+ onPressed: parent.border.width = 4
+ onReleased: parent.border.width = 0
+ }
+ }
+}
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
index 90ee8215a1..e14b7d7c84 100644
--- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -161,6 +161,8 @@ private slots:
void touchGrabCausesMouseUngrab();
+ void hoverEnabled();
+
protected:
bool eventFilter(QObject *, QEvent *event)
{
@@ -1232,6 +1234,93 @@ void tst_TouchMouse::touchGrabCausesMouseUngrab()
delete window;
}
+void tst_TouchMouse::hoverEnabled()
+{
+ // QTouchDevice *device = new QTouchDevice;
+ // device->setType(QTouchDevice::TouchScreen);
+ // QWindowSystemInterface::registerTouchDevice(device);
+
+ QQuickView *window = createView();
+ window->setSource(testFileUrl("hoverMouseAreas.qml"));
+
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+ QQuickItem *root = window->rootObject();
+ QVERIFY(root != 0);
+
+ QQuickMouseArea *mouseArea1 = root->findChild<QQuickMouseArea*>("mouseArea1");
+ QVERIFY(mouseArea1 != 0);
+
+ QQuickMouseArea *mouseArea2 = root->findChild<QQuickMouseArea*>("mouseArea2");
+ QVERIFY(mouseArea2 != 0);
+
+ QSignalSpy enterSpy1(mouseArea1, SIGNAL(entered()));
+ QSignalSpy exitSpy1(mouseArea1, SIGNAL(exited()));
+ QSignalSpy clickSpy1(mouseArea1, SIGNAL(clicked(QQuickMouseEvent *)));
+
+ QSignalSpy enterSpy2(mouseArea2, SIGNAL(entered()));
+ QSignalSpy exitSpy2(mouseArea2, SIGNAL(exited()));
+ QSignalSpy clickSpy2(mouseArea2, SIGNAL(clicked(QQuickMouseEvent *)));
+
+ QPoint p0(50, 50);
+ QPoint p1(150, 150);
+ QPoint p2(150, 250);
+
+ // ------------------------- Mouse move to mouseArea1
+ QTest::mouseMove(window, p1);
+
+ QVERIFY(enterSpy1.count() == 1);
+ QVERIFY(mouseArea1->hovered());
+ QVERIFY(!mouseArea2->hovered());
+
+ // ------------------------- Touch click on mouseArea1
+ QTest::touchEvent(window, device).press(0, p1, window);
+
+ QVERIFY(enterSpy1.count() == 1);
+ QVERIFY(enterSpy2.count() == 0);
+ QVERIFY(mouseArea1->pressed());
+ QVERIFY(mouseArea1->hovered());
+ QVERIFY(!mouseArea2->hovered());
+
+ QTest::touchEvent(window, device).release(0, p1, window);
+ QVERIFY(clickSpy1.count() == 1);
+ QVERIFY(mouseArea1->hovered());
+ QVERIFY(!mouseArea2->hovered());
+
+ // ------------------------- Touch click on mouseArea2
+ QTest::touchEvent(window, device).press(0, p2, window);
+
+ QVERIFY(mouseArea1->hovered());
+ QVERIFY(mouseArea2->hovered());
+ QVERIFY(mouseArea2->pressed());
+ QVERIFY(enterSpy1.count() == 1);
+ QVERIFY(enterSpy2.count() == 1);
+
+ QTest::touchEvent(window, device).release(0, p2, window);
+
+ QVERIFY(clickSpy2.count() == 1);
+ QVERIFY(mouseArea1->hovered());
+ QVERIFY(!mouseArea2->hovered());
+ QVERIFY(exitSpy1.count() == 0);
+ QVERIFY(exitSpy2.count() == 1);
+
+ // ------------------------- Another touch click on mouseArea1
+ QTest::touchEvent(window, device).press(0, p1, window);
+
+ QVERIFY(enterSpy1.count() == 1);
+ QVERIFY(enterSpy2.count() == 1);
+ QVERIFY(mouseArea1->pressed());
+ QVERIFY(mouseArea1->hovered());
+ QVERIFY(!mouseArea2->hovered());
+
+ QTest::touchEvent(window, device).release(0, p1, window);
+ QVERIFY(clickSpy1.count() == 2);
+ QVERIFY(mouseArea1->hovered());
+ QVERIFY(!mouseArea1->pressed());
+ QVERIFY(!mouseArea2->hovered());
+}
+
QTEST_MAIN(tst_TouchMouse)
#include "tst_touchmouse.moc"