aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickevents.cpp
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2017-02-16 11:26:23 +0100
committerJan Arve Sæther <jan-arve.saether@qt.io>2017-03-06 10:30:59 +0000
commit781f76176239bfbfe6041f2676e2f2804337d312 (patch)
tree0095045e326fd5d029cdbf380eb6791a78bf0c67 /src/quick/items/qquickevents.cpp
parent32c1212f81fcfc7b5e49f85d68b05cd94cd90521 (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.cpp22
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;