From fe11219a0cf9f9a227532d9e839cd4c35e824c5d Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Sat, 26 Jun 2021 01:00:56 +0200 Subject: [PATCH] improve gesture recognition In order to not make misdetections with sub-pixel movements the gesture recognizer completely ignored those. This fails however when you move your fingers very slowly, so instead accumulate the delta and only use it for direction detection if it's high enough. --- src/gestures.cpp | 26 +++++++++++++++++++------- src/gestures.h | 2 ++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/gestures.cpp b/src/gestures.cpp index 7839e2eba4..72e2c619f9 100644 --- a/src/gestures.cpp +++ b/src/gestures.cpp @@ -142,24 +142,30 @@ int GestureRecognizer::startSwipeGesture(uint fingerCount, const QPointF &startP void GestureRecognizer::updateSwipeGesture(const QSizeF &delta) { m_swipeUpdates << delta; - if (std::abs(delta.width()) < 1 && std::abs(delta.height()) < 1) { - // some (touch) devices report sub-pixel movement on screen edges - // this often cancels gestures -> ignore these movements + m_currentDelta += delta; + // with high resolution touch(pad) gestures can be cancelled without intention + // -> don't cancel movements if their accumulated values are too small but also still update the gesture for animations + if (std::abs(m_currentDelta.width()) > 1 || std::abs(m_currentDelta.height()) > 1) { + m_lastDelta = m_currentDelta; + m_currentDelta = QSizeF(0, 0); + } else if (std::abs(m_lastDelta.width()) < 1 && std::abs(m_lastDelta.height()) < 1) { + // no direction yet return; } + // determine the direction of the swipe - if (delta.width() == delta.height()) { + if (m_lastDelta.width() == m_lastDelta.height()) { // special case of diagonal, this is not yet supported, thus cancel all gestures cancelActiveSwipeGestures(); return; } SwipeGesture::Direction direction; - if (std::abs(delta.width()) > std::abs(delta.height())) { + if (std::abs(m_lastDelta.width()) > std::abs(m_lastDelta.height())) { // horizontal - direction = delta.width() < 0 ? SwipeGesture::Direction::Left : SwipeGesture::Direction::Right; + direction = m_lastDelta.width() < 0 ? SwipeGesture::Direction::Left : SwipeGesture::Direction::Right; } else { // vertical - direction = delta.height() < 0 ? SwipeGesture::Direction::Up : SwipeGesture::Direction::Down; + direction = m_lastDelta.height() < 0 ? SwipeGesture::Direction::Up : SwipeGesture::Direction::Down; } const QSizeF combinedDelta = std::accumulate(m_swipeUpdates.constBegin(), m_swipeUpdates.constEnd(), QSizeF(0, 0)); for (auto it = m_activeSwipeGestures.begin(); it != m_activeSwipeGestures.end();) { @@ -182,12 +188,16 @@ void GestureRecognizer::cancelActiveSwipeGestures() Q_EMIT g->cancelled(); } m_activeSwipeGestures.clear(); + m_currentDelta = QSizeF(0, 0); + m_lastDelta = QSizeF(0, 0); } void GestureRecognizer::cancelSwipeGesture() { cancelActiveSwipeGestures(); m_swipeUpdates.clear(); + m_currentDelta = QSizeF(0, 0); + m_lastDelta = QSizeF(0, 0); } void GestureRecognizer::endSwipeGesture() @@ -202,6 +212,8 @@ void GestureRecognizer::endSwipeGesture() } m_activeSwipeGestures.clear(); m_swipeUpdates.clear(); + m_currentDelta = QSizeF(0, 0); + m_lastDelta = QSizeF(0, 0); } } diff --git a/src/gestures.h b/src/gestures.h index 9fc2fadc3e..eed5ced5b0 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -201,6 +201,8 @@ private: QVector m_activeSwipeGestures; QMap m_destroyConnections; QVector m_swipeUpdates; + QSizeF m_lastDelta = QSizeF(0, 0); + QSizeF m_currentDelta = QSizeF(0, 0); }; }