aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickwindow.cpp51
-rw-r--r--src/quick/items/qquickwindow_p.h1
2 files changed, 30 insertions, 22 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 4f14eedd39..83a1268d1d 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -655,6 +655,13 @@ bool QQuickWindowPrivate::checkIfDoubleClicked(ulong newPressEventTimestamp)
return doubleClicked;
}
+void QQuickWindowPrivate::cancelTouchMouseSynthesis()
+{
+ qCDebug(DBG_TOUCH_TARGET);
+ touchMouseId = -1;
+ touchMouseDevice = nullptr;
+}
+
bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEvent *pointerEvent)
{
Q_ASSERT(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents));
@@ -704,10 +711,8 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
QScopedPointer<QMouseEvent> mouseDoubleClick(touchToMouseEvent(QEvent::MouseButtonDblClick, p, event.data(), item, false));
QCoreApplication::sendEvent(item, mouseDoubleClick.data());
event->setAccepted(mouseDoubleClick->isAccepted());
- if (!mouseDoubleClick->isAccepted()) {
- touchMouseId = -1;
- touchMouseDevice = nullptr;
- }
+ if (!mouseDoubleClick->isAccepted())
+ cancelTouchMouseSynthesis();
}
return true;
@@ -761,8 +766,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
if (q->mouseGrabberItem()) // might have ungrabbed due to event
q->mouseGrabberItem()->ungrabMouse();
- touchMouseId = -1;
- touchMouseDevice = nullptr;
+ cancelTouchMouseSynthesis();
return me->isAccepted();
}
}
@@ -788,8 +792,7 @@ void QQuickWindowPrivate::grabTouchPoints(QObject *grabber, const QVector<int> &
point->setExclusiveGrabber(nullptr);
touchMouseGrabber->mouseUngrabEvent();
touchMouseGrabber->touchUngrabEvent();
- touchMouseDevice = nullptr;
- touchMouseId = -1;
+ cancelTouchMouseSynthesis();
}
qCDebug(DBG_MOUSE_TARGET) << "grabTouchPoints: mouse grabber changed due to grabTouchPoints:" << touchMouseGrabber << "-> null";
}
@@ -2014,8 +2017,7 @@ bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event)
if (q->mouseGrabberItem())
q->mouseGrabberItem()->ungrabMouse();
- touchMouseId = -1;
- touchMouseDevice = nullptr;
+ cancelTouchMouseSynthesis();
// A TouchCancel event will typically not contain any points.
// Deliver it to all items and handlers that have active touches.
@@ -2443,10 +2445,8 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event)
int id = point->pointId();
qCDebug(DBG_TOUCH_TARGET) << "TP" << hex << id << "released";
point->setGrabberItem(nullptr);
- if (id == touchMouseId) {
- touchMouseId = -1;
- touchMouseDevice = nullptr;
- }
+ if (id == touchMouseId)
+ cancelTouchMouseSynthesis();
} else {
allReleased = false;
}
@@ -2526,11 +2526,18 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event,
int pointCount = event->pointCount();
QVector<QQuickItem *> targetItems;
bool isTouchEvent = (event->asPointerTouchEvent() != nullptr);
- if (isTouchEvent && event->isPressEvent()) {
- // When a second point is pressed, we're starting over with delivery, so
- // don't let prior conception of which one is acting as a mouse interfere
- touchMouseId = -1;
- touchMouseDevice = nullptr;
+ if (isTouchEvent && event->isPressEvent() && isDeliveringTouchAsMouse() &&
+ pointerEventInstance(touchMouseDevice)->pointById(touchMouseId)->grabberPointerHandler()) {
+ // When a second point is pressed, if the first point's existing
+ // grabber was a pointer handler while a filtering parent is filtering
+ // the same first point _as mouse_: we're starting over with delivery,
+ // so we need to allow the second point to now be sent as a synth-mouse
+ // instead of the first one, so that filtering parents (maybe even the
+ // same one) can get a chance to see the second touchpoint as a
+ // synth-mouse and perhaps grab it. Ideally we would always do this
+ // when a new touchpoint is pressed, but this compromise fixes
+ // QTBUG-70998 and avoids breaking tst_FlickableInterop::touchDragSliderAndFlickable
+ cancelTouchMouseSynthesis();
}
for (int i = 0; i < pointCount; ++i) {
auto point = event->point(i);
@@ -2945,12 +2952,13 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
// touchMouseId and touchMouseDevice must be set, even if it's only temporarily and isn't grabbed.
touchMouseId = tp.id();
touchMouseDevice = event->device();
+ QQuickPointerDevice *dev = touchMouseDevice;
if (filteringParent->childMouseEventFilter(receiver, mouseEvent.data())) {
qCDebug(DBG_TOUCH) << "touch event intercepted as synth mouse event by childMouseEventFilter of " << filteringParent;
skipDelivery.append(filteringParent);
if (t != QEvent::MouseButtonRelease) {
qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << tp.id() << "->" << filteringParent;
- pointerEventInstance(touchMouseDevice)->pointById(tp.id())->setGrabberItem(filteringParent);
+ pointerEventInstance(dev)->pointById(tp.id())->setGrabberItem(filteringParent);
touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set
if (mouseEvent->isAccepted())
filteringParent->grabMouse();
@@ -2960,8 +2968,7 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
if (touchMouseUnset) {
// Now that we're done sending a synth mouse event, and it wasn't grabbed,
// the touchpoint is no longer acting as a synthetic mouse. Restore previous state.
- touchMouseId = -1;
- touchMouseDevice = nullptr;
+ cancelTouchMouseSynthesis();
}
// Only one touchpoint can be treated as a synthetic mouse, so after childMouseEventFilter
// has been called once, we're done with this loop over the touchpoints.
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 10c8477417..5a3807b24f 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -137,6 +137,7 @@ public:
QQuickPointerDevice *touchMouseDevice;
bool checkIfDoubleClicked(ulong newPressEventTimestamp);
ulong touchMousePressTimestamp;
+ void cancelTouchMouseSynthesis();
// Mouse positions are saved in widget coordinates
QPointF lastMousePosition;