aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2022-06-15 10:52:20 +0300
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-06-23 05:20:57 +0000
commitc3aaa51a36063d4804ce0e9ca1d9bf4a358a4568 (patch)
treee7b48394a7636e57b3048bdded9520122a315e4a /src/quick
parent17b903ce6f0c01f9b46985394000cf4eaa06435d (diff)
Handle unprocessed pressed case in Flickable
Handle case where Flickable filters a pressed event before the receiver has decided whether it wants to keep the grab. That causes the Flickable to not process the press event, but still processes all the later events. This happens when the receiver is MouseArea so add special case for it in Flickable, where we start the drag if all conditions are met. Fixes: QTBUG-38765 Fixes: QTBUG-74842 Change-Id: I2e02042cb496e9eb3b7b5da824e56f76ee76ccbb Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> (cherry picked from commit d7b5a485583004ad6a1374a50b7c3f6cab00aca3) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/qquickflickable.cpp23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 2620d6afc0..96f974174f 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -43,6 +43,8 @@
#include "qquickwindow.h"
#include "qquickwindow_p.h"
#include "qquickevents_p_p.h"
+#include "qquickmousearea_p.h"
+#include "qquickdrag_p.h"
#include <QtQuick/private/qquickpointerhandler_p.h>
#include <QtQuick/private/qquicktransition_p.h>
@@ -2553,6 +2555,23 @@ bool QQuickFlickable::filterPointerEvent(QQuickItem *receiver, QPointerEvent *ev
bool receiverDisabled = receiver && !receiver->isEnabled();
bool stealThisEvent = d->stealMouse;
bool receiverKeepsGrab = receiver && (receiver->keepMouseGrab() || receiver->keepTouchGrab());
+ bool receiverRelinquishGrab = false;
+
+ // Special case for MouseArea, try to guess what it does with the event
+ if (auto *mouseArea = qmlobject_cast<QQuickMouseArea *>(receiver)) {
+ bool preventStealing = mouseArea->preventStealing();
+ if (mouseArea->drag() && mouseArea->drag()->target())
+ preventStealing = true;
+ if (!preventStealing && receiverKeepsGrab) {
+ receiverRelinquishGrab = !receiverDisabled
+ || (QQuickDeliveryAgentPrivate::isMouseEvent(event)
+ && firstPoint.state() == QEventPoint::State::Pressed
+ && (receiver->acceptedMouseButtons() & static_cast<QMouseEvent *>(event)->button()));
+ if (receiverRelinquishGrab)
+ receiverKeepsGrab = false;
+ }
+ }
+
if ((stealThisEvent || contains(localPos)) && (!receiver || !receiverKeepsGrab || receiverDisabled)) {
QScopedPointer<QPointerEvent> localizedEvent(QQuickDeliveryAgentPrivate::clonePointerEvent(event, localPos));
localizedEvent->setAccepted(false);
@@ -2563,7 +2582,7 @@ bool QQuickFlickable::filterPointerEvent(QQuickItem *receiver, QPointerEvent *ev
case QEventPoint::State::Pressed:
d->handlePressEvent(localizedEvent.data());
d->captureDelayedPress(receiver, event);
- stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above
+ stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by handlePressEvent
break;
case QEventPoint::State::Released:
d->handleReleaseEvent(localizedEvent.data());
@@ -2580,7 +2599,7 @@ bool QQuickFlickable::filterPointerEvent(QQuickItem *receiver, QPointerEvent *ev
event->setExclusiveGrabber(firstPoint, this);
}
- const bool filtered = stealThisEvent || d->delayedPressEvent || receiverDisabled;
+ const bool filtered = !receiverRelinquishGrab && (stealThisEvent || d->delayedPressEvent || receiverDisabled);
if (filtered) {
event->setAccepted(true);
}