From 222f22f626d8ae92500da440a4fb5f429da52407 Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoffart@woboq.com>
Date: Wed, 3 Sep 2014 20:42:04 +0200
Subject: [PATCH] MouseArea: Fix cancelling the double click when the windows
 loses focus

Without this, the next click is not received after the windows loses
focus while we double clicked but not released the mouse.

This may happen if the onDoubleClicked opens a new window

Change-Id: I86742de2bb1ea4c9657b9d5e90472d093293177d
Reviewed-by: Alan Alpert <aalpert@blackberry.com>
---
 src/quick/items/qquickmousearea.cpp           |  1 +
 .../qquickmousearea/data/pressedCanceled.qml  |  8 ++-
 .../qquickmousearea/tst_qquickmousearea.cpp   | 53 ++++++++++++++++---
 3 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 4af728d14f..dc7ba96c35 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -843,6 +843,7 @@ void QQuickMouseArea::ungrabMouse()
         // state
         d->pressed = 0;
         d->stealMouse = false;
+        d->doubleClick = false;
         setKeepMouseGrab(false);
 
 #ifndef QT_NO_DRAGANDDROP
diff --git a/tests/auto/quick/qquickmousearea/data/pressedCanceled.qml b/tests/auto/quick/qquickmousearea/data/pressedCanceled.qml
index 14630b8962..9079cbdfce 100644
--- a/tests/auto/quick/qquickmousearea/data/pressedCanceled.qml
+++ b/tests/auto/quick/qquickmousearea/data/pressedCanceled.qml
@@ -7,7 +7,9 @@ Rectangle {
     width: 320; height: 240
     property bool pressed:mouse.pressed
     property bool canceled: false
-    property bool released: false
+    property int clicked: 0
+    property int doubleClicked: 0
+    property int released: 0
     property alias secondWindow: secondWindow
 
     Window {
@@ -20,6 +22,8 @@ Rectangle {
         anchors.fill: parent
         onPressed: { root.canceled = false }
         onCanceled: {root.canceled = true}
-        onReleased: {root.released = true; root.canceled = false}
+        onReleased: {root.released++; root.canceled = false}
+        onClicked: {root.clicked++}
+        onDoubleClicked: {root.doubleClicked++}
     }
 }
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index 99634c55e5..2fd2e03966 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -88,6 +88,7 @@ private slots:
     void updateMouseAreaPosOnResize();
     void noOnClickedWithPressAndHold();
     void onMousePressRejected();
+    void pressedCanceledOnWindowDeactivate_data();
     void pressedCanceledOnWindowDeactivate();
     void doubleClick_data() { acceptedButton_data(); }
     void doubleClick();
@@ -731,8 +732,19 @@ void tst_QQuickMouseArea::onMousePressRejected()
     QVERIFY(!window.rootObject()->property("mr1_canceled").toBool());
     QVERIFY(!window.rootObject()->property("mr2_released").toBool());
 }
+
+void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate_data()
+{
+    QTest::addColumn<bool>("doubleClick");
+    QTest::newRow("simple click") << false;
+    QTest::newRow("double click") << true;
+}
+
+
 void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
 {
+    QFETCH(bool, doubleClick);
+
     QQuickView window;
     QByteArray errorMessage;
     QVERIFY2(initView(window, testFileUrl("pressedCanceled.qml"), true, &errorMessage), errorMessage.constData());
@@ -741,14 +753,41 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
     QVERIFY(window.rootObject() != 0);
     QVERIFY(!window.rootObject()->property("pressed").toBool());
     QVERIFY(!window.rootObject()->property("canceled").toBool());
-    QVERIFY(!window.rootObject()->property("released").toBool());
+
+    int expectedRelease = 0;
+    int expectedClicks = 0;
+    QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease);
+    QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks);
+
 
     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+
     QGuiApplication::sendEvent(&window, &pressEvent);
 
     QVERIFY(window.rootObject()->property("pressed").toBool());
     QVERIFY(!window.rootObject()->property("canceled").toBool());
-    QVERIFY(!window.rootObject()->property("released").toBool());
+    QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease);
+    QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks);
+
+    if (doubleClick) {
+        QGuiApplication::sendEvent(&window, &releaseEvent);
+        QVERIFY(!window.rootObject()->property("pressed").toBool());
+        QVERIFY(!window.rootObject()->property("canceled").toBool());
+        QCOMPARE(window.rootObject()->property("released").toInt(), ++expectedRelease);
+        QCOMPARE(window.rootObject()->property("clicked").toInt(), ++expectedClicks);
+
+        QGuiApplication::sendEvent(&window, &pressEvent);
+        QMouseEvent pressEvent2(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+        QGuiApplication::sendEvent(&window, &pressEvent2);
+
+        QVERIFY(window.rootObject()->property("pressed").toBool());
+        QVERIFY(!window.rootObject()->property("canceled").toBool());
+        QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease);
+        QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks);
+        QCOMPARE(window.rootObject()->property("doubleClicked").toInt(), 1);
+    }
+
 
     QWindow *secondWindow = qvariant_cast<QWindow*>(window.rootObject()->property("secondWindow"));
     secondWindow->setProperty("visible", true);
@@ -756,22 +795,24 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
 
     QVERIFY(!window.rootObject()->property("pressed").toBool());
     QVERIFY(window.rootObject()->property("canceled").toBool());
-    QVERIFY(!window.rootObject()->property("released").toBool());
+    QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease);
+    QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks);
 
     //press again
     QGuiApplication::sendEvent(&window, &pressEvent);
     QVERIFY(window.rootObject()->property("pressed").toBool());
     QVERIFY(!window.rootObject()->property("canceled").toBool());
-    QVERIFY(!window.rootObject()->property("released").toBool());
+    QCOMPARE(window.rootObject()->property("released").toInt(), expectedRelease);
+    QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks);
 
     QTest::qWait(200);
 
     //release
-    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
     QGuiApplication::sendEvent(&window, &releaseEvent);
     QVERIFY(!window.rootObject()->property("pressed").toBool());
     QVERIFY(!window.rootObject()->property("canceled").toBool());
-    QVERIFY(window.rootObject()->property("released").toBool());
+    QCOMPARE(window.rootObject()->property("released").toInt(), ++expectedRelease);
+    QCOMPARE(window.rootObject()->property("clicked").toInt(), ++expectedClicks);
 }
 
 void tst_QQuickMouseArea::doubleClick()
-- 
GitLab