diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2020-09-30 19:36:09 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2020-11-17 08:24:44 +0100 |
commit | a2209698d3584a7c05d0c12aa61de050fe0e78fd (patch) | |
tree | 58fc82632a88af5988b5c20dd37b44ecc67abf40 /src/quick/items/qquickitem.cpp | |
parent | a8122590058e57a340a42eab0a34010a3a3c5271 (diff) |
Don't synthesize mouse from touch for items that accept touch
Followup to 1457df74f4c1d770e1e820de8cd082be1bd2489e : if an item that
has acceptTouchEvents() == true merely fails to accept one touch event,
that does not mean a mouse event should be sent.
Finish changing the default to false: handling touch events is opt-in,
just like handling mouse events; most items don't. And if you opt in,
then you MUST handle touch events, because you will NOT receive mouse
events as a fall-back.
Now that Flickable handles touch, filtering multi-touch events becomes
relevant. There was a failure in tst_touchmouse::mouseOnFlickableOnPinch
when Flickable grabs a stationary touchpoint at the same time as another
touchpoint is pressed, preventing a child PinchArea from reacting.
So there's a new rule: just as we start over with event delivery when a
new point is pressed, QQuickFlickable::filterPointerEvent() should also
not immediately grab when any point is newly pressed; it can afford to
wait, because it's filtering, so it will be able to see if one point is
dragged past the drag threshold later on.
When a parent (such as Flickable) contains only mouse-handling items
(such as MouseArea), the parent should filter the touch event if it is
able (if acceptTouchEvents() returns true). Flickable is now able to.
Filtering parents that are not able to filter touch events can still
filter a synth-mouse event as before. But filtering both must be
avoided: then we would have the problem that Flickable filters a touch
move, sees that it's being dragged past the drag threshold, and sets
d->stealMouse to true to indicate that it wants to steal the _next_
event; then it filters a synth-mouse move, and that's perceived as being
the next event even though it's just a different view of the same event,
so it steals it. In tst_qquickflickable::nestedMouseAreaUsingTouch we
rely on the delay caused by waiting for the next event: the MouseArea is
trying to drag an item and the Flickable wants to flick; both of them
decide on the same event that the drag threshold is exceeded. But
MouseArea calls setKeepMouseGrab() immediately, whereas Flickable
doesn't try to steal the grab until the next event, and then it sees the
keepMouseGrab flag has been set, so it doesn't do it. If Flickable
could filter the same event twice (once as touch, once as synth-mouse),
this logic doesn't work, so it's effectively "more grabby" than
intended. So it works better to have it filter only the actual touch
event, not the synth-mouse that comes after.
When the child has pointer handlers, we need to visit them, and
therefore we should let Flickable filter a touch event on the way.
tst_FlickableInterop::touchDragFlickableBehindButton() depends on this.
[ChangeLog][QtQuick][QQuickWindow] In Qt 6, a QQuickItem subclass must
explicitly call setAcceptTouchEvents(true) to receive QTouchEvents,
and then it must handle them: we no longer fall back to sending a
QMouseEvent if the touch event is not accepted. If it has additionally
called setFiltersChildMouseEvents(true), then it will filter touch
events, not any synthetic mouse events that may be needed for some
children.
Task-number: QTBUG-87018
Fixes: QTBUG-88169
Change-Id: I8784fe097198c99c754c4ebe205bef8fe490f6f4
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/quick/items/qquickitem.cpp')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 4 |
1 files changed, 0 insertions, 4 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index e71ae85c54..116d1a370b 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -3172,11 +3172,7 @@ QQuickItemPrivate::QQuickItemPrivate() , antialiasingValid(false) , isTabFence(false) , replayingPressEvent(false) -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - , touchEnabled(true) -#else , touchEnabled(false) -#endif , hasCursorHandler(false) , dirtyAttributes(0) , nextDirtyItem(nullptr) |