Cancel mousearea pressed state when window is deactivated
authorCharles Yin <charles.yin@nokia.com>
Fri, 29 Jul 2011 00:38:35 +0000 (10:38 +1000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 2 Aug 2011 08:46:54 +0000 (10:46 +0200)
Change-Id: I1cc21c338576a2ac3b1e8e282e8e4de3bc63759a
Task-number:QTBUG-19904
Reviewed-on: http://codereview.qt.nokia.com/2357
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/declarative/items/qsgcanvas.cpp
src/declarative/items/qsgitem.cpp
src/declarative/items/qsgitem.h
src/declarative/items/qsgmousearea.cpp
src/declarative/items/qsgmousearea_p.h
tests/auto/declarative/qsgmousearea/data/pressedCanceled.qml [new file with mode: 0644]
tests/auto/declarative/qsgmousearea/tst_qsgmousearea.cpp

index 2efdd50..03b6a72 100644 (file)
@@ -1017,6 +1017,9 @@ bool QSGCanvas::event(QEvent *e)
     case QSGEvent::SGDragDrop:
         d->deliverDragEvent(static_cast<QSGDragEvent *>(e));
         break;
+    case QEvent::WindowDeactivate:
+        rootItem()->windowDeactivateEvent();
+        break;
     default:
         break;
     }
index ef77bfd..f94aa96 100644 (file)
@@ -1714,6 +1714,13 @@ bool QSGItem::childMouseEventFilter(QSGItem *, QEvent *)
     return false;
 }
 
+void QSGItem::windowDeactivateEvent()
+{
+    foreach (QSGItem* item, childItems()) {
+        item->windowDeactivateEvent();
+    }
+}
+
 Qt::InputMethodHints QSGItem::inputMethodHints() const
 {
     Q_D(const QSGItem);
index 2cd2082..249a206 100644 (file)
@@ -370,6 +370,7 @@ protected:
     virtual void dragExitEvent(QSGDragEvent *event);
     virtual void dragDropEvent(QSGDragEvent *event);
     virtual bool childMouseEventFilter(QSGItem *, QEvent *);
+    virtual void windowDeactivateEvent();
 
     virtual void geometryChanged(const QRectF &newGeometry,
                                  const QRectF &oldGeometry);
index 88a617f..5bf0867 100644 (file)
@@ -682,7 +682,7 @@ void QSGMouseArea::hoverLeaveEvent(QHoverEvent *event)
         setHovered(false);
 }
 
-void QSGMouseArea::mouseUngrabEvent()
+void QSGMouseArea::ungrabMouse()
 {
     Q_D(QSGMouseArea);
     if (d->pressed) {
@@ -700,6 +700,11 @@ void QSGMouseArea::mouseUngrabEvent()
     }
 }
 
+void QSGMouseArea::mouseUngrabEvent()
+{
+    ungrabMouse();
+}
+
 bool QSGMouseArea::sendMouseEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QSGMouseArea);
@@ -794,6 +799,12 @@ void QSGMouseArea::timerEvent(QTimerEvent *event)
     }
 }
 
+void QSGMouseArea::windowDeactivateEvent()
+{
+    ungrabMouse();
+    QSGItem::windowDeactivateEvent();
+}
+
 void QSGMouseArea::geometryChanged(const QRectF &newGeometry,
                                             const QRectF &oldGeometry)
 {
index aac829f..ff3863c 100644 (file)
@@ -223,6 +223,7 @@ protected:
     virtual void hoverLeaveEvent(QHoverEvent *event);
     virtual bool childMouseEventFilter(QSGItem *i, QEvent *e);
     virtual void timerEvent(QTimerEvent *event);
+    virtual void windowDeactivateEvent();
 
     virtual void geometryChanged(const QRectF &newGeometry,
                                  const QRectF &oldGeometry);
@@ -231,6 +232,7 @@ protected:
 private:
     void handlePress();
     void handleRelease();
+    void ungrabMouse();
 
 private:
     Q_DISABLE_COPY(QSGMouseArea)
diff --git a/tests/auto/declarative/qsgmousearea/data/pressedCanceled.qml b/tests/auto/declarative/qsgmousearea/data/pressedCanceled.qml
new file mode 100644 (file)
index 0000000..231436d
--- /dev/null
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+
+Rectangle {
+    id: root
+    color: "#ffffff"
+    width: 320; height: 240
+    property bool pressed:mouse.pressed
+    property bool canceled: false
+    property bool released: false
+
+    MouseArea {
+        id: mouse
+        anchors.fill: parent
+        onPressed: { root.canceled = false }
+        onCanceled: {root.canceled = true}
+        onReleased: {root.released = true; root.canceled = false}
+    }
+}
\ No newline at end of file
index e9788cd..6e731d1 100644 (file)
@@ -67,6 +67,7 @@ private slots:
     void updateMouseAreaPosOnResize();
     void noOnClickedWithPressAndHold();
     void onMousePressRejected();
+    void pressedCanceledOnWindowDeactivate();
     void doubleClick();
     void clickTwice();
     void pressedOrdering();
@@ -418,7 +419,51 @@ void tst_QSGMouseArea::onMousePressRejected()
 
     delete canvas;
 }
+void tst_QSGMouseArea::pressedCanceledOnWindowDeactivate()
+{
+    QSGView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pressedCanceled.qml"));
+    canvas->show();
+    canvas->setFocus();
+    QVERIFY(canvas->rootObject() != 0);
+    QVERIFY(!canvas->rootObject()->property("pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
+    QVERIFY(!canvas->rootObject()->property("released").toBool());
+
+    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &pressEvent);
+
+    QVERIFY(canvas->rootObject()->property("pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
+    QVERIFY(!canvas->rootObject()->property("released").toBool());
+
+    QTest::qWait(200);
+
+    QEvent windowDeactivateEvent(QEvent::WindowDeactivate);
+    QApplication::sendEvent(canvas, &windowDeactivateEvent);
+    QVERIFY(!canvas->rootObject()->property("pressed").toBool());
+    QVERIFY(canvas->rootObject()->property("canceled").toBool());
+    QVERIFY(!canvas->rootObject()->property("released").toBool());
 
+    QTest::qWait(200);
+
+    //press again
+    QApplication::sendEvent(canvas, &pressEvent);
+    QVERIFY(canvas->rootObject()->property("pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
+    QVERIFY(!canvas->rootObject()->property("released").toBool());
+
+    QTest::qWait(200);
+
+    //release
+    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &releaseEvent);
+    QVERIFY(!canvas->rootObject()->property("pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
+    QVERIFY(canvas->rootObject()->property("released").toBool());
+
+    delete canvas;
+}
 void tst_QSGMouseArea::doubleClick()
 {
     QSGView *canvas = createView();