From 4eb74f5b7173cbf8de15628fd0233b43d25bdbf8 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Tue, 29 May 2018 12:05:16 +0200 Subject: [PATCH] working with nested gesture recognizers fixed --- src/controls/QskGestureRecognizer.cpp | 21 ++++++++++++++++++++- src/controls/QskGestureRecognizer.h | 2 ++ src/controls/QskScrollView.cpp | 6 ++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/controls/QskGestureRecognizer.cpp b/src/controls/QskGestureRecognizer.cpp index dd8b185e..010e7c7e 100644 --- a/src/controls/QskGestureRecognizer.cpp +++ b/src/controls/QskGestureRecognizer.cpp @@ -74,8 +74,10 @@ namespace if ( m_recognizer ) { - m_recognizer->reject(); + auto recognizer = m_recognizer; m_recognizer = nullptr; + + recognizer->reject(); } } @@ -105,6 +107,7 @@ public: PrivateData(): watchedItem( nullptr ), timestamp( 0 ), + timestampProcessed( 0 ), timeout( -1 ), buttons( Qt::NoButton ), state( QskGestureRecognizer::Idle ), @@ -116,6 +119,7 @@ public: PendingEvents pendingEvents; ulong timestamp; + ulong timestampProcessed; int timeout; // ms @@ -170,6 +174,11 @@ ulong QskGestureRecognizer::timestamp() const return m_data->timestamp; } +bool QskGestureRecognizer::hasProcessedBefore( const QMouseEvent* event ) const +{ + return event && ( event->timestamp() <= m_data->timestampProcessed ); +} + bool QskGestureRecognizer::isReplaying() const { return m_data->isReplayingEvents; @@ -383,6 +392,16 @@ void QskGestureRecognizer::reject() if ( !events.isEmpty() && events[0]->type() == QEvent::MouseButtonPress ) { + /* + In a situation of several recognizers ( f.e a vertical + scroll view inside a horizontal swipe view ), we might receive + cloned events from another recognizer. + To avoid to process them twice we store the most recent timestamp + of the cloned events we have already processed, but reposted. + */ + + m_data->timestampProcessed = events.last()->timestamp(); + QCoreApplication::sendEvent( window, events[0] ); /* diff --git a/src/controls/QskGestureRecognizer.h b/src/controls/QskGestureRecognizer.h index 52af7676..7dedffa2 100644 --- a/src/controls/QskGestureRecognizer.h +++ b/src/controls/QskGestureRecognizer.h @@ -37,6 +37,7 @@ public: void setTimeout( int ); int timeout() const; + // timestamp, when the Idle state had been left ulong timestamp() const; bool processEvent( QQuickItem*, QEvent*, bool blockReplayedEvents = true ); @@ -48,6 +49,7 @@ public: State state() const; bool isReplaying() const; + bool hasProcessedBefore( const QMouseEvent* ) const; protected: virtual void pressEvent( const QMouseEvent* ); diff --git a/src/controls/QskScrollView.cpp b/src/controls/QskScrollView.cpp index 567232fa..0d1a8bdf 100644 --- a/src/controls/QskScrollView.cpp +++ b/src/controls/QskScrollView.cpp @@ -604,9 +604,11 @@ bool QskScrollView::gestureFilter( QQuickItem* item, QEvent* event ) if ( event->type() == QEvent::MouseButtonPress ) { - if ( recognizer.isReplaying() ) + if ( ( item != this ) && ( recognizer.timeout() < 0 ) ) { - if ( ( item != this ) || ( recognizer.timeout() < 0 ) ) + const auto mouseEvent = static_cast< QMouseEvent* >( event ); + + if ( recognizer.hasProcessedBefore( mouseEvent ) ) return false; }