diff options
Diffstat (limited to 'src/quick/util')
| -rw-r--r-- | src/quick/util/qquickanimation.cpp | 8 | ||||
| -rw-r--r-- | src/quick/util/qquickdeliveryagent.cpp | 61 | ||||
| -rw-r--r-- | src/quick/util/qquickdeliveryagent_p_p.h | 5 | ||||
| -rw-r--r-- | src/quick/util/qquickpixmapcache.cpp | 17 |
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(); } |
