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>
This commit is contained in:
parent
388b2c5b46
commit
e611c00d8c
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue