aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickevents.cpp4
-rw-r--r--src/quick/items/qquickevents_p_p.h3
-rw-r--r--src/quick/items/qquickwindow.cpp45
-rw-r--r--src/quick/items/qquickwindow_p.h8
4 files changed, 48 insertions, 12 deletions
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 4f677e841c..911cc9a52c 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -450,8 +450,8 @@ Item {
to expose the event to QML, the same as is done with QQuickMouseEvent,
QQuickTouchPoint, QQuickKeyEvent, etc. Since only one event can be
delivered at a time, this class is effectively a singleton. We don't worry
- about the QObject overhead because we never dynamically create and destroy
- objects of this type.
+ about the QObject overhead because the instances are long-lived: we don't
+ dynamically create and destroy objects of this type for each event.
*/
/*!
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index b798165861..624c131683 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -435,6 +435,7 @@ public:
int buttonCount() const { return m_buttonCount; }
QString name() const { return m_name; }
qint64 uniqueId() const { return m_uniqueId; }
+ QQuickPointerEvent *pointerEvent() const { return &m_event; }
private:
DeviceType m_deviceType;
@@ -444,6 +445,8 @@ private:
int m_buttonCount;
QString m_name;
qint64 m_uniqueId;
+ // the device-specific event instance which is reused during event delivery
+ mutable QQuickPointerEvent m_event;
Q_DISABLE_COPY(QQuickPointerDevice)
};
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index af72ff3af2..22086c577c 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -1892,7 +1892,7 @@ void QQuickWindowPrivate::deliverDelayedTouchEvent()
// Set delayedTouch to 0 before delivery to avoid redelivery in case of
// event loop recursions (e.g if it the touch starts a dnd session).
QScopedPointer<QTouchEvent> e(delayedTouch.take());
- deliverPointerEvent(currentPointerEvent.reset(e.data()));
+ deliverPointerEvent(pointerEventInstance(e.data()));
}
static bool qquickwindow_no_touch_compression = qEnvironmentVariableIsSet("QML_NO_TOUCH_COMPRESSION");
@@ -1971,14 +1971,14 @@ void QQuickWindowPrivate::handleTouchEvent(QTouchEvent *event)
qCDebug(DBG_TOUCH) << event;
if (qquickwindow_no_touch_compression || pointerEventRecursionGuard) {
- deliverPointerEvent(currentPointerEvent.reset(event));
+ deliverPointerEvent(pointerEventInstance(event));
return;
}
if (!compressTouchEvent(event)) {
if (delayedTouch)
deliverDelayedTouchEvent();
- deliverPointerEvent(currentPointerEvent.reset(event));
+ deliverPointerEvent(pointerEventInstance(event));
}
}
@@ -2019,7 +2019,7 @@ void QQuickWindowPrivate::handleMouseEvent(QMouseEvent *event)
case QEvent::MouseButtonPress:
Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMousePress, event->button(),
event->buttons());
- deliverPointerEvent(currentPointerEvent.reset(event));
+ deliverPointerEvent(pointerEventInstance(event));
break;
case QEvent::MouseButtonRelease:
Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseRelease, event->button(),
@@ -2029,14 +2029,14 @@ void QQuickWindowPrivate::handleMouseEvent(QMouseEvent *event)
return;
}
- deliverPointerEvent(currentPointerEvent.reset(event));
+ deliverPointerEvent(pointerEventInstance(event));
if (mouseGrabberItem && !event->buttons())
mouseGrabberItem->ungrabMouse();
break;
case QEvent::MouseButtonDblClick:
Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseDoubleClick,
event->button(), event->buttons());
- deliverPointerEvent(currentPointerEvent.reset(event));
+ deliverPointerEvent(pointerEventInstance(event));
break;
case QEvent::MouseMove:
Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseMove,
@@ -2063,7 +2063,7 @@ void QQuickWindowPrivate::handleMouseEvent(QMouseEvent *event)
event->setAccepted(accepted);
return;
}
- deliverPointerEvent(currentPointerEvent.reset(event));
+ deliverPointerEvent(pointerEventInstance(event));
break;
default:
Q_ASSERT(false);
@@ -2095,6 +2095,37 @@ void QQuickWindowPrivate::flushFrameSynchronousEvents()
}
}
+/*!
+ \internal
+ Returns a QQuickPointerEvent instance suitable for wrapping and delivering \a event.
+
+ There is a unique instance per QQuickPointerDevice, which is determined
+ from \a event's device.
+*/
+QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event)
+{
+ QQuickPointerDevice *dev = nullptr;
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ dev = genericMouseDevice;
+ break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ case QEvent::TouchCancel:
+ dev = touchDevice(static_cast<QTouchEvent *>(event)->device());
+ break;
+ // TODO tablet event types
+ default:
+ break;
+ }
+ Q_ASSERT(dev);
+ return dev->pointerEvent()->reset(event);
+}
+
void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
{
// If users spin the eventloop as a result of event delivery, we disable
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 7183d17514..ab704b9adf 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -163,6 +163,7 @@ public:
void deliverDelayedTouchEvent();
// delivery of pointer events:
+ QQuickPointerEvent *pointerEventInstance(QEvent *ev);
void deliverPointerEvent(QQuickPointerEvent *);
void deliverTouchEvent(QQuickPointerEvent *);
bool deliverTouchCancelEvent(QTouchEvent *);
@@ -245,9 +246,10 @@ public:
QQuickAnimatorController *animationController;
QScopedPointer<QTouchEvent> delayedTouch;
- // The current touch or mouse event that is delivered.
- // This event gets re-used (reset) for every incoming mouse/touch event.
- QQuickPointerEvent currentPointerEvent;
+ // An event instance for each device that we've seen so far.
+ // One of these gets re-used (reset) for every incoming mouse/touch/tablet event.
+ // One reason to keep them separate is so that m_touchPoints will be only those from a single device.
+ QVector<QQuickPointerEvent> pointerEventsByDevice;
int pointerEventRecursionGuard;
QQuickCustomRenderStage *customRenderStage;