Add grabber context pointers

In Qt Quick we now need to keep track of which QQDeliveryAgent is
responsible when a point is grabbed, either passively or exclusively.
When we re-deliver to that grabber, we need to do it via the same agent,
so that the same scene transform is used, and the grabber will see the
event in the correct coordinate system.  It's easier to track this
mapping here instead of in a separate map in Qt Quick.

Task-number: QTBUG-92944
Change-Id: I69f769c694d0da24885cdf4087e5032022bff629
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 40330b8f0a717098982d1f54f34a18a8262b1f55)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Shawn Rutledge 2021-04-19 16:00:35 +02:00 committed by Qt Cherry-pick Bot
parent 931e742a82
commit c69bee2073
5 changed files with 18 additions and 13 deletions

View File

@ -400,7 +400,7 @@ QList<QPointer<QObject> > QPointerEvent::passiveGrabbers(const QEventPoint &poin
qWarning() << "point is not in activePoints" << point;
return {};
}
return persistentPoint->passiveGrabbers;
return persistentPoint->passiveGrabbers.keys();
}
/*!

View File

@ -504,6 +504,8 @@ void QPointingDevicePrivate::setExclusiveGrabber(const QPointerEvent *event, con
QMutableEventPoint::from(persistentPoint->eventPoint).setGlobalGrabPosition(point.globalPosition());
if (exclusiveGrabber)
emit q->grabChanged(exclusiveGrabber, QPointingDevice::GrabExclusive, event, point);
else
persistentPoint->exclusiveGrabberContext.clear();
}
/*!
@ -536,7 +538,7 @@ bool QPointingDevicePrivate::addPassiveGrabber(const QPointerEvent *event, const
qCDebug(lcPointerGrab) << name << "point" << point.id() << point.state()
<< ": grab (passive)" << grabber;
}
persistentPoint->passiveGrabbers << grabber;
persistentPoint->passiveGrabbers.insert(grabber, {});
emit q->grabChanged(grabber, QPointingDevice::GrabPassive, event, point);
return true;
}
@ -549,14 +551,14 @@ bool QPointingDevicePrivate::removePassiveGrabber(const QPointerEvent *event, co
qWarning() << "point is not in activePoints" << point;
return false;
}
int i = persistentPoint->passiveGrabbers.indexOf(grabber);
if (i >= 0) {
auto pgit = persistentPoint->passiveGrabbers.find(grabber);
if (pgit != persistentPoint->passiveGrabbers.end()) {
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
qCDebug(lcPointerGrab) << name << "point" << point.id() << point.state()
<< ": removing passive grabber" << grabber;
}
emit q->grabChanged(grabber, QPointingDevice::UngrabPassive, event, point);
persistentPoint->passiveGrabbers.removeAt(i);
persistentPoint->passiveGrabbers.erase(pgit);
return true;
}
return false;
@ -574,9 +576,9 @@ void QPointingDevicePrivate::clearPassiveGrabbers(const QPointerEvent *event, co
return;
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
qCDebug(lcPointerGrab) << name << "point" << point.id() << point.state()
<< ": clearing" << persistentPoint->passiveGrabbers;
<< ": clearing" << persistentPoint->passiveGrabbers.keys();
}
for (auto g : persistentPoint->passiveGrabbers)
for (auto g : persistentPoint->passiveGrabbers.keys())
emit q->grabChanged(g, QPointingDevice::UngrabPassive, event, point);
persistentPoint->passiveGrabbers.clear();
}
@ -602,15 +604,16 @@ void QPointingDevicePrivate::removeGrabber(QObject *grabber, bool cancel)
<< "@" << epd.eventPoint.scenePosition()
<< ": grab" << grabber << "-> nullptr";
epd.exclusiveGrabber.clear();
epd.exclusiveGrabberContext.clear();
emit q->grabChanged(grabber,
cancel ? QPointingDevice::CancelGrabExclusive : QPointingDevice::UngrabExclusive,
nullptr, epd.eventPoint);
}
int pi = epd.passiveGrabbers.indexOf(grabber);
if (pi >= 0) {
auto pgit = epd.passiveGrabbers.find(grabber);
if (pgit != epd.passiveGrabbers.end()) {
qCDebug(lcPointerGrab) << name << "point" << epd.eventPoint.id() << epd.eventPoint.state()
<< ": removing passive grabber" << grabber;
epd.passiveGrabbers.removeAt(pi);
epd.passiveGrabbers.erase(pgit);
emit q->grabChanged(grabber,
cancel ? QPointingDevice::CancelGrabPassive : QPointingDevice::UngrabPassive,
nullptr, epd.eventPoint);

View File

@ -85,10 +85,12 @@ public:
/*! \internal
This struct (stored in activePoints) holds persistent state between event deliveries.
*/
using PassiveGrabbersMap = QFlatMap<QPointer<QObject>, QPointer<QObject>>;
struct EventPointData {
QEventPoint eventPoint;
QPointer<QObject> exclusiveGrabber;
QList<QPointer <QObject> > passiveGrabbers;
QPointer<QObject> exclusiveGrabberContext; // extra info about where the grab happened
PassiveGrabbersMap passiveGrabbers; // key: passive grabber; value: context (where the grab happened)
};
EventPointData *queryPointById(int id) const;
EventPointData *pointById(int id) const;

View File

@ -290,7 +290,7 @@ void tst_QMouseEvent::grabbers()
QCOMPARE(firstEPD->exclusiveGrabber, grabExclusive ? testMouseWidget : nullptr);
QCOMPARE(firstEPD->passiveGrabbers.count(), grabPassive ? 1 : 0);
if (grabPassive)
QCOMPARE(firstEPD->passiveGrabbers.first(), testMouseWidget);
QCOMPARE(firstEPD->passiveGrabbers.keys().first(), testMouseWidget);
// Ensure that grabbers are forgotten after release delivery
QTest::mouseRelease(testMouseWidget, Qt::LeftButton, Qt::KeyboardModifiers(), {10, 10});

View File

@ -1949,7 +1949,7 @@ void tst_QTouchEvent::grabbers()
QCOMPARE(devPriv->pointById(0)->exclusiveGrabber, grabExclusive ? &w : nullptr);
QCOMPARE(devPriv->pointById(0)->passiveGrabbers.count(), grabPassive ? 1 : 0);
if (grabPassive)
QCOMPARE(devPriv->pointById(0)->passiveGrabbers.first(), &w);
QCOMPARE(devPriv->pointById(0)->passiveGrabbers.keys().first(), &w);
// Ensure that eventpoints are forgotten after release delivery
points.first().state = QEventPoint::State::Released;