From: Charles Yin Date: Fri, 29 Jul 2011 00:38:35 +0000 (+1000) Subject: Cancel mousearea pressed state when window is deactivated X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=09f4bd20d7514f229338667effdf8519f1722b3f;p=konrad%2Fqtdeclarative.git Cancel mousearea pressed state when window is deactivated Change-Id: I1cc21c338576a2ac3b1e8e282e8e4de3bc63759a Task-number:QTBUG-19904 Reviewed-on: http://codereview.qt.nokia.com/2357 Reviewed-by: Qt Sanity Bot Reviewed-by: Martin Jones --- diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp index 2efdd50..03b6a72 100644 --- a/src/declarative/items/qsgcanvas.cpp +++ b/src/declarative/items/qsgcanvas.cpp @@ -1017,6 +1017,9 @@ bool QSGCanvas::event(QEvent *e) case QSGEvent::SGDragDrop: d->deliverDragEvent(static_cast(e)); break; + case QEvent::WindowDeactivate: + rootItem()->windowDeactivateEvent(); + break; default: break; } diff --git a/src/declarative/items/qsgitem.cpp b/src/declarative/items/qsgitem.cpp index ef77bfd..f94aa96 100644 --- a/src/declarative/items/qsgitem.cpp +++ b/src/declarative/items/qsgitem.cpp @@ -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); diff --git a/src/declarative/items/qsgitem.h b/src/declarative/items/qsgitem.h index 2cd2082..249a206 100644 --- a/src/declarative/items/qsgitem.h +++ b/src/declarative/items/qsgitem.h @@ -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); diff --git a/src/declarative/items/qsgmousearea.cpp b/src/declarative/items/qsgmousearea.cpp index 88a617f..5bf0867 100644 --- a/src/declarative/items/qsgmousearea.cpp +++ b/src/declarative/items/qsgmousearea.cpp @@ -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) { diff --git a/src/declarative/items/qsgmousearea_p.h b/src/declarative/items/qsgmousearea_p.h index aac829f..ff3863c 100644 --- a/src/declarative/items/qsgmousearea_p.h +++ b/src/declarative/items/qsgmousearea_p.h @@ -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 index 0000000..231436d --- /dev/null +++ b/tests/auto/declarative/qsgmousearea/data/pressedCanceled.qml @@ -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 diff --git a/tests/auto/declarative/qsgmousearea/tst_qsgmousearea.cpp b/tests/auto/declarative/qsgmousearea/tst_qsgmousearea.cpp index e9788cd..6e731d1 100644 --- a/tests/auto/declarative/qsgmousearea/tst_qsgmousearea.cpp +++ b/tests/auto/declarative/qsgmousearea/tst_qsgmousearea.cpp @@ -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();