diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2017-01-18 13:53:07 +0100 |
---|---|---|
committer | Jan Arve Sæther <jan-arve.saether@qt.io> | 2017-02-07 16:30:18 +0000 |
commit | fb8058e5bfbd412e4503eb280721e4875fda0936 (patch) | |
tree | e24830323e33f826071d28ba7f8c0e0160a8fa5d /src | |
parent | e2fd141372335f917c2d216051abb00d8b15f87c (diff) |
QQuickWindow: use QVector eventDeliveryTargets to avoid repeated delivery
If no handler or item accepts a newly-pressed point, the event will be
re-delivered in deliverTouchEvent(). It doesn't make sense to
re-deliver to the same handlers though.
A temporary QSet isn't cheap to create, whereas it seems we will need
to keep track of handlers which have already been visited, in order to
avoid visiting passively-grabbing handlers multiple times. Since both
a QVector and a QSet are heap-allocated, and we expect to have a limited
quantity of handlers grabbing at one time, a retained QVector (cleared
between events) seems to be the cheapest data structure.
Change-Id: I831e9a2576b2fcb9095e065795f2baff58115a49
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickevents.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickevents_p_p.h | 3 | ||||
-rw-r--r-- | src/quick/items/qquickitem.cpp | 4 |
3 files changed, 8 insertions, 1 deletions
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index a68e72b0b7..d7b5fe79de 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -731,6 +731,7 @@ QQuickPointerEvent *QQuickPointerMouseEvent::reset(QEvent *event) return this; m_device = QQuickPointerDevice::genericMouseDevice(); + m_device->eventDeliveryTargets().clear(); m_button = ev->button(); m_pressedButtons = ev->buttons(); Qt::TouchPointState state = Qt::TouchPointStationary; @@ -765,6 +766,7 @@ QQuickPointerEvent *QQuickPointerTouchEvent::reset(QEvent *event) return this; m_device = QQuickPointerDevice::touchDevice(ev->device()); + m_device->eventDeliveryTargets().clear(); m_button = Qt::NoButton; m_pressedButtons = Qt::NoButton; diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index bbfc34dacf..1751e366b2 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -553,6 +553,8 @@ public: static QQuickPointerDevice *genericMouseDevice(); static QQuickPointerDevice *tabletDevice(qint64); + QVector<QQuickPointerHandler *> &eventDeliveryTargets() { return m_eventDeliveryTargets; } + private: QQuickPointerDevice(DeviceType devType, PointerType pType, Capabilities caps, int maxPoints, int buttonCount, const QString &name, qint64 uniqueId = 0) : m_deviceType(devType), m_pointerType(pType), m_capabilities(caps) @@ -579,6 +581,7 @@ private: QPointingDeviceUniqueId m_uniqueId; // the device-specific event instance which is reused during event delivery QQuickPointerEvent *m_event; + QVector<QQuickPointerHandler *> m_eventDeliveryTargets; // during delivery, handlers which have already seen the event Q_DISABLE_COPY(QQuickPointerDevice) friend struct ConstructableQQuickPointerDevice; diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 46e381db7d..9b91b4bda4 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -5095,12 +5095,14 @@ bool QQuickItemPrivate::handlePointerEvent(QQuickPointerEvent *event, bool avoid { Q_Q(QQuickItem); bool delivered = false; + QVector<QQuickPointerHandler *> &eventDeliveryTargets = event->device()->eventDeliveryTargets(); if (extra.isAllocated()) { for (QQuickPointerHandler *handler : extra->pointerHandlers) { qCDebug(lcPointerHandlerDispatch) << " delivering" << event << "to" << handler << "on" << q; - if (!avoidGrabber || !event->hasGrabber(handler)) { + if ((!avoidGrabber || !event->hasGrabber(handler)) && !eventDeliveryTargets.contains(handler)) { handler->handlePointerEvent(event); delivered = true; + eventDeliveryTargets.append(handler); } } } |