aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/util')
-rw-r--r--src/quick/util/qquickanimation.cpp8
-rw-r--r--src/quick/util/qquickdeliveryagent.cpp61
-rw-r--r--src/quick/util/qquickdeliveryagent_p_p.h5
-rw-r--r--src/quick/util/qquickpixmapcache.cpp17
4 files changed, 64 insertions, 27 deletions
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp
index 548ec8415a..7cbd3ea741 100644
--- a/src/quick/util/qquickanimation.cpp
+++ b/src/quick/util/qquickanimation.cpp
@@ -130,7 +130,8 @@ void QQuickAbstractAnimationPrivate::commence()
QQmlProperties properties;
auto *newInstance = q->transition(actions, properties, QQuickAbstractAnimation::Forward);
- Q_ASSERT(newInstance != animationInstance);
+ // transition can return a nullptr; that's the only allowed case were old and new have the same value
+ Q_ASSERT(newInstance != animationInstance || !newInstance);
delete animationInstance;
animationInstance = newInstance;
@@ -290,6 +291,11 @@ void QQuickAbstractAnimation::setRunning(bool r)
// Therefore, the state of d->running will in that case be different than r if we are back in
// the root stack frame of the recursive calls to setRunning()
emit runningChanged(d->running);
+ } else if (d->animationInstance) {
+ // If there was a recursive call, make sure the d->running is set correctly
+ d->running = d->animationInstance->isRunning();
+ } else {
+ d->running = r;
}
}
diff --git a/src/quick/util/qquickdeliveryagent.cpp b/src/quick/util/qquickdeliveryagent.cpp
index 2ae2bd1a02..6fc50aaa5c 100644
--- a/src/quick/util/qquickdeliveryagent.cpp
+++ b/src/quick/util/qquickdeliveryagent.cpp
@@ -70,32 +70,56 @@ void QQuickDeliveryAgentPrivate::touchToMouseEvent(QEvent::Type type, const QEve
qWarning() << "Unexpected: synthesized an indistinguishable mouse event" << mouseEvent;
}
-bool QQuickDeliveryAgentPrivate::checkIfDoubleTapped(ulong newPressEventTimestamp, QPoint newPressPos)
+/*!
+ Returns \c false if the time constraint for detecting a double-click is violated.
+*/
+bool QQuickDeliveryAgentPrivate::isWithinDoubleClickInterval(ulong timeInterval)
{
- bool doubleClicked = false;
+ return timeInterval < static_cast<ulong>(QGuiApplication::styleHints()->mouseDoubleClickInterval());
+}
- if (touchMousePressTimestamp > 0) {
- QPoint distanceBetweenPresses = newPressPos - touchMousePressPos;
- const int doubleTapDistance = QGuiApplication::styleHints()->touchDoubleTapDistance();
- doubleClicked = (qAbs(distanceBetweenPresses.x()) <= doubleTapDistance) && (qAbs(distanceBetweenPresses.y()) <= doubleTapDistance);
+/*!
+ Returns \c false if the spatial constraint for detecting a touchscreen double-tap is violated.
+*/
+bool QQuickDeliveryAgentPrivate::isWithinDoubleTapDistance(const QPoint &distanceBetweenPresses)
+{
+ auto square = [](qint64 v) { return v * v; };
+ return square(distanceBetweenPresses.x()) + square(distanceBetweenPresses.y()) <
+ square(QGuiApplication::styleHints()->touchDoubleTapDistance());
+}
- if (doubleClicked) {
- ulong timeBetweenPresses = newPressEventTimestamp - touchMousePressTimestamp;
- ulong doubleClickInterval = static_cast<ulong>(QGuiApplication::styleHints()->
- mouseDoubleClickInterval());
- doubleClicked = timeBetweenPresses < doubleClickInterval;
- }
- }
+bool QQuickDeliveryAgentPrivate::checkIfDoubleTapped(ulong newPressEventTimestamp, const QPoint &newPressPos)
+{
+ const bool doubleClicked = isDeliveringTouchAsMouse() &&
+ isWithinDoubleTapDistance(newPressPos - touchMousePressPos) &&
+ isWithinDoubleClickInterval(newPressEventTimestamp - touchMousePressTimestamp);
if (doubleClicked) {
touchMousePressTimestamp = 0;
} else {
touchMousePressTimestamp = newPressEventTimestamp;
touchMousePressPos = newPressPos;
}
-
return doubleClicked;
}
+void QQuickDeliveryAgentPrivate::resetIfDoubleTapPrevented(const QEventPoint &pressedPoint)
+{
+ if (touchMousePressTimestamp > 0 &&
+ (!isWithinDoubleTapDistance(pressedPoint.globalPosition().toPoint() - touchMousePressPos) ||
+ !isWithinDoubleClickInterval(pressedPoint.timestamp() - touchMousePressTimestamp))) {
+ touchMousePressTimestamp = 0;
+ touchMousePressPos = QPoint();
+ }
+}
+
+/*! \internal
+ \deprecated events are handled by methods in which the event is an argument
+
+ Accessor for use by legacy methods such as QQuickItem::grabMouse(),
+ QQuickItem::ungrabMouse(), and QQuickItem::grabTouchPoints() which
+ are not given sufficient context to do the grabbing.
+ We should remove eventsInDelivery in Qt 7.
+*/
QPointerEvent *QQuickDeliveryAgentPrivate::eventInDelivery() const
{
if (eventsInDelivery.isEmpty())
@@ -186,9 +210,7 @@ bool QQuickDeliveryAgentPrivate::deliverTouchAsMouse(QQuickItem *item, QTouchEve
} else if (touchMouseDevice == device && p.id() == touchMouseId) {
if (p.state() & QEventPoint::State::Updated) {
if (touchMousePressTimestamp != 0) {
- const int doubleTapDistance = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::TouchDoubleTapDistance).toInt();
- const QPoint moveDelta = p.globalPosition().toPoint() - touchMousePressPos;
- if (moveDelta.x() >= doubleTapDistance || moveDelta.y() >= doubleTapDistance)
+ if (!isWithinDoubleTapDistance(p.globalPosition().toPoint() - touchMousePressPos))
touchMousePressTimestamp = 0; // Got dragged too far, dismiss the double tap
}
if (QQuickItem *mouseGrabberItem = qmlobject_cast<QQuickItem *>(pointerEvent->exclusiveGrabber(p))) {
@@ -2124,6 +2146,11 @@ bool QQuickDeliveryAgentPrivate::deliverPressOrReleaseEvent(QPointerEvent *event
}
for (int i = 0; i < event->pointCount(); ++i) {
auto &point = event->point(i);
+ // Regardless whether a touchpoint could later result in a synth-mouse event:
+ // if the double-tap time or space constraint has been violated,
+ // reset state to prevent a double-click event.
+ if (isTouch && point.state() == QEventPoint::Pressed)
+ resetIfDoubleTapPrevented(point);
QVector<QQuickItem *> targetItemsForPoint = pointerTargets(rootItem, event, point, !isTouch, isTouch);
if (targetItems.size()) {
targetItems = mergePointerTargets(targetItems, targetItemsForPoint);
diff --git a/src/quick/util/qquickdeliveryagent_p_p.h b/src/quick/util/qquickdeliveryagent_p_p.h
index 7852ad4673..0fce213291 100644
--- a/src/quick/util/qquickdeliveryagent_p_p.h
+++ b/src/quick/util/qquickdeliveryagent_p_p.h
@@ -107,7 +107,8 @@ public:
bool isDeliveringTouchAsMouse() const { return touchMouseId != -1 && touchMouseDevice; }
void cancelTouchMouseSynthesis();
- bool checkIfDoubleTapped(ulong newPressEventTimestamp, QPoint newPressPos);
+ bool checkIfDoubleTapped(ulong newPressEventTimestamp, const QPoint &newPressPos);
+ void resetIfDoubleTapPrevented(const QEventPoint &pressedPoint);
QPointingDevicePrivate::EventPointData *mousePointData();
QPointerEvent *eventInDelivery() const;
@@ -146,6 +147,8 @@ public:
static bool isTabletEvent(const QPointerEvent *ev);
static bool isEventFromMouseOrTouchpad(const QPointerEvent *ev);
static bool isSynthMouse(const QPointerEvent *ev);
+ static bool isWithinDoubleClickInterval(ulong timeInterval);
+ static bool isWithinDoubleTapDistance(const QPoint &distanceBetweenPresses);
static QQuickPointingDeviceExtra *deviceExtra(const QInputDevice *device);
// delivery of pointer events:
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index f0d9959d87..0cf24bfba2 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -528,7 +528,6 @@ QQuickPixmapReader::~QQuickPixmapReader()
delete reply;
}
jobs.clear();
-#if QT_CONFIG(qml_network)
const auto cancelJob = [this](QQuickPixmapReply *reply) {
if (reply->loading) {
@@ -537,12 +536,13 @@ QQuickPixmapReader::~QQuickPixmapReader()
}
};
+#if QT_CONFIG(qml_network)
for (auto *reply : std::as_const(networkJobs))
cancelJob(reply);
+#endif
for (auto *reply : std::as_const(asyncResponses))
cancelJob(reply);
-#endif
if (threadObject())
threadObject()->processJobs();
mutex.unlock();
@@ -550,7 +550,6 @@ QQuickPixmapReader::~QQuickPixmapReader()
eventLoopQuitHack->deleteLater();
wait();
-#if QT_CONFIG(qml_network)
// While we've been waiting, the other thread may have added
// more replies. No one will care about them anymore.
@@ -559,16 +558,17 @@ QQuickPixmapReader::~QQuickPixmapReader()
reply->data->reply = nullptr;
delete reply;
};
-
+#if QT_CONFIG(qml_network)
for (QQuickPixmapReply *reply : std::as_const(networkJobs))
deleteReply(reply);
-
+#endif
for (QQuickPixmapReply *reply : std::as_const(asyncResponses))
deleteReply(reply);
+#if QT_CONFIG(qml_network)
networkJobs.clear();
- asyncResponses.clear();
#endif
+ asyncResponses.clear();
}
#if QT_CONFIG(qml_network)
@@ -729,7 +729,9 @@ void QQuickPixmapReader::processJobs()
// cancel any jobs already started
reply->close();
}
- } else {
+ } else
+#endif
+ {
QQuickImageResponse *asyncResponse = asyncResponses.key(job);
if (asyncResponse) {
asyncResponses.remove(asyncResponse);
@@ -737,7 +739,6 @@ void QQuickPixmapReader::processJobs()
}
}
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(job->url));
-#endif
// deleteLater, since not owned by this thread
job->deleteLater();
}