working with nested gesture recognizers fixed

This commit is contained in:
Uwe Rathmann 2018-05-29 12:05:16 +02:00
parent 0c5dc0ce37
commit 4eb74f5b71
3 changed files with 26 additions and 3 deletions

View File

@ -74,8 +74,10 @@ namespace
if ( m_recognizer ) if ( m_recognizer )
{ {
m_recognizer->reject(); auto recognizer = m_recognizer;
m_recognizer = nullptr; m_recognizer = nullptr;
recognizer->reject();
} }
} }
@ -105,6 +107,7 @@ public:
PrivateData(): PrivateData():
watchedItem( nullptr ), watchedItem( nullptr ),
timestamp( 0 ), timestamp( 0 ),
timestampProcessed( 0 ),
timeout( -1 ), timeout( -1 ),
buttons( Qt::NoButton ), buttons( Qt::NoButton ),
state( QskGestureRecognizer::Idle ), state( QskGestureRecognizer::Idle ),
@ -116,6 +119,7 @@ public:
PendingEvents pendingEvents; PendingEvents pendingEvents;
ulong timestamp; ulong timestamp;
ulong timestampProcessed;
int timeout; // ms int timeout; // ms
@ -170,6 +174,11 @@ ulong QskGestureRecognizer::timestamp() const
return m_data->timestamp; return m_data->timestamp;
} }
bool QskGestureRecognizer::hasProcessedBefore( const QMouseEvent* event ) const
{
return event && ( event->timestamp() <= m_data->timestampProcessed );
}
bool QskGestureRecognizer::isReplaying() const bool QskGestureRecognizer::isReplaying() const
{ {
return m_data->isReplayingEvents; return m_data->isReplayingEvents;
@ -383,6 +392,16 @@ void QskGestureRecognizer::reject()
if ( !events.isEmpty() && events[0]->type() == QEvent::MouseButtonPress ) 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] ); QCoreApplication::sendEvent( window, events[0] );
/* /*

View File

@ -37,6 +37,7 @@ public:
void setTimeout( int ); void setTimeout( int );
int timeout() const; int timeout() const;
// timestamp, when the Idle state had been left
ulong timestamp() const; ulong timestamp() const;
bool processEvent( QQuickItem*, QEvent*, bool blockReplayedEvents = true ); bool processEvent( QQuickItem*, QEvent*, bool blockReplayedEvents = true );
@ -48,6 +49,7 @@ public:
State state() const; State state() const;
bool isReplaying() const; bool isReplaying() const;
bool hasProcessedBefore( const QMouseEvent* ) const;
protected: protected:
virtual void pressEvent( const QMouseEvent* ); virtual void pressEvent( const QMouseEvent* );

View File

@ -604,9 +604,11 @@ bool QskScrollView::gestureFilter( QQuickItem* item, QEvent* event )
if ( event->type() == QEvent::MouseButtonPress ) 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; return false;
} }