diff options
author | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2016-07-29 14:09:00 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2016-08-02 10:35:47 +0000 |
commit | e611c00d8c73f0aae77920646db88c09f0f880fa (patch) | |
tree | 4ef727cef316a9712cb970eec11b4d7f3b6a2e93 | |
parent | 388b2c5b46365a12aea5aaab091f24314349a102 (diff) |
Stop copying mouse events when delivering them
Reduce allocations of events, just refill the local pos.
Change-Id: I2948faf0e302bff315e482f2c1432fe0def19bc5
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r-- | src/quick/items/qquickevents.cpp | 6 | ||||
-rw-r--r-- | src/quick/items/qquickevents_p_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 35 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquickwindow/tst_qquickwindow.cpp | 12 |
5 files changed, 34 insertions, 23 deletions
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 39dcf0ac1c..cfc35efbb4 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -619,9 +619,11 @@ bool QQuickPointerMouseEvent::allPointsAccepted() const { return m_mousePoint->isAccepted(); } -QMouseEvent *QQuickPointerMouseEvent::asMouseEvent() const +QMouseEvent *QQuickPointerMouseEvent::asMouseEvent(const QPointF &localPos) const { - return static_cast<QMouseEvent *>(m_event); + auto event = static_cast<QMouseEvent *>(m_event); + event->setLocalPos(localPos); + return event; } QVector<QQuickItem *> QQuickPointerMouseEvent::grabbers() const diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index 571c257a26..072a90d864 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -401,7 +401,7 @@ public: QVector<QQuickItem *> grabbers() const override; void clearGrabbers() const override; - QMouseEvent *asMouseEvent() const; + QMouseEvent *asMouseEvent(const QPointF& localPos) const; private: QQuickEventPoint *m_mousePoint; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 0b3026c167..e08147d7b0 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1622,56 +1622,57 @@ QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *t return me; } -bool QQuickWindowPrivate::deliverInitialMousePressEvent(QMouseEvent *event) +void QQuickWindowPrivate::deliverInitialMousePressEvent(QQuickPointerMouseEvent *event) { Q_Q(QQuickWindow); + QPointF scenePos = event->point(0)->scenePos(); - QVector<QQuickItem *> targets = pointerTargets(contentItem, event->windowPos(), true); + QVector<QQuickItem *> targets = pointerTargets(contentItem, scenePos, true); for (QQuickItem *item: qAsConst(targets)) { QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); if (itemPrivate->acceptedMouseButtons() & event->button()) { - QPointF localPos = item->mapFromScene(event->windowPos()); + QPointF localPos = item->mapFromScene(scenePos); if (item->contains(localPos)) { - QScopedPointer<QMouseEvent> me(cloneMouseEvent(event, &localPos)); + QMouseEvent *me = event->asMouseEvent(localPos); me->accept(); - q->sendEvent(item, me.data()); - event->setAccepted(me->isAccepted()); + q->sendEvent(item, me); if (me->isAccepted()) { if (!q->mouseGrabberItem()) item->grabMouse(); - return true; + return; } } } } - return false; + // no item accepted the event, make sure we don't accept the original mouse event + event->asMouseEvent(QPointF())->setAccepted(false); } void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent) { Q_Q(QQuickWindow); - auto event = pointerEvent->asMouseEvent(); lastMousePosition = pointerEvent->point(0)->scenePos(); QQuickItem *mouseGrabberItem = q->mouseGrabberItem(); if (mouseGrabberItem) { // send update - QPointF localPos = mouseGrabberItem->mapFromScene(event->windowPos()); - QScopedPointer<QMouseEvent> me(cloneMouseEvent(event, &localPos)); + QPointF localPos = mouseGrabberItem->mapFromScene(lastMousePosition); + auto me = pointerEvent->asMouseEvent(localPos); me->accept(); - q->sendEvent(mouseGrabberItem, me.data()); - event->setAccepted(me->isAccepted()); + q->sendEvent(mouseGrabberItem, me); + pointerEvent->point(0)->setAccepted(me->isAccepted()); // release event, make sure to ungrab if there still is a grabber - if (event->type() == QEvent::MouseButtonRelease && !event->buttons() && q->mouseGrabberItem()) + if (me->type() == QEvent::MouseButtonRelease && !me->buttons() && q->mouseGrabberItem()) q->mouseGrabberItem()->ungrabMouse(); } else { // send initial press - event->setAccepted(false); if (pointerEvent->isPressEvent()) { - bool delivered = deliverInitialMousePressEvent(event); - event->setAccepted(delivered); + deliverInitialMousePressEvent(pointerEvent); + } else { + // make sure not to accept unhandled events + pointerEvent->asMouseEvent(QPointF())->setAccepted(false); } } } diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 5747a26c9d..a97ed36b09 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -145,7 +145,7 @@ public: void removeGrabber(QQuickItem *grabber, bool mouse = true, bool touch = true); static void transformTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints, const QTransform &transform); static QMouseEvent *cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos = 0); - bool deliverInitialMousePressEvent(QMouseEvent *); + void deliverInitialMousePressEvent(QQuickPointerMouseEvent *); void deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent); bool sendFilteredMouseEvent(QQuickItem *, QQuickItem *, QEvent *, QSet<QQuickItem *> *); #ifndef QT_NO_WHEELEVENT diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index e57e27533b..a9953b944c 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -2400,19 +2400,27 @@ void tst_qquickwindow::testHoverChildMouseEventFilter() void tst_qquickwindow::pointerEventTypeAndPointCount() { - QMouseEvent me(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QPointF localPosition(33, 66); + QPointF scenePosition(133, 166); + QPointF screenPosition(333, 366); + QMouseEvent me(QEvent::MouseButtonPress, localPosition, scenePosition, screenPosition, + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QTouchEvent te(QEvent::TouchBegin, touchDevice, Qt::NoModifier, Qt::TouchPointPressed, QList<QTouchEvent::TouchPoint>() << QTouchEvent::TouchPoint(1)); + QQuickPointerMouseEvent pme; pme.reset(&me); QVERIFY(pme.isValid()); - QCOMPARE(pme.asMouseEvent(), &me); + QCOMPARE(pme.asMouseEvent(localPosition), &me); QVERIFY(pme.asPointerMouseEvent()); QVERIFY(!pme.asPointerTouchEvent()); QVERIFY(!pme.asPointerTabletEvent()); // QVERIFY(!pe->asTabletEvent()); // TODO QCOMPARE(pme.pointCount(), 1); + QCOMPARE(pme.point(0)->scenePos(), scenePosition); + QCOMPARE(pme.asMouseEvent(localPosition)->localPos(), localPosition); + QCOMPARE(pme.asMouseEvent(localPosition)->screenPos(), screenPosition); QQuickPointerTouchEvent pte; pte.reset(&te); |