aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/handlers/qquickpointerhandler_p.h1
-rw-r--r--src/quick/items/qquickevents.cpp16
-rw-r--r--src/quick/items/qquickevents_p_p.h5
-rw-r--r--src/quick/items/qquickwindow.cpp15
4 files changed, 23 insertions, 14 deletions
diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h
index b5da8cba1f..24a058275d 100644
--- a/src/quick/handlers/qquickpointerhandler_p.h
+++ b/src/quick/handlers/qquickpointerhandler_p.h
@@ -115,6 +115,7 @@ private:
bool m_hadKeepTouchGrab : 1; // some handlers override target()->setKeepTouchGrab(); this remembers previous state
friend class QQuickEventPoint;
+ friend class QQuickWindowPrivate;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index a7ab0f01b0..bbea32f905 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -681,16 +681,26 @@ void QQuickEventPoint::setGrabberPointerHandler(QQuickPointerHandler *grabber, b
*/
void QQuickEventPoint::cancelExclusiveGrab()
{
- if (m_exclusiveGrabber.isNull()) {
+ if (m_exclusiveGrabber.isNull())
qWarning("cancelGrab: no grabber");
+ else
+ cancelExclusiveGrabImpl();
+}
+
+void QQuickEventPoint::cancelExclusiveGrabImpl(QTouchEvent *cancelEvent)
+{
+ if (m_exclusiveGrabber.isNull())
return;
- }
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
<< ": grab (exclusive)" << m_exclusiveGrabber << "-> nullptr";
}
- if (auto handler = grabberPointerHandler())
+ if (auto handler = grabberPointerHandler()) {
handler->onGrabChanged(handler, CancelGrabExclusive, this);
+ } else if (auto item = grabberItem()) {
+ if (cancelEvent)
+ QCoreApplication::sendEvent(item, cancelEvent);
+ }
m_exclusiveGrabber.clear();
}
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 455648a743..d046480f25 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -320,6 +320,9 @@ public:
void setPassiveGrabbers(const QVector<QPointer <QQuickPointerHandler> > &grabbers) { m_passiveGrabbers = grabbers; }
void clearPassiveGrabbers() { m_passiveGrabbers.clear(); }
+protected:
+ void cancelExclusiveGrabImpl(QTouchEvent *cancelEvent = nullptr);
+
private:
QVector2D estimatedVelocity() const;
@@ -339,6 +342,8 @@ private:
bool m_grabberIsHandler : 1;
int m_reserved : 29;
+ friend class QQuickWindowPrivate;
+
Q_DISABLE_COPY(QQuickEventPoint)
};
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 0cd9357b9a..3089e3c2fa 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -1927,23 +1927,16 @@ bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event)
Q_Q(QQuickWindow);
// A TouchCancel event will typically not contain any points.
- // Deliver it to all items that have active touches.
+ // Deliver it to all items and handlers that have active touches.
QQuickPointerEvent *pointerEvent = QQuickPointerDevice::touchDevice(event->device())->pointerEvent();
- QVector<QObject *> grabbers = pointerEvent->exclusiveGrabbers();
-
- for (QObject *grabber: qAsConst(grabbers)) {
- if (QQuickItem *grabberItem = qmlobject_cast<QQuickItem *>(grabber))
- QCoreApplication::sendEvent(grabberItem, event);
- else //if (QQuickPointerHandler *grabberHandler = qmlobject_cast<QQuickPointerHandler *>(grabber))
-// grabberHandler->handlePointerEvent()
- qWarning("unexpected: can't deliver touch cancel to a PointerHandler (yet?)");
- }
+ for (int i = 0; i < pointerEvent->pointCount(); ++i)
+ pointerEvent->point(i)->cancelExclusiveGrabImpl(event);
touchMouseId = -1;
touchMouseDevice = nullptr;
if (q->mouseGrabberItem())
q->mouseGrabberItem()->ungrabMouse();
- // The next touch event can only be a TouchBegin so clean up.
+ // The next touch event can only be a TouchBegin, so clean up.
pointerEvent->clearGrabbers();
return true;
}