diff options
author | Shawn Rutledge <[email protected]> | 2021-04-19 15:44:45 +0200 |
---|---|---|
committer | Shawn Rutledge <[email protected]> | 2021-05-05 08:40:59 +0200 |
commit | 5c08e911375966761ee8e4d7cd425120985876e2 (patch) | |
tree | 912266b9875b7ddcdad3a1ffeb5162db830502ea /src/quick/util/qquickdeliveryagent_p.h | |
parent | ba0e42d645f6882db32fa557d2d8da6a497d502a (diff) |
Store memory of grabbing agents in EventPointData
QQuickDeliveryAgentPrivate::grabberAgent(event, point) was too naive:
it's not only that each point could be delivered by a different agent,
but also each point could have an exclusive grab in the context of one
agent and multiple passive grabs in the contexts of different agents.
E.g. in qtquick3d/examples/quick3d/dynamictexture, many grabs can occur
if you press on a door: the View3D has a TapHandler to pick the door, so
that you can click to open; each Panel has a TapHandler to defocus
whichever TextArea has focus; there is a ListView for dragging through
the panel delegates sideways; if you press on a yellow note, its
DragHandler prepares to start dragging; etc. So at least, a TapHandler
in the subscene and the other one in the View3D need to get passive
grabs, and need to receive the release event in the correct coordinate
system, to detect taps. When we apply the sceneTransform of a
particular agent before re-delivering an update or a release, based on
the grab, it has to be in the correct coordinate system for that grabber.
So on grab, we use EventPointData::exclusiveGrabberContext or
passiveGrabbersContext to store the pointer to the QQDeliveryAgent that
was doing the delivery when the grab occurred. When we deliver the next
event to a grabber, we also look up the correct DA to do the delivery.
This gets done twice: once in QQuickWindow::event() to find the DAs that
need to handle the event, and in QQDeliveryAgentPriv::deliverUpdatedPoints()
to ignore passive grabbers for which a different DA is responsible.
The failsafe "never allow any kind of grab to persist after release" is
moved to QQuickWindow::event because we don't want to do it prematurely
in a subscene agent, and ATM we don't require the main DA to deliver
last: it depends on the order in EventPointData::passiveGrabbersContext.
QQuickPointerHandler::onGrabChanged() should only be called from the
relevant DA, to avoid overreaction: that is, the DA that is delivering
an event at the time the grab occurs. QQDelAgentPrivate::onGrabChanged()
gets called on all DA instances, but only one of them is supposed to
store itself as the assigned DA for handling a particular point ID.
It's not always the same as QQuickItemPrivate::deliveryAgent(): that
goes astray when the same 2D subscene is mapped to the main scene and
also onto multiple QQ3D models. In that case, if the user interacts
directly with the 2D scene, the main DA should be assigned; or if the
user interacts with one of the mapped subscenes, its DA should be assigned.
We have to stop delivering to subscenes when the event is accepted,
at least, because of the usual convention that delivery is done when
the event remains accepted rather than being purposely ignored. So in
the dynamictexture example, if you click on a TextEdit on one of the
doors, it receives the event first (because it's on top) and accepts it;
that stops delivery in QQuickDeliveryAgentPrivate::deliverPressOrReleaseEvent(),
and now also stops QQuickWindow::event() from visiting the next
subscene, or the main scene, so that the TapHandler in the View3D
doesn't get clicked, and the doors don't open.
Task-number: QTBUG-92944
Pick-to: 6.1
Change-Id: I1b4520b665e58874d17a936024cf62e4c7175d8e
Reviewed-by: Qt CI Bot <[email protected]>
Reviewed-by: Andy Nichols <[email protected]>
Diffstat (limited to 'src/quick/util/qquickdeliveryagent_p.h')
-rw-r--r-- | src/quick/util/qquickdeliveryagent_p.h | 2 |
1 files changed, 0 insertions, 2 deletions
diff --git a/src/quick/util/qquickdeliveryagent_p.h b/src/quick/util/qquickdeliveryagent_p.h index 41b3a5390b..9b73d9b9b9 100644 --- a/src/quick/util/qquickdeliveryagent_p.h +++ b/src/quick/util/qquickdeliveryagent_p.h @@ -79,8 +79,6 @@ public: explicit QQuickDeliveryAgent(QQuickItem *rootItem); virtual ~QQuickDeliveryAgent(); - static QQuickDeliveryAgent *grabberAgent(QPointerEvent *pe, const QEventPoint &pt); - QQuickItem *rootItem() const; void setSceneTransform(Transform *transform); |