diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2017-02-16 11:26:23 +0100 |
---|---|---|
committer | Jan Arve Sæther <jan-arve.saether@qt.io> | 2017-03-06 10:30:59 +0000 |
commit | 781f76176239bfbfe6041f2676e2f2804337d312 (patch) | |
tree | 0095045e326fd5d029cdbf380eb6791a78bf0c67 /src/quick/items/qquickevents.cpp | |
parent | 32c1212f81fcfc7b5e49f85d68b05cd94cd90521 (diff) |
notify a PointerHandler when it loses grab due to Item::grabTouchPoints
and move more notification responsibility into QQuickEventPoint,
thus simplifying QQuickWindowPrivate::grabTouchPoints() which is the
implementation behind QQuickItem::grabTouchPoints.
It's important for QQuickEventPoint::setGrabberItem to
change local state first and then notify, to prevent recursive
notify/ungrab loops. MPTA for example does an ungrab
when it receives touchUngrabEvent, which then notifies again
if the first ungrab was not already fully completed.
Change-Id: I6f7b939c8cd76ac5f2d1ddda8b210fa3d31d619a
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 | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index bbea32f905..97183c55bc 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -609,13 +609,20 @@ void QQuickEventPoint::setGrabberItem(QQuickItem *grabber) qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this) << ": grab" << m_exclusiveGrabber << "->" << grabber; } - if (auto handler = grabberPointerHandler()) - handler->onGrabChanged(handler, CancelGrabExclusive, this); - for (QPointer<QQuickPointerHandler> passiveGrabber : m_passiveGrabbers) - passiveGrabber->onGrabChanged(passiveGrabber, OverrideGrabPassive, this); + QQuickPointerHandler *oldGrabberHandler = grabberPointerHandler(); + QQuickItem *oldGrabberItem = grabberItem(); m_exclusiveGrabber = QPointer<QObject>(grabber); m_grabberIsHandler = false; m_sceneGrabPos = m_scenePos; + if (oldGrabberHandler) + oldGrabberHandler->onGrabChanged(oldGrabberHandler, CancelGrabExclusive, this); + else if (oldGrabberItem && oldGrabberItem != grabber) { + auto pte = pointerEvent()->asPointerTouchEvent(); + if (pte && pte->asTouchEvent() && pte->asTouchEvent()->touchPointStates() == Qt::TouchPointReleased) + oldGrabberItem->touchUngrabEvent(); + } + for (QPointer<QQuickPointerHandler> passiveGrabber : m_passiveGrabbers) + passiveGrabber->onGrabChanged(passiveGrabber, OverrideGrabPassive, this); } } @@ -656,7 +663,14 @@ void QQuickEventPoint::setGrabberPointerHandler(QQuickPointerHandler *grabber, b } } else if (QQuickPointerHandler *oldGrabberPointerHandler = qmlobject_cast<QQuickPointerHandler *>(m_exclusiveGrabber.data())) { oldGrabberPointerHandler->onGrabChanged(oldGrabberPointerHandler, UngrabExclusive, this); + } else if (!m_exclusiveGrabber.isNull()) { + // If there is a previous grabber and it's not a PointerHandler, it must be an Item. + QQuickItem *oldGrabberItem = static_cast<QQuickItem *>(m_exclusiveGrabber.data()); + // If this point came from a touchscreen, notify that previous grabber Item that it's losing its touch grab. + if (pointerEvent()->asPointerTouchEvent()) + oldGrabberItem->touchUngrabEvent(); } + m_exclusiveGrabber = QPointer<QObject>(grabber); m_grabberIsHandler = true; m_sceneGrabPos = m_scenePos; |