diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2017-03-02 11:56:10 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2017-03-06 14:23:40 +0000 |
commit | 8c659c6c723e4f5f97f46a4555a4765e85c26f1d (patch) | |
tree | 12aebd05d1419a4c3e71ddd511901e0e970d7fc7 /src/quick/items/qquickevents.cpp | |
parent | 2917d56ee6338c4a25c918383efc2356c229ff72 (diff) |
QQuickEventPoint::reset: don't cancel grabs
Because touchpoints can be released in a different order than they
were pressed, and even the QPA plugins don't guarantee that points
in a QTouchEvent will always stay in the same order while they are
still pressed, we cannot assume that the order of points will not
change every time a touch update occurs. And QQuickPointerTouchEvent
has a vector m_touchPoints in which the current points come first:
if the first point in that vector is released, it will be reset() to
represent a different touchpoint with a different ID. So it follows
that QQuickEventPoint::reset doesn't have enough information to
decide when a change of pointId means an implicit ungrab; and this
code was just a failsafe anyway (thus the qWarning).
QQuickPointerTouchEvent::reset() is responsible for identifying
which grabs need to be retained in which points from one event to
the next, and also currently warns if a point was pressed while
still being grabbed from previous interactions.
However, a mouse event only has one point, and we rely on
QQuickEventPoint to retain the grabbers. Efficiency-wise it
doesn't make sense to clear m_exclusiveGrabber and m_passiveGrabbers
and then re-populate them each time the mouse moves.
Since the risk of reordered points is only for touch events,
clearing the grabbers is now done in QQuickEventTouchPoint::reset().
One manifestation of this bug was in multibuttons.qml: sometimes
pressing a second button would cause the first button to be released.
It turned out to occur whenever the touchpoints got reordered.
Change-Id: Ia641f619d763e1a1ea7b59c1e1d08bce9d88e707
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src/quick/items/qquickevents.cpp')
-rw-r--r-- | src/quick/items/qquickevents.cpp | 10 |
1 files changed, 3 insertions, 7 deletions
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 97183c55bc..49ed0f050e 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -534,13 +534,7 @@ QQuickPointerDevice *QQuickPointerDevice::tabletDevice(qint64 id) void QQuickEventPoint::reset(Qt::TouchPointState state, const QPointF &scenePos, int pointId, ulong timestamp, const QVector2D &velocity) { m_scenePos = scenePos; - if (m_pointId != pointId) { - if (m_exclusiveGrabber) { - qWarning() << m_exclusiveGrabber << "failed to ungrab previous point" << m_pointId; - cancelExclusiveGrab(); - } - m_pointId = pointId; - } + m_pointId = pointId; m_accept = false; m_state = static_cast<QQuickEventPoint::State>(state); m_timestamp = timestamp; @@ -784,6 +778,8 @@ QQuickEventTouchPoint::QQuickEventTouchPoint(QQuickPointerTouchEvent *parent) void QQuickEventTouchPoint::reset(const QTouchEvent::TouchPoint &tp, ulong timestamp) { QQuickEventPoint::reset(tp.state(), tp.scenePos(), tp.id(), timestamp, tp.velocity()); + m_exclusiveGrabber.clear(); + m_passiveGrabbers.clear(); m_rotation = tp.rotation(); m_pressure = tp.pressure(); m_ellipseDiameters = tp.ellipseDiameters(); |