diff options
author | Daniel d'Andrada <daniel.dandrada@canonical.com> | 2016-07-06 17:01:35 -0300 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2016-07-12 10:41:42 +0000 |
commit | e4f7ab42c6c4f19eed76d9d0de5accda5835a3a8 (patch) | |
tree | 29f8748dd7716132f6dd18701704773f6c0b86c3 | |
parent | 1e18a4f985f6ec4a0191a2e0cc087b13d29b1719 (diff) |
QQuickWindow: Fill out timestamps in QHoverEvents sent to QQuickItems
Task-number: QTBUG-54600
Change-Id: Ie24c44e2f68aae55ff1146c13c3dfc25349b7a29
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 28 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 6 | ||||
-rw-r--r-- | tests/auto/quick/qquickwindow/tst_qquickwindow.cpp | 85 |
3 files changed, 103 insertions, 16 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 14e7915dba..de1b5f236e 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -661,10 +661,10 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e lastMousePosition = me->windowPos(); bool accepted = me->isAccepted(); - bool delivered = deliverHoverEvent(contentItem, me->windowPos(), last, me->modifiers(), accepted); + bool delivered = deliverHoverEvent(contentItem, me->windowPos(), last, me->modifiers(), me->timestamp(), accepted); if (!delivered) { //take care of any exits - accepted = clearHover(); + accepted = clearHover(me->timestamp()); } me->setAccepted(accepted); break; @@ -1397,7 +1397,7 @@ QQuickItem *QQuickWindow::mouseGrabberItem() const } -bool QQuickWindowPrivate::clearHover() +bool QQuickWindowPrivate::clearHover(ulong timestamp) { Q_Q(QQuickWindow); if (hoverItems.isEmpty()) @@ -1407,7 +1407,7 @@ bool QQuickWindowPrivate::clearHover() bool accepted = false; foreach (QQuickItem* item, hoverItems) - accepted = sendHoverEvent(QEvent::HoverLeave, item, pos, pos, QGuiApplication::keyboardModifiers(), true) || accepted; + accepted = sendHoverEvent(QEvent::HoverLeave, item, pos, pos, QGuiApplication::keyboardModifiers(), timestamp, true) || accepted; hoverItems.clear(); return accepted; } @@ -1657,13 +1657,15 @@ void QQuickWindow::mouseDoubleClickEvent(QMouseEvent *event) bool QQuickWindowPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item, const QPointF &scenePos, const QPointF &lastScenePos, - Qt::KeyboardModifiers modifiers, bool accepted) + Qt::KeyboardModifiers modifiers, ulong timestamp, + bool accepted) { Q_Q(QQuickWindow); const QTransform transform = QQuickItemPrivate::get(item)->windowToItemTransform(); //create copy of event QHoverEvent hoverEvent(type, transform.map(scenePos), transform.map(lastScenePos), modifiers); + hoverEvent.setTimestamp(timestamp); hoverEvent.setAccepted(accepted); QSet<QQuickItem *> hasFiltered; @@ -1699,10 +1701,10 @@ void QQuickWindow::mouseMoveEvent(QMouseEvent *event) d->lastMousePosition = event->windowPos(); bool accepted = event->isAccepted(); - bool delivered = d->deliverHoverEvent(d->contentItem, event->windowPos(), last, event->modifiers(), accepted); + bool delivered = d->deliverHoverEvent(d->contentItem, event->windowPos(), last, event->modifiers(), event->timestamp(), accepted); if (!delivered) { //take care of any exits - accepted = d->clearHover(); + accepted = d->clearHover(event->timestamp()); } event->setAccepted(accepted); return; @@ -1712,7 +1714,7 @@ void QQuickWindow::mouseMoveEvent(QMouseEvent *event) } bool QQuickWindowPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &scenePos, const QPointF &lastScenePos, - Qt::KeyboardModifiers modifiers, bool &accepted) + Qt::KeyboardModifiers modifiers, ulong timestamp, bool &accepted) { Q_Q(QQuickWindow); QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); @@ -1728,7 +1730,7 @@ bool QQuickWindowPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &sce QQuickItem *child = children.at(ii); if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled) continue; - if (deliverHoverEvent(child, scenePos, lastScenePos, modifiers, accepted)) + if (deliverHoverEvent(child, scenePos, lastScenePos, modifiers, timestamp, accepted)) return true; } @@ -1737,7 +1739,7 @@ bool QQuickWindowPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &sce if (item->contains(p)) { if (!hoverItems.isEmpty() && hoverItems[0] == item) { //move - accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted); + accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, timestamp, accepted); } else { QList<QQuickItem *> itemsToHover; QQuickItem* parent = item; @@ -1748,12 +1750,12 @@ bool QQuickWindowPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &sce // Leaving from previous hovered items until we reach the item or one of its ancestors. while (!hoverItems.isEmpty() && !itemsToHover.contains(hoverItems[0])) { QQuickItem *hoverLeaveItem = hoverItems.takeFirst(); - sendHoverEvent(QEvent::HoverLeave, hoverLeaveItem, scenePos, lastScenePos, modifiers, accepted); + sendHoverEvent(QEvent::HoverLeave, hoverLeaveItem, scenePos, lastScenePos, modifiers, timestamp, accepted); } if (!hoverItems.isEmpty() && hoverItems[0] == item){//Not entering a new Item // ### Shouldn't we send moves for the parent items as well? - accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted); + accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, timestamp, accepted); } else { // Enter items that are not entered yet. int startIdx = -1; @@ -1772,7 +1774,7 @@ bool QQuickWindowPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &sce // itemToHoverPrivate->window here prevents that case. if (itemToHoverPrivate->window == q && itemToHoverPrivate->hoverEnabled) { hoverItems.prepend(itemToHover); - sendHoverEvent(QEvent::HoverEnter, itemToHover, scenePos, lastScenePos, modifiers, accepted); + sendHoverEvent(QEvent::HoverEnter, itemToHover, scenePos, lastScenePos, modifiers, timestamp, accepted); } } } diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 33aa021d98..be7252d335 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -155,14 +155,14 @@ public: bool deliverTouchCancelEvent(QTouchEvent *); void deliverDelayedTouchEvent(); void flushDelayedTouchEvent(); - bool deliverHoverEvent(QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, bool &accepted); + bool deliverHoverEvent(QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, ulong timestamp, bool &accepted); bool deliverMatchingPointsToItem(QQuickItem *item, QTouchEvent *event, QSet<int> *acceptedNewPoints, const QSet<int> &matchingNewPoints, const QList<QTouchEvent::TouchPoint> &matchingPoints, QSet<QQuickItem*> *filtered); QTouchEvent *touchEventForItemBounds(QQuickItem *target, const QTouchEvent &originalEvent); QTouchEvent *touchEventWithPoints(const QTouchEvent &event, const QList<QTouchEvent::TouchPoint> &newPoints); bool sendFilteredTouchEvent(QQuickItem *target, QQuickItem *item, QTouchEvent *event, QSet<QQuickItem*> *filtered); bool sendHoverEvent(QEvent::Type, QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos, - Qt::KeyboardModifiers modifiers, bool accepted); - bool clearHover(); + Qt::KeyboardModifiers modifiers, ulong timestamp, bool accepted); + bool clearHover(ulong timestamp = 0); #ifndef QT_NO_DRAGANDDROP void deliverDragEvent(QQuickDragGrabber *, QEvent *); bool deliverDragEvent(QQuickDragGrabber *, QQuickItem *, QDragMoveEvent *); diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index c597cf03dd..b03cb856c1 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -371,6 +371,7 @@ private slots: void testRenderJob(); void testHoverChildMouseEventFilter(); + void testHoverTimestamp(); private: QTouchDevice *touchDevice; QTouchDevice *touchDeviceWithVelocity; @@ -2282,6 +2283,90 @@ void tst_qquickwindow::testHoverChildMouseEventFilter() QCOMPARE(middleItem->eventCount(QEvent::HoverEnter), 0); } +class HoverTimestampConsumer : public QQuickItem +{ + Q_OBJECT +public: + HoverTimestampConsumer(QQuickItem *parent = 0) + : QQuickItem(parent) + { + setAcceptHoverEvents(true); + } + + void hoverEnterEvent(QHoverEvent *event) { hoverTimestamps << event->timestamp(); } + void hoverLeaveEvent(QHoverEvent *event) { hoverTimestamps << event->timestamp(); } + void hoverMoveEvent(QHoverEvent *event) { hoverTimestamps << event->timestamp(); } + + QList<ulong> hoverTimestamps; +}; + +// Checks that a QHoverEvent carries the timestamp of the QMouseEvent that caused it. +// QTBUG-54600 +void tst_qquickwindow::testHoverTimestamp() +{ + QQuickWindow window; + + window.resize(200, 200); + window.setPosition(100, 100); + window.setTitle(QTest::currentTestFunction()); + window.show(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + + HoverTimestampConsumer *hoverConsumer = new HoverTimestampConsumer(window.contentItem()); + hoverConsumer->setWidth(100); + hoverConsumer->setHeight(100); + hoverConsumer->setX(50); + hoverConsumer->setY(50); + + // First position, outside + { + QMouseEvent mouseEvent(QEvent::MouseMove, QPointF(40, 40), QPointF(40, 40), QPointF(140, 140), + Qt::NoButton, Qt::NoButton, Qt::NoModifier, Qt::MouseEventNotSynthesized); + mouseEvent.setTimestamp(10); + QVERIFY(QCoreApplication::sendEvent(&window, &mouseEvent)); + } + + // Enter + { + QMouseEvent mouseEvent(QEvent::MouseMove, QPointF(50, 50), QPointF(50, 50), QPointF(150, 150), + Qt::NoButton, Qt::NoButton, Qt::NoModifier, Qt::MouseEventNotSynthesized); + mouseEvent.setTimestamp(20); + QVERIFY(QCoreApplication::sendEvent(&window, &mouseEvent)); + } + QCOMPARE(hoverConsumer->hoverTimestamps.size(), 1); + QCOMPARE(hoverConsumer->hoverTimestamps.last(), 20UL); + + // Move + { + QMouseEvent mouseEvent(QEvent::MouseMove, QPointF(60, 60), QPointF(60, 60), QPointF(160, 160), + Qt::NoButton, Qt::NoButton, Qt::NoModifier, Qt::MouseEventNotSynthesized); + mouseEvent.setTimestamp(30); + QVERIFY(QCoreApplication::sendEvent(&window, &mouseEvent)); + } + QCOMPARE(hoverConsumer->hoverTimestamps.size(), 2); + QCOMPARE(hoverConsumer->hoverTimestamps.last(), 30UL); + + // Move + { + QMouseEvent mouseEvent(QEvent::MouseMove, QPointF(100, 100), QPointF(100, 100), QPointF(200, 200), + Qt::NoButton, Qt::NoButton, Qt::NoModifier, Qt::MouseEventNotSynthesized); + mouseEvent.setTimestamp(40); + QVERIFY(QCoreApplication::sendEvent(&window, &mouseEvent)); + } + QCOMPARE(hoverConsumer->hoverTimestamps.size(), 3); + QCOMPARE(hoverConsumer->hoverTimestamps.last(), 40UL); + + // Leave + { + QMouseEvent mouseEvent(QEvent::MouseMove, QPointF(160, 160), QPointF(160, 160), QPointF(260, 260), + Qt::NoButton, Qt::NoButton, Qt::NoModifier, Qt::MouseEventNotSynthesized); + mouseEvent.setTimestamp(5); + QVERIFY(QCoreApplication::sendEvent(&window, &mouseEvent)); + } + QCOMPARE(hoverConsumer->hoverTimestamps.size(), 4); + QCOMPARE(hoverConsumer->hoverTimestamps.last(), 5UL); +} + QTEST_MAIN(tst_qquickwindow) #include "tst_qquickwindow.moc" |