aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2016-07-14 11:17:54 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2016-07-15 13:26:56 +0000
commit288c1425d6e3ac200dd8e687f13de6ce4a41260b (patch)
tree78cba9a5ffd2416f0c2a703c8ec16e02b221275b /src/quick/items
parent6ce37a1eed9a41b036872bbbac2a5e73c6cbf9eb (diff)
QQuickWindow: keep a collection of devices which own event instances
That will allow the event instances to hold state, even between events. So now every QQuickWindow has its own set of them, per device. Hopefully that means we won't have any trouble delivering events in parallel in case each window has its own thread. Otherwise maybe it's slightly wasteful in multi-window apps. Change-Id: I766b580e1c177255905cc04b5de7d33ae503c6fd Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
Diffstat (limited to 'src/quick/items')
-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;