From fb6baf03faf1ffdda5917b9daa9e9ed0f821fa8a Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 4 Aug 2020 12:53:00 +0200 Subject: AbstractButton: emit doubleClicked() for touch events [ChangeLog][Controls][AbstractButton] doubleClicked() is now also emitted for touch events. Fixes: QTBUG-82146 Change-Id: Ie1e24d291bd4b592edd91fc762da8636e08698df Reviewed-by: Volker Hilsheimer --- src/quicktemplates2/qquickabstractbutton.cpp | 46 +++++++++++++++++++------ src/quicktemplates2/qquickabstractbutton_p_p.h | 9 ++--- src/quicktemplates2/qquickcombobox.cpp | 18 +++++----- src/quicktemplates2/qquickcontrol.cpp | 18 +++++----- src/quicktemplates2/qquickcontrol_p_p.h | 6 ++-- src/quicktemplates2/qquickdial.cpp | 22 ++++++------ src/quicktemplates2/qquickpageindicator.cpp | 18 +++++----- src/quicktemplates2/qquickrangeslider.cpp | 26 +++++++------- src/quicktemplates2/qquickscrollbar.cpp | 16 +++++---- src/quicktemplates2/qquickscrollbar_p_p.h | 6 ++-- src/quicktemplates2/qquickslider.cpp | 26 +++++++------- src/quicktemplates2/qquickspinbox.cpp | 18 +++++----- src/quicktemplates2/qquicksplitview.cpp | 12 +++---- src/quicktemplates2/qquicksplitview_p_p.h | 6 ++-- src/quicktemplates2/qquickswitch.cpp | 12 +++---- src/quicktemplates2/qquickswitchdelegate.cpp | 12 +++---- tests/auto/controls/data/tst_abstractbutton.qml | 29 ++++++++++++++++ tests/auto/controls/data/tst_checkbox.qml | 3 ++ tests/auto/controls/data/tst_delaybutton.qml | 4 +++ tests/auto/controls/data/tst_radiobutton.qml | 3 ++ tests/auto/controls/data/tst_switch.qml | 8 +++++ tests/auto/controls/data/tst_switchdelegate.qml | 8 +++++ 22 files changed, 205 insertions(+), 121 deletions(-) diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index d589e613..61b358e0 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -134,10 +134,10 @@ void QQuickAbstractButtonPrivate::setMovePoint(const QPointF &point) emit q->pressYChanged(); } -void QQuickAbstractButtonPrivate::handlePress(const QPointF &point) +void QQuickAbstractButtonPrivate::handlePress(const QPointF &point, ulong timestamp) { Q_Q(QQuickAbstractButton); - QQuickControlPrivate::handlePress(point); + QQuickControlPrivate::handlePress(point, timestamp); setPressPoint(point); q->setPressed(true); @@ -151,10 +151,10 @@ void QQuickAbstractButtonPrivate::handlePress(const QPointF &point) stopPressAndHold(); } -void QQuickAbstractButtonPrivate::handleMove(const QPointF &point) +void QQuickAbstractButtonPrivate::handleMove(const QPointF &point, ulong timestamp) { Q_Q(QQuickAbstractButton); - QQuickControlPrivate::handleMove(point); + QQuickControlPrivate::handleMove(point, timestamp); setMovePoint(point); q->setPressed(keepPressed || q->contains(point)); @@ -164,22 +164,28 @@ void QQuickAbstractButtonPrivate::handleMove(const QPointF &point) stopPressAndHold(); } -void QQuickAbstractButtonPrivate::handleRelease(const QPointF &point) +void QQuickAbstractButtonPrivate::handleRelease(const QPointF &point, ulong timestamp) { Q_Q(QQuickAbstractButton); - QQuickControlPrivate::handleRelease(point); + // Store this here since the base class' handleRelease clears it. + const int pressTouchId = touchId; + + QQuickControlPrivate::handleRelease(point, timestamp); bool wasPressed = pressed; setPressPoint(point); q->setPressed(false); pressButtons = Qt::NoButton; + const bool touchDoubleClick = pressTouchId != -1 && lastTouchReleaseTimestamp != 0 + && timestamp - lastTouchReleaseTimestamp < qApp->styleHints()->mouseDoubleClickInterval(); + if (!wasHeld && (keepPressed || q->contains(point))) q->nextCheckState(); if (wasPressed) { emit q->released(); if (!wasHeld && !wasDoubleClick) - trigger(); + trigger(touchDoubleClick); } else { emit q->canceled(); } @@ -189,6 +195,21 @@ void QQuickAbstractButtonPrivate::handleRelease(const QPointF &point) else stopPressAndHold(); + if (!touchDoubleClick) { + // This is not a double click yet, but it is potentially the + // first release before a double click. + if (pressTouchId != -1) { + // The corresponding press for this release was a touch press. + // Keep track of the timestamp of the release so that we can + // emit doubleClicked() if another one comes afterwards. + lastTouchReleaseTimestamp = timestamp; + } + } else { + // We just did a double click, so clear the release timestamp + // to prepare for any possible future double clicks. + lastTouchReleaseTimestamp = 0; + } + wasDoubleClick = false; } @@ -204,6 +225,7 @@ void QQuickAbstractButtonPrivate::handleUngrab() stopPressRepeat(); stopPressAndHold(); wasDoubleClick = false; + lastTouchReleaseTimestamp = 0; emit q->canceled(); } @@ -332,14 +354,18 @@ void QQuickAbstractButtonPrivate::click() emit q->clicked(); } -void QQuickAbstractButtonPrivate::trigger() +void QQuickAbstractButtonPrivate::trigger(bool doubleClick) { Q_Q(QQuickAbstractButton); const bool wasEnabled = effectiveEnable; if (action && action->isEnabled()) QQuickActionPrivate::get(action)->trigger(q, false); - if (wasEnabled && (!action || !action->isEnabled())) - emit q->clicked(); + if (wasEnabled && (!action || !action->isEnabled())) { + if (!doubleClick) + emit q->clicked(); + else + emit q->doubleClicked(); + } } void QQuickAbstractButtonPrivate::toggle(bool value) diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h index 9291c1a8..744d9e66 100644 --- a/src/quicktemplates2/qquickabstractbutton_p_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p_p.h @@ -72,9 +72,9 @@ public: void setPressPoint(const QPointF &point); void setMovePoint(const QPointF &point); - void handlePress(const QPointF &point) override; - void handleMove(const QPointF &point) override; - void handleRelease(const QPointF &point) override; + void handlePress(const QPointF &point, ulong timestamp) override; + void handleMove(const QPointF &point, ulong timestamp) override; + void handleRelease(const QPointF &point, ulong timestamp) override; void handleUngrab() override; virtual bool acceptKeyClick(Qt::Key key) const; @@ -101,7 +101,7 @@ public: void updateEffectiveIcon(); void click(); - void trigger(); + void trigger(bool doubleClick = false); void toggle(bool value); void cancelIndicator(); @@ -134,6 +134,7 @@ public: int shortcutId = 0; QKeySequence shortcut; #endif + qreal lastTouchReleaseTimestamp = 0; QString text; QQuickIcon icon; QQuickIcon effectiveIcon; diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index b5a68ecd..71fb33c8 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -255,9 +255,9 @@ public: void createDelegateModel(); - void handlePress(const QPointF &point) override; - void handleMove(const QPointF &point) override; - void handleRelease(const QPointF &point) override; + void handlePress(const QPointF &point, ulong timestamp) override; + void handleMove(const QPointF &point, ulong timestamp) override; + void handleRelease(const QPointF &point, ulong timestamp) override; void handleUngrab() override; void cancelIndicator(); @@ -714,24 +714,24 @@ void QQuickComboBoxPrivate::createDelegateModel() delete oldModel; } -void QQuickComboBoxPrivate::handlePress(const QPointF &point) +void QQuickComboBoxPrivate::handlePress(const QPointF &point, ulong timestamp) { Q_Q(QQuickComboBox); - QQuickControlPrivate::handlePress(point); + QQuickControlPrivate::handlePress(point, timestamp); q->setPressed(true); } -void QQuickComboBoxPrivate::handleMove(const QPointF &point) +void QQuickComboBoxPrivate::handleMove(const QPointF &point, ulong timestamp) { Q_Q(QQuickComboBox); - QQuickControlPrivate::handleMove(point); + QQuickControlPrivate::handleMove(point, timestamp); q->setPressed(q->contains(point)); } -void QQuickComboBoxPrivate::handleRelease(const QPointF &point) +void QQuickComboBoxPrivate::handleRelease(const QPointF &point, ulong timestamp) { Q_Q(QQuickComboBox); - QQuickControlPrivate::handleRelease(point); + QQuickControlPrivate::handleRelease(point, timestamp); if (pressed) { q->setPressed(false); togglePopup(false); diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 89f6abd4..56e7e935 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -197,14 +197,14 @@ static void setActiveFocus(QQuickControl *control, Qt::FocusReason reason) control->forceActiveFocus(reason); } -void QQuickControlPrivate::handlePress(const QPointF &) +void QQuickControlPrivate::handlePress(const QPointF &, ulong) { Q_Q(QQuickControl); if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && !QGuiApplication::styleHints()->setFocusOnTouchRelease()) setActiveFocus(q, Qt::MouseFocusReason); } -void QQuickControlPrivate::handleMove(const QPointF &point) +void QQuickControlPrivate::handleMove(const QPointF &point, ulong) { #if QT_CONFIG(quicktemplates2_hover) Q_Q(QQuickControl); @@ -214,7 +214,7 @@ void QQuickControlPrivate::handleMove(const QPointF &point) #endif } -void QQuickControlPrivate::handleRelease(const QPointF &) +void QQuickControlPrivate::handleRelease(const QPointF &, ulong) { Q_Q(QQuickControl); if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease()) @@ -1960,7 +1960,7 @@ void QQuickControl::hoverLeaveEvent(QHoverEvent *event) void QQuickControl::mousePressEvent(QMouseEvent *event) { Q_D(QQuickControl); - d->handlePress(event->position()); + d->handlePress(event->position(), event->timestamp()); if (event->source() == Qt::MouseEventSynthesizedByQt) { d->pressWasTouch = true; d->previousPressPos = event->position(); @@ -1971,14 +1971,14 @@ void QQuickControl::mousePressEvent(QMouseEvent *event) void QQuickControl::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickControl); - d->handleMove(event->position()); + d->handleMove(event->position(), event->timestamp()); event->accept(); } void QQuickControl::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickControl); - d->handleRelease(event->position()); + d->handleRelease(event->position(), event->timestamp()); event->accept(); } @@ -2002,13 +2002,13 @@ void QQuickControl::touchEvent(QTouchEvent *event) switch (point.state()) { case QEventPoint::Pressed: - d->handlePress(point.position()); + d->handlePress(point.position(), event->timestamp()); break; case QEventPoint::Updated: - d->handleMove(point.position()); + d->handleMove(point.position(), event->timestamp()); break; case QEventPoint::Released: - d->handleRelease(point.position()); + d->handleRelease(point.position(), event->timestamp()); break; default: break; diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h index cb2eb419..4b8fb3e0 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -89,9 +89,9 @@ public: #if QT_CONFIG(quicktemplates2_multitouch) virtual bool acceptTouch(const QTouchEvent::TouchPoint &point); #endif - virtual void handlePress(const QPointF &point); - virtual void handleMove(const QPointF &point); - virtual void handleRelease(const QPointF &point); + virtual void handlePress(const QPointF &point, ulong timestamp); + virtual void handleMove(const QPointF &point, ulong timestamp); + virtual void handleRelease(const QPointF &point, ulong timestamp); virtual void handleUngrab(); void mirrorChange() override; diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp index bd9c864d..24783c9a 100644 --- a/src/quicktemplates2/qquickdial.cpp +++ b/src/quicktemplates2/qquickdial.cpp @@ -110,9 +110,9 @@ public: bool isLargeChange(const QPointF &eventPos, qreal proposedPosition) const; bool isHorizontalOrVertical() const; - void handlePress(const QPointF &point) override; - void handleMove(const QPointF &point) override; - void handleRelease(const QPointF &point) override; + void handlePress(const QPointF &point, ulong timestamp) override; + void handleMove(const QPointF &point, ulong timestamp) override; + void handleRelease(const QPointF &point, ulong timestamp) override; void handleUngrab() override; void cancelHandle(); @@ -241,19 +241,19 @@ bool QQuickDialPrivate::isHorizontalOrVertical() const return inputMode == QQuickDial::Horizontal || inputMode == QQuickDial::Vertical; } -void QQuickDialPrivate::handlePress(const QPointF &point) +void QQuickDialPrivate::handlePress(const QPointF &point, ulong timestamp) { Q_Q(QQuickDial); - QQuickControlPrivate::handlePress(point); + QQuickControlPrivate::handlePress(point, timestamp); pressPoint = point; positionBeforePress = position; q->setPressed(true); } -void QQuickDialPrivate::handleMove(const QPointF &point) +void QQuickDialPrivate::handleMove(const QPointF &point, ulong timestamp) { Q_Q(QQuickDial); - QQuickControlPrivate::handleMove(point); + QQuickControlPrivate::handleMove(point, timestamp); const qreal oldPos = position; qreal pos = positionAt(point); if (snapMode == QQuickDial::SnapAlways) @@ -269,10 +269,10 @@ void QQuickDialPrivate::handleMove(const QPointF &point) } } -void QQuickDialPrivate::handleRelease(const QPointF &point) +void QQuickDialPrivate::handleRelease(const QPointF &point, ulong timestamp) { Q_Q(QQuickDial); - QQuickControlPrivate::handleRelease(point); + QQuickControlPrivate::handleRelease(point, timestamp); if (q->keepMouseGrab() || q->keepTouchGrab()) { const qreal oldPos = position; qreal pos = positionAt(point); @@ -766,7 +766,7 @@ void QQuickDial::mousePressEvent(QMouseEvent *event) { Q_D(QQuickDial); QQuickControl::mousePressEvent(event); - d->handleMove(event->position()); + d->handleMove(event->position(), event->timestamp()); setKeepMouseGrab(true); } @@ -792,7 +792,7 @@ void QQuickDial::touchEvent(QTouchEvent *event) } } if (keepTouchGrab()) - d->handleMove(point.position()); + d->handleMove(point.position(), event->timestamp()); break; default: diff --git a/src/quicktemplates2/qquickpageindicator.cpp b/src/quicktemplates2/qquickpageindicator.cpp index 4a2b7f14..41caa234 100644 --- a/src/quicktemplates2/qquickpageindicator.cpp +++ b/src/quicktemplates2/qquickpageindicator.cpp @@ -88,9 +88,9 @@ class QQuickPageIndicatorPrivate : public QQuickControlPrivate Q_DECLARE_PUBLIC(QQuickPageIndicator) public: - void handlePress(const QPointF &point) override; - void handleMove(const QPointF &point) override; - void handleRelease(const QPointF &point) override; + void handlePress(const QPointF &point, ulong timestamp) override; + void handleMove(const QPointF &point, ulong timestamp) override; + void handleRelease(const QPointF &point, ulong timestamp) override; void handleUngrab() override; QQuickItem *itemAt(const QPointF &pos) const; @@ -106,24 +106,24 @@ public: QQuickItem *pressedItem = nullptr; }; -void QQuickPageIndicatorPrivate::handlePress(const QPointF &point) +void QQuickPageIndicatorPrivate::handlePress(const QPointF &point, ulong timestamp) { - QQuickControlPrivate::handlePress(point); + QQuickControlPrivate::handlePress(point, timestamp); if (interactive) updatePressed(true, point); } -void QQuickPageIndicatorPrivate::handleMove(const QPointF &point) +void QQuickPageIndicatorPrivate::handleMove(const QPointF &point, ulong timestamp) { - QQuickControlPrivate::handleMove(point); + QQuickControlPrivate::handleMove(point, timestamp); if (interactive) updatePressed(true, point); } -void QQuickPageIndicatorPrivate::handleRelease(const QPointF &point) +void QQuickPageIndicatorPrivate::handleRelease(const QPointF &point, ulong timestamp) { Q_Q(QQuickPageIndicator); - QQuickControlPrivate::handleRelease(point); + QQuickControlPrivate::handleRelease(point, timestamp); if (interactive) { if (pressedItem && contentItem) q->setCurrentIndex(contentItem->childItems().indexOf(pressedItem)); diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index 0455ab21..2348e642 100644 --- a/src/quicktemplates2/qquickrangeslider.cpp +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -380,9 +380,9 @@ public: #if QT_CONFIG(quicktemplates2_multitouch) bool acceptTouch(const QTouchEvent::TouchPoint &point) override; #endif - void handlePress(const QPointF &point) override; - void handleMove(const QPointF &point) override; - void handleRelease(const QPointF &point) override; + void handlePress(const QPointF &point, ulong timestamp) override; + void handleMove(const QPointF &point, ulong timestamp) override; + void handleRelease(const QPointF &point, ulong timestamp) override; void handleUngrab() override; void updateHover(const QPointF &pos); @@ -467,10 +467,10 @@ bool QQuickRangeSliderPrivate::acceptTouch(const QTouchEvent::TouchPoint &point) } #endif -void QQuickRangeSliderPrivate::handlePress(const QPointF &point) +void QQuickRangeSliderPrivate::handlePress(const QPointF &point, ulong timestamp) { Q_Q(QQuickRangeSlider); - QQuickControlPrivate::handlePress(point); + QQuickControlPrivate::handlePress(point, timestamp); pressPoint = point; QQuickItem *firstHandle = first->handle(); @@ -528,10 +528,10 @@ void QQuickRangeSliderPrivate::handlePress(const QPointF &point) } } -void QQuickRangeSliderPrivate::handleMove(const QPointF &point) +void QQuickRangeSliderPrivate::handleMove(const QPointF &point, ulong timestamp) { Q_Q(QQuickRangeSlider); - QQuickControlPrivate::handleMove(point); + QQuickControlPrivate::handleMove(point, timestamp); QQuickRangeSliderNode *pressedNode = QQuickRangeSliderPrivate::pressedNode(touchId); if (pressedNode) { const qreal oldPos = pressedNode->position(); @@ -548,10 +548,10 @@ void QQuickRangeSliderPrivate::handleMove(const QPointF &point) } } -void QQuickRangeSliderPrivate::handleRelease(const QPointF &point) +void QQuickRangeSliderPrivate::handleRelease(const QPointF &point, ulong timestamp) { Q_Q(QQuickRangeSlider); - QQuickControlPrivate::handleRelease(point); + QQuickControlPrivate::handleRelease(point, timestamp); pressPoint = QPointF(); QQuickRangeSliderNode *pressedNode = QQuickRangeSliderPrivate::pressedNode(touchId); @@ -1182,7 +1182,7 @@ void QQuickRangeSlider::mousePressEvent(QMouseEvent *event) { Q_D(QQuickRangeSlider); QQuickControl::mousePressEvent(event); - d->handleMove(event->position()); + d->handleMove(event->position(), event->timestamp()); setKeepMouseGrab(true); } @@ -1198,7 +1198,7 @@ void QQuickRangeSlider::touchEvent(QTouchEvent *event) switch (point.state()) { case QEventPoint::Pressed: - d->handlePress(point.position()); + d->handlePress(point.position(), event->timestamp()); break; case QEventPoint::Updated: if (!keepTouchGrab()) { @@ -1208,10 +1208,10 @@ void QQuickRangeSlider::touchEvent(QTouchEvent *event) setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().y() - point.pressPosition().y(), Qt::YAxis, &point, qRound(d->touchDragThreshold))); } if (keepTouchGrab()) - d->handleMove(point.position()); + d->handleMove(point.position(), event->timestamp()); break; case QEventPoint::Released: - d->handleRelease(point.position()); + d->handleRelease(point.position(), event->timestamp()); break; default: break; diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp index dfa8d1bd..9d62611e 100644 --- a/src/quicktemplates2/qquickscrollbar.cpp +++ b/src/quicktemplates2/qquickscrollbar.cpp @@ -282,10 +282,10 @@ void QQuickScrollBarPrivate::itemImplicitHeightChanged(QQuickItem *item) emit indicatorButton->implicitIndicatorHeightChanged(); } -void QQuickScrollBarPrivate::handlePress(const QPointF &point) +void QQuickScrollBarPrivate::handlePress(const QPointF &point, ulong timestamp) { Q_Q(QQuickScrollBar); - QQuickControlPrivate::handlePress(point); + QQuickControlPrivate::handlePress(point, timestamp); if (QQuickIndicatorButton *indicatorButton = q->decreaseVisual()) { QQuickItem *decreaseArrow = indicatorButton->indicator(); if (decreaseArrow && decreaseArrow->contains(q->mapToItem(decreaseArrow, point + QPointF(0.5, 0.5)))) { @@ -311,10 +311,10 @@ void QQuickScrollBarPrivate::handlePress(const QPointF &point) q->setPressed(true); } -void QQuickScrollBarPrivate::handleMove(const QPointF &point) +void QQuickScrollBarPrivate::handleMove(const QPointF &point, ulong timestamp) { Q_Q(QQuickScrollBar); - QQuickControlPrivate::handleMove(point); + QQuickControlPrivate::handleMove(point, timestamp); /* * handleMove() will be called as soon as you hold the mouse button down *anywhere* on the @@ -325,16 +325,17 @@ void QQuickScrollBarPrivate::handleMove(const QPointF &point) */ if (!pressed) return; + qreal pos = qBound(0.0, positionAt(point) - offset, 1.0 - size); if (snapMode == QQuickScrollBar::SnapAlways) pos = snapPosition(pos); q->setPosition(pos); } -void QQuickScrollBarPrivate::handleRelease(const QPointF &point) +void QQuickScrollBarPrivate::handleRelease(const QPointF &point, ulong timestamp) { Q_Q(QQuickScrollBar); - QQuickControlPrivate::handleRelease(point); + QQuickControlPrivate::handleRelease(point, timestamp); if (orientation == Qt::Vertical) { if (point.y() < q->topPadding() || point.y() >= (q->height() - q->bottomPadding())) @@ -343,6 +344,7 @@ void QQuickScrollBarPrivate::handleRelease(const QPointF &point) if (point.x() < q->leftPadding() || point.x() >= (q->width() - q->rightPadding())) return; } + qreal pos = qBound(0.0, positionAt(point) - offset, 1.0 - size); if (snapMode != QQuickScrollBar::NoSnap) pos = snapPosition(pos); @@ -821,7 +823,7 @@ void QQuickScrollBar::mousePressEvent(QMouseEvent *event) { Q_D(QQuickScrollBar); QQuickControl::mousePressEvent(event); - d->handleMove(event->position()); + d->handleMove(event->position(), event->timestamp()); } #if QT_CONFIG(quicktemplates2_hover) diff --git a/src/quicktemplates2/qquickscrollbar_p_p.h b/src/quicktemplates2/qquickscrollbar_p_p.h index 4c4f72dd..2c6345e9 100644 --- a/src/quicktemplates2/qquickscrollbar_p_p.h +++ b/src/quicktemplates2/qquickscrollbar_p_p.h @@ -86,9 +86,9 @@ public: void itemImplicitWidthChanged(QQuickItem *item) override; void itemImplicitHeightChanged(QQuickItem *item) override; - void handlePress(const QPointF &point) override; - void handleMove(const QPointF &point) override; - void handleRelease(const QPointF &point) override; + void handlePress(const QPointF &point, ulong timestamp) override; + void handleMove(const QPointF &point, ulong timestamp) override; + void handleRelease(const QPointF &point, ulong timestamp) override; void handleUngrab() override; void visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea); diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp index e45a3455..7f6b025d 100644 --- a/src/quicktemplates2/qquickslider.cpp +++ b/src/quicktemplates2/qquickslider.cpp @@ -97,9 +97,9 @@ public: void setPosition(qreal position); void updatePosition(); - void handlePress(const QPointF &point) override; - void handleMove(const QPointF &point) override; - void handleRelease(const QPointF &point) override; + void handlePress(const QPointF &point, ulong timestamp) override; + void handleMove(const QPointF &point, ulong timestamp) override; + void handleRelease(const QPointF &point, ulong timestamp) override; void handleUngrab() override; void cancelHandle(); @@ -179,18 +179,18 @@ void QQuickSliderPrivate::updatePosition() setPosition(pos); } -void QQuickSliderPrivate::handlePress(const QPointF &point) +void QQuickSliderPrivate::handlePress(const QPointF &point, ulong timestamp) { Q_Q(QQuickSlider); - QQuickControlPrivate::handlePress(point); + QQuickControlPrivate::handlePress(point, timestamp); pressPoint = point; q->setPressed(true); } -void QQuickSliderPrivate::handleMove(const QPointF &point) +void QQuickSliderPrivate::handleMove(const QPointF &point, ulong timestamp) { Q_Q(QQuickSlider); - QQuickControlPrivate::handleMove(point); + QQuickControlPrivate::handleMove(point, timestamp); const qreal oldPos = position; qreal pos = positionAt(point); if (snapMode == QQuickSlider::SnapAlways) @@ -203,10 +203,10 @@ void QQuickSliderPrivate::handleMove(const QPointF &point) emit q->moved(); } -void QQuickSliderPrivate::handleRelease(const QPointF &point) +void QQuickSliderPrivate::handleRelease(const QPointF &point, ulong timestamp) { Q_Q(QQuickSlider); - QQuickControlPrivate::handleRelease(point); + QQuickControlPrivate::handleRelease(point, timestamp); pressPoint = QPointF(); const qreal oldPos = position; qreal pos = positionAt(point); @@ -797,7 +797,7 @@ void QQuickSlider::mousePressEvent(QMouseEvent *event) { Q_D(QQuickSlider); QQuickControl::mousePressEvent(event); - d->handleMove(event->position()); + d->handleMove(event->position(), event->timestamp()); setKeepMouseGrab(true); } @@ -813,7 +813,7 @@ void QQuickSlider::touchEvent(QTouchEvent *event) switch (point.state()) { case QEventPoint::Pressed: - d->handlePress(point.position()); + d->handlePress(point.position(), event->timestamp()); break; case QEventPoint::Updated: if (!keepTouchGrab()) { @@ -823,10 +823,10 @@ void QQuickSlider::touchEvent(QTouchEvent *event) setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().y() - d->pressPoint.y(), Qt::YAxis, &point, qRound(d->touchDragThreshold))); } if (keepTouchGrab()) - d->handleMove(point.position()); + d->handleMove(point.position(), event->timestamp()); break; case QEventPoint::Released: - d->handleRelease(point.position()); + d->handleRelease(point.position(), event->timestamp()); break; default: break; diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index d8c8b689..b26c9aa6 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -131,9 +131,9 @@ public: void startPressRepeat(); void stopPressRepeat(); - void handlePress(const QPointF &point) override; - void handleMove(const QPointF &point) override; - void handleRelease(const QPointF &point) override; + void handlePress(const QPointF &point, ulong timestamp) override; + void handleMove(const QPointF &point, ulong timestamp) override; + void handleRelease(const QPointF &point, ulong timestamp) override; void handleUngrab() override; void itemImplicitWidthChanged(QQuickItem *item) override; @@ -337,10 +337,10 @@ void QQuickSpinBoxPrivate::stopPressRepeat() } } -void QQuickSpinBoxPrivate::handlePress(const QPointF &point) +void QQuickSpinBoxPrivate::handlePress(const QPointF &point, ulong timestamp) { Q_Q(QQuickSpinBox); - QQuickControlPrivate::handlePress(point); + QQuickControlPrivate::handlePress(point, timestamp); QQuickItem *ui = up->indicator(); QQuickItem *di = down->indicator(); up->setPressed(ui && ui->isEnabled() && ui->contains(ui->mapFromItem(q, point))); @@ -352,10 +352,10 @@ void QQuickSpinBoxPrivate::handlePress(const QPointF &point) startRepeatDelay(); } -void QQuickSpinBoxPrivate::handleMove(const QPointF &point) +void QQuickSpinBoxPrivate::handleMove(const QPointF &point, ulong timestamp) { Q_Q(QQuickSpinBox); - QQuickControlPrivate::handleMove(point); + QQuickControlPrivate::handleMove(point, timestamp); QQuickItem *ui = up->indicator(); QQuickItem *di = down->indicator(); up->setHovered(ui && ui->isEnabled() && ui->contains(ui->mapFromItem(q, point))); @@ -369,10 +369,10 @@ void QQuickSpinBoxPrivate::handleMove(const QPointF &point) stopPressRepeat(); } -void QQuickSpinBoxPrivate::handleRelease(const QPointF &point) +void QQuickSpinBoxPrivate::handleRelease(const QPointF &point, ulong timestamp) { Q_Q(QQuickSpinBox); - QQuickControlPrivate::handleRelease(point); + QQuickControlPrivate::handleRelease(point, timestamp); QQuickItem *ui = up->indicator(); QQuickItem *di = down->indicator(); diff --git a/src/quicktemplates2/qquicksplitview.cpp b/src/quicktemplates2/qquicksplitview.cpp index bc5e10d2..a34a0c17 100644 --- a/src/quicktemplates2/qquicksplitview.cpp +++ b/src/quicktemplates2/qquicksplitview.cpp @@ -976,10 +976,10 @@ QQuickItem *QQuickSplitViewPrivate::getContentItem() return new QQuickContentItem(q); } -void QQuickSplitViewPrivate::handlePress(const QPointF &point) +void QQuickSplitViewPrivate::handlePress(const QPointF &point, ulong timestamp) { Q_Q(QQuickSplitView); - QQuickContainerPrivate::handlePress(point); + QQuickContainerPrivate::handlePress(point, timestamp); QQuickItem *pressedItem = q->childAt(point.x(), point.y()); const int pressedHandleIndex = m_handleItems.indexOf(pressedItem); @@ -1029,9 +1029,9 @@ void QQuickSplitViewPrivate::handlePress(const QPointF &point) } } -void QQuickSplitViewPrivate::handleMove(const QPointF &point) +void QQuickSplitViewPrivate::handleMove(const QPointF &point, ulong timestamp) { - QQuickContainerPrivate::handleMove(point); + QQuickContainerPrivate::handleMove(point, timestamp); if (m_pressedHandleIndex != -1) { m_mousePos = point; @@ -1041,10 +1041,10 @@ void QQuickSplitViewPrivate::handleMove(const QPointF &point) } } -void QQuickSplitViewPrivate::handleRelease(const QPointF &point) +void QQuickSplitViewPrivate::handleRelease(const QPointF &point, ulong timestamp) { Q_Q(QQuickSplitView); - QQuickContainerPrivate::handleRelease(point); + QQuickContainerPrivate::handleRelease(point, timestamp); if (m_pressedHandleIndex != -1) { QQuickItem *pressedHandle = m_handleItems.at(m_pressedHandleIndex); diff --git a/src/quicktemplates2/qquicksplitview_p_p.h b/src/quicktemplates2/qquicksplitview_p_p.h index 6123f83d..ebf51bf9 100644 --- a/src/quicktemplates2/qquicksplitview_p_p.h +++ b/src/quicktemplates2/qquicksplitview_p_p.h @@ -95,9 +95,9 @@ public: int handleIndexForSplitIndex(int splitIndex) const; QQuickItem *getContentItem() override; - void handlePress(const QPointF &point) override; - void handleMove(const QPointF &point) override; - void handleRelease(const QPointF &point) override; + void handlePress(const QPointF &point, ulong timestamp) override; + void handleMove(const QPointF &point, ulong timestamp) override; + void handleRelease(const QPointF &point, ulong timestamp) override; void itemVisibilityChanged(QQuickItem *item) override; void itemImplicitWidthChanged(QQuickItem *item) override; diff --git a/src/quicktemplates2/qquickswitch.cpp b/src/quicktemplates2/qquickswitch.cpp index 4fc40c33..e9fef6c8 100644 --- a/src/quicktemplates2/qquickswitch.cpp +++ b/src/quicktemplates2/qquickswitch.cpp @@ -85,8 +85,8 @@ public: qreal positionAt(const QPointF &point) const; bool canDrag(const QPointF &movePoint) const; - void handleMove(const QPointF &point) override; - void handleRelease(const QPointF &point) override; + void handleMove(const QPointF &point, ulong timestamp) override; + void handleRelease(const QPointF &point, ulong timestamp) override; QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::Switch); } @@ -114,18 +114,18 @@ bool QQuickSwitchPrivate::canDrag(const QPointF &movePoint) const return (pressPos >= 0.0 && pressPos <= 1.0) || (movePos >= 0.0 && movePos <= 1.0); } -void QQuickSwitchPrivate::handleMove(const QPointF &point) +void QQuickSwitchPrivate::handleMove(const QPointF &point, ulong timestamp) { Q_Q(QQuickSwitch); - QQuickAbstractButtonPrivate::handleMove(point); + QQuickAbstractButtonPrivate::handleMove(point, timestamp); if (q->keepMouseGrab() || q->keepTouchGrab()) q->setPosition(positionAt(point)); } -void QQuickSwitchPrivate::handleRelease(const QPointF &point) +void QQuickSwitchPrivate::handleRelease(const QPointF &point, ulong timestamp) { Q_Q(QQuickSwitch); - QQuickAbstractButtonPrivate::handleRelease(point); + QQuickAbstractButtonPrivate::handleRelease(point, timestamp); q->setKeepMouseGrab(false); q->setKeepTouchGrab(false); } diff --git a/src/quicktemplates2/qquickswitchdelegate.cpp b/src/quicktemplates2/qquickswitchdelegate.cpp index 86041354..e0f1636c 100644 --- a/src/quicktemplates2/qquickswitchdelegate.cpp +++ b/src/quicktemplates2/qquickswitchdelegate.cpp @@ -82,8 +82,8 @@ public: qreal positionAt(const QPointF &point) const; bool canDrag(const QPointF &movePoint) const; - void handleMove(const QPointF &point) override; - void handleRelease(const QPointF &point) override; + void handleMove(const QPointF &point, ulong timestamp) override; + void handleRelease(const QPointF &point, ulong timestamp) override; QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::ListView); } @@ -111,18 +111,18 @@ bool QQuickSwitchDelegatePrivate::canDrag(const QPointF &movePoint) const return (pressPos >= 0.0 && pressPos <= 1.0) || (movePos >= 0.0 && movePos <= 1.0); } -void QQuickSwitchDelegatePrivate::handleMove(const QPointF &point) +void QQuickSwitchDelegatePrivate::handleMove(const QPointF &point, ulong timestamp) { Q_Q(QQuickSwitchDelegate); - QQuickItemDelegatePrivate::handleMove(point); + QQuickItemDelegatePrivate::handleMove(point, timestamp); if (q->keepMouseGrab() || q->keepTouchGrab()) q->setPosition(positionAt(point)); } -void QQuickSwitchDelegatePrivate::handleRelease(const QPointF &point) +void QQuickSwitchDelegatePrivate::handleRelease(const QPointF &point, ulong timestamp) { Q_Q(QQuickSwitchDelegate); - QQuickItemDelegatePrivate::handleRelease(point); + QQuickItemDelegatePrivate::handleRelease(point, timestamp); q->setKeepMouseGrab(false); q->setKeepTouchGrab(false); } diff --git a/tests/auto/controls/data/tst_abstractbutton.qml b/tests/auto/controls/data/tst_abstractbutton.qml index f2242feb..72e56270 100644 --- a/tests/auto/controls/data/tst_abstractbutton.qml +++ b/tests/auto/controls/data/tst_abstractbutton.qml @@ -909,6 +909,35 @@ TestCase { compare(releasedSpy.count, 2) compare(clickedSpy.count, 1) compare(doubleClickedSpy.count, 1) + + let touch = touchEvent(control) + touch.press(0, control) + touch.commit() + compare(pressedSpy.count, 3) + compare(releasedSpy.count, 2) + compare(clickedSpy.count, 1) + compare(doubleClickedSpy.count, 1) + + touch.release(0, control) + touch.commit() + compare(pressedSpy.count, 3) + compare(releasedSpy.count, 3) + compare(clickedSpy.count, 2) + compare(doubleClickedSpy.count, 1) + + touch.press(0, control) + touch.commit() + compare(pressedSpy.count, 4) + compare(releasedSpy.count, 3) + compare(clickedSpy.count, 2) + compare(doubleClickedSpy.count, 1) + + touch.release(0, control) + touch.commit() + compare(pressedSpy.count, 4) + compare(releasedSpy.count, 4) + compare(clickedSpy.count, 2) + compare(doubleClickedSpy.count, 2) } function test_checkedShouldNotSetCheckable() { diff --git a/tests/auto/controls/data/tst_checkbox.qml b/tests/auto/controls/data/tst_checkbox.qml index 81c3d6ca..be68ac0d 100644 --- a/tests/auto/controls/data/tst_checkbox.qml +++ b/tests/auto/controls/data/tst_checkbox.qml @@ -236,6 +236,8 @@ TestCase { // uncheck sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], "pressed"] + // Don't want to double-click. + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(sequenceSpy.success) @@ -254,6 +256,7 @@ TestCase { // release outside sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(sequenceSpy.success) diff --git a/tests/auto/controls/data/tst_delaybutton.qml b/tests/auto/controls/data/tst_delaybutton.qml index 731caf86..0e8d188d 100644 --- a/tests/auto/controls/data/tst_delaybutton.qml +++ b/tests/auto/controls/data/tst_delaybutton.qml @@ -203,6 +203,8 @@ TestCase { ["downChanged", { "down": true }], "pressed", "activated"] + // Don't want to double-click. + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) tryVerify(function() { return sequenceSpy.success}) @@ -220,6 +222,7 @@ TestCase { sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], ["downChanged", { "down": true }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(sequenceSpy.success) @@ -237,6 +240,7 @@ TestCase { sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], ["downChanged", { "down": true }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(sequenceSpy.success) diff --git a/tests/auto/controls/data/tst_radiobutton.qml b/tests/auto/controls/data/tst_radiobutton.qml index 42ef9a15..973e56a3 100644 --- a/tests/auto/controls/data/tst_radiobutton.qml +++ b/tests/auto/controls/data/tst_radiobutton.qml @@ -193,6 +193,8 @@ TestCase { // attempt uncheck sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], "pressed"] + // Don't want to double-click. + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(sequenceSpy.success) @@ -207,6 +209,7 @@ TestCase { // release outside sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(sequenceSpy.success) diff --git a/tests/auto/controls/data/tst_switch.qml b/tests/auto/controls/data/tst_switch.qml index 9050964f..175cd741 100644 --- a/tests/auto/controls/data/tst_switch.qml +++ b/tests/auto/controls/data/tst_switch.qml @@ -249,6 +249,8 @@ TestCase { // uncheck spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], "pressed"] + // Don't want to double-click. + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(spy.success) @@ -265,6 +267,7 @@ TestCase { // release on the right spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(spy.success) @@ -283,6 +286,7 @@ TestCase { // release on the left spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(spy.success) @@ -301,6 +305,7 @@ TestCase { // release in the middle spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, 0, 0).commit() compare(control.pressed, true) verify(spy.success) @@ -460,6 +465,8 @@ TestCase { // press-drag-release outside the indicator spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], "pressed"] + // Don't want to double-click. + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, 0).commit() compare(control.position, 1.0) compare(control.checked, true) @@ -495,6 +502,7 @@ TestCase { // press-drag-release from and to outside the indicator spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width).commit() compare(control.position, 0.0) compare(control.checked, false) diff --git a/tests/auto/controls/data/tst_switchdelegate.qml b/tests/auto/controls/data/tst_switchdelegate.qml index fabd6279..f7f0ead4 100644 --- a/tests/auto/controls/data/tst_switchdelegate.qml +++ b/tests/auto/controls/data/tst_switchdelegate.qml @@ -245,6 +245,8 @@ TestCase { // uncheck spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], "pressed"] + // Don't want to double-click. + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(spy.success) @@ -261,6 +263,7 @@ TestCase { // release on the right spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(spy.success) @@ -279,6 +282,7 @@ TestCase { // release on the left spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width / 2, control.height / 2).commit() compare(control.pressed, true) verify(spy.success) @@ -297,6 +301,7 @@ TestCase { // release in the middle spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, 0, 0).commit() compare(control.pressed, true) verify(spy.success) @@ -456,6 +461,8 @@ TestCase { // press-drag-release outside the indicator spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], "pressed"] + // Don't want to double-click. + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, 0).commit() compare(control.position, 1.0) compare(control.checked, true) @@ -491,6 +498,7 @@ TestCase { // press-drag-release from and to outside the indicator spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) touch.press(0, control, control.width).commit() compare(control.position, 0.0) compare(control.checked, false) -- cgit v1.2.3