From 8c659c6c723e4f5f97f46a4555a4765e85c26f1d Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 2 Mar 2017 11:56:10 +0100 Subject: QQuickEventPoint::reset: don't cancel grabs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/quick/items/qquickevents.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src/quick/items/qquickevents.cpp') 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(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(); -- cgit v1.2.3