diff options
-rw-r--r-- | src/quick/items/qquickevents_p_p.h | 25 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 52 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 4 | ||||
-rw-r--r-- | tests/auto/quick/touchmouse/tst_touchmouse.cpp | 6 |
4 files changed, 55 insertions, 32 deletions
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index cf6f83e5b1..3735d68a85 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -332,9 +332,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerEvent : public QObject Q_PROPERTY(Qt::MouseButtons buttons READ buttons) public: - QQuickPointerEvent(QObject *parent = nullptr) + QQuickPointerEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr) : QObject(parent) - , m_device(nullptr) + , m_device(device) , m_event(nullptr) , m_button(Qt::NoButton) , m_pressedButtons(Qt::NoButton) @@ -385,8 +385,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerMouseEvent : public QQuickPointerEvent { Q_OBJECT public: - QQuickPointerMouseEvent(QObject *parent = nullptr) - : QQuickPointerEvent(parent), m_mousePoint(new QQuickEventPoint(this)) { } + QQuickPointerMouseEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr) + : QQuickPointerEvent(parent, device), m_mousePoint(new QQuickEventPoint(this)) { } QQuickPointerEvent *reset(QEvent *) override; bool isPressEvent() const override; @@ -411,8 +411,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerTouchEvent : public QQuickPointerEvent { Q_OBJECT public: - QQuickPointerTouchEvent(QObject *parent = nullptr) - : QQuickPointerEvent(parent) + QQuickPointerTouchEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr) + : QQuickPointerEvent(parent, device) , m_pointCount(0) , m_synthMouseEvent(QEvent::MouseMove, QPointF(), Qt::NoButton, Qt::NoButton, Qt::NoModifier) { } @@ -500,18 +500,10 @@ public: 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) , m_maximumTouchPoints(maxPoints), m_buttonCount(buttonCount), m_name(name) - , m_uniqueId(QPointingDeviceUniqueId::fromNumericId(uniqueId)), m_event(nullptr) + , m_uniqueId(QPointingDeviceUniqueId::fromNumericId(uniqueId)) { - if (m_deviceType == Mouse) { - m_event = new QQuickPointerMouseEvent; - } else if (m_deviceType == TouchScreen || m_deviceType == TouchPad) { - m_event = new QQuickPointerTouchEvent; - } else { - Q_ASSERT(false); - } } - ~QQuickPointerDevice() { delete m_event; } DeviceType type() const { return m_deviceType; } PointerType pointerType() const { return m_pointerType; } Capabilities capabilities() const { return m_capabilities; } @@ -520,7 +512,6 @@ public: int buttonCount() const { return m_buttonCount; } QString name() const { return m_name; } QPointingDeviceUniqueId uniqueId() const { return m_uniqueId; } - QQuickPointerEvent *pointerEvent() const { return m_event; } static QQuickPointerDevice *touchDevice(QTouchDevice *d); static QList<QQuickPointerDevice *> touchDevices(); @@ -535,8 +526,6 @@ private: int m_buttonCount; QString m_name; QPointingDeviceUniqueId m_uniqueId; - // the device-specific event instance which is reused during event delivery - QQuickPointerEvent *m_event; Q_DISABLE_COPY(QQuickPointerDevice) }; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index bdb362e1ff..c441cfc357 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -752,12 +752,12 @@ void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber) if (grabber && touchMouseId != -1 && touchMouseDevice) { // update the touch item for mouse touch id to the new grabber qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << touchMouseId << "->" << q->mouseGrabberItem(); - auto point = touchMouseDevice->pointerEvent()->pointById(touchMouseId); + auto point = pointerEventInstance(touchMouseDevice)->pointById(touchMouseId); if (point) point->setGrabber(grabber); fromTouch = true; } else { - QQuickPointerEvent *event = QQuickPointerDevice::genericMouseDevice()->pointerEvent(); + QQuickPointerEvent *event = pointerEventInstance(QQuickPointerDevice::genericMouseDevice()); Q_ASSERT(event->pointCount() == 1); event->point(0)->setGrabber(grabber); } @@ -784,7 +784,7 @@ void QQuickWindowPrivate::grabTouchPoints(QQuickItem *grabber, const QVector<int continue; } if (id == touchMouseId) { - auto point = touchMouseDevice->pointerEvent()->pointById(id); + auto point = pointerEventInstance(touchMouseDevice)->pointById(id); auto touchMouseGrabber = point->grabber(); if (touchMouseGrabber) { point->setGrabber(nullptr); @@ -798,7 +798,7 @@ void QQuickWindowPrivate::grabTouchPoints(QQuickItem *grabber, const QVector<int const auto touchDevices = QQuickPointerDevice::touchDevices(); for (auto device : touchDevices) { - auto point = device->pointerEvent()->pointById(id); + auto point = pointerEventInstance(device)->pointById(id); if (!point) continue; QQuickItem *oldGrabber = point->grabber(); @@ -824,7 +824,7 @@ void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool to if (Q_LIKELY(touch)) { const auto touchDevices = QQuickPointerDevice::touchDevices(); for (auto device : touchDevices) { - auto pointerEvent = device->pointerEvent(); + auto pointerEvent = pointerEventInstance(device); for (int i = 0; i < pointerEvent->pointCount(); ++i) { if (pointerEvent->point(i)->grabber() == grabber) { pointerEvent->point(i)->setGrabber(nullptr); @@ -1493,13 +1493,13 @@ QQuickItem *QQuickWindow::mouseGrabberItem() const Q_D(const QQuickWindow); if (d->touchMouseId != -1 && d->touchMouseDevice) { - QQuickPointerEvent *event = d->touchMouseDevice->pointerEvent(); + QQuickPointerEvent *event = d->pointerEventInstance(d->touchMouseDevice); auto point = event->pointById(d->touchMouseId); Q_ASSERT(point); return point->grabber(); } - QQuickPointerEvent *event = QQuickPointerDevice::genericMouseDevice()->pointerEvent(); + QQuickPointerEvent *event = d->pointerEventInstance(QQuickPointerDevice::genericMouseDevice()); Q_ASSERT(event->pointCount()); return event->point(0)->grabber(); } @@ -1883,7 +1883,7 @@ bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event) // A TouchCancel event will typically not contain any points. // Deliver it to all items that have active touches. - QQuickPointerEvent *pointerEvent = QQuickPointerDevice::touchDevice(event->device())->pointerEvent(); + QQuickPointerEvent *pointerEvent = pointerEventInstance(QQuickPointerDevice::touchDevice(event->device())); QVector<QQuickItem *> grabbers = pointerEvent->grabbers(); for (QQuickItem *grabber: qAsConst(grabbers)) { @@ -2113,6 +2113,32 @@ void QQuickWindowPrivate::flushFrameSynchronousEvents() } } +QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevice *device) const +{ + // the list of devices should be very small so a linear search should be ok + for (QQuickPointerEvent *e: pointerEventInstances) { + if (e->device() == device) + return e; + } + + QQuickPointerEvent *ev = nullptr; + QQuickWindow *q = const_cast<QQuickWindow*>(q_func()); + switch (device->type()) { + case QQuickPointerDevice::Mouse: + ev = new QQuickPointerMouseEvent(q, device); + break; + case QQuickPointerDevice::TouchPad: + case QQuickPointerDevice::TouchScreen: + ev = new QQuickPointerTouchEvent(q, device); + break; + default: + // TODO tablet event types + break; + } + pointerEventInstances << ev; + return ev; +} + /*! \internal Returns a QQuickPointerEvent instance suitable for wrapping and delivering \a event. @@ -2123,25 +2149,29 @@ void QQuickWindowPrivate::flushFrameSynchronousEvents() QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event) const { QQuickPointerDevice *dev = nullptr; + QQuickPointerEvent *ev = nullptr; switch (event->type()) { case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: case QEvent::MouseMove: dev = QQuickPointerDevice::genericMouseDevice(); + ev = pointerEventInstance(dev); break; case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: case QEvent::TouchCancel: dev = QQuickPointerDevice::touchDevice(static_cast<QTouchEvent *>(event)->device()); + ev = pointerEventInstance(dev); break; // TODO tablet event types default: break; } - Q_ASSERT(dev); - return dev->pointerEvent()->reset(event); + + Q_ASSERT(ev); + return ev->reset(event); } void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event) @@ -2616,7 +2646,7 @@ bool QQuickWindowPrivate::sendFilteredTouchEvent(QQuickItem *target, QQuickItem if (touchMouseUnset) { // the point was grabbed as a pure touch point before, now it will be treated as mouse // but the old receiver still needs to be informed - if (auto oldGrabber = touchMouseDevice->pointerEvent()->pointById(tp.id())->grabber()) + if (auto oldGrabber = pointerEventInstance(touchMouseDevice)->pointById(tp.id())->grabber()) oldGrabber->touchUngrabEvent(); } touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index be915903c6..b3ff5a2b35 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -162,6 +162,10 @@ public: void flushFrameSynchronousEvents(); void deliverDelayedTouchEvent(); + // the device-specific event instances which are reused during event delivery + mutable QVector<QQuickPointerEvent *> pointerEventInstances; + QQuickPointerEvent *pointerEventInstance(QQuickPointerDevice *device) const; + // delivery of pointer events: QQuickPointerEvent *pointerEventInstance(QEvent *ev) const; void deliverPointerEvent(QQuickPointerEvent *); diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp index fbdeb1d836..c4a222e970 100644 --- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp +++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp @@ -571,7 +571,7 @@ void tst_TouchMouse::buttonOnFlickable() QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window.data()); QVERIFY(windowPriv->touchMouseId != -1); - auto pointerEvent = QQuickPointerDevice::touchDevices().at(0)->pointerEvent(); + auto pointerEvent = windowPriv->pointerEventInstance(QQuickPointerDevice::touchDevices().at(0)); QCOMPARE(pointerEvent->point(0)->grabber(), eventItem1); QCOMPARE(window->mouseGrabberItem(), eventItem1); @@ -632,7 +632,7 @@ void tst_TouchMouse::touchButtonOnFlickable() QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window.data()); QVERIFY(windowPriv->touchMouseId == -1); - auto pointerEvent = QQuickPointerDevice::touchDevices().at(0)->pointerEvent(); + auto pointerEvent = windowPriv->pointerEventInstance(QQuickPointerDevice::touchDevices().at(0)); QCOMPARE(pointerEvent->point(0)->grabber(), eventItem2); QCOMPARE(window->mouseGrabberItem(), nullptr); @@ -758,7 +758,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() // for the touchMouseId to the new grabber. QCOMPARE(window->mouseGrabberItem(), flickable); QVERIFY(windowPriv->touchMouseId != -1); - auto pointerEvent = QQuickPointerDevice::touchDevices().at(0)->pointerEvent(); + auto pointerEvent = windowPriv->pointerEventInstance(QQuickPointerDevice::touchDevices().at(0)); QCOMPARE(pointerEvent->point(0)->grabber(), flickable); QTest::touchEvent(window.data(), device).release(0, p3, window.data()); |