corner case for simultaneous mouse press events on different screens
fixed
This commit is contained in:
parent
b0a87163bf
commit
db3f1e3c19
|
@ -6,6 +6,7 @@
|
||||||
#include <QBasicTimer>
|
#include <QBasicTimer>
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
QSK_QT_PRIVATE_BEGIN
|
||||||
#include <private/qquickwindow_p.h>
|
#include <private/qquickwindow_p.h>
|
||||||
|
@ -33,38 +34,37 @@ static inline QMouseEvent* qskClonedMouseEvent(
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// again we try to avoid creating unnecessary QObjects by
|
/*
|
||||||
// using the same timer Object for all gesture recognizers
|
As we don't want QskGestureRecognizer being a QObject
|
||||||
|
we need some extra timers - usually one per screen.
|
||||||
|
*/
|
||||||
|
|
||||||
class Timer final : public QObject
|
class Timer final : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static Timer* instance()
|
Timer():
|
||||||
|
m_recognizer( nullptr )
|
||||||
{
|
{
|
||||||
// ther should be only one mouse being pressed at the same time
|
|
||||||
static Timer timer;
|
|
||||||
return &timer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void start( int ms, QskGestureRecognizer* recognizer )
|
void start( int ms, QskGestureRecognizer* recognizer )
|
||||||
{
|
{
|
||||||
if ( m_recognizer && m_recognizer != recognizer )
|
if ( m_timer.isActive() )
|
||||||
{
|
qWarning() << "QskGestureRecognizer: resetting an active timer";
|
||||||
qWarning() << "QskGestureRecognizer: running more than one recognizer at the same time";
|
|
||||||
m_recognizer->reject(); // should never happen
|
|
||||||
}
|
|
||||||
|
|
||||||
m_recognizer = recognizer;
|
m_recognizer = recognizer;
|
||||||
m_timer.start( ms, this );
|
m_timer.start( ms, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop( const QskGestureRecognizer* recognizer )
|
void stop()
|
||||||
{
|
{
|
||||||
if ( recognizer == m_recognizer )
|
m_timer.stop();
|
||||||
{
|
m_recognizer = nullptr;
|
||||||
m_timer.stop();
|
}
|
||||||
m_recognizer = nullptr;
|
|
||||||
}
|
const QskGestureRecognizer* recognizer() const
|
||||||
|
{
|
||||||
|
return m_recognizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -85,6 +85,60 @@ namespace
|
||||||
QskGestureRecognizer* m_recognizer;
|
QskGestureRecognizer* m_recognizer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TimerTable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~TimerTable()
|
||||||
|
{
|
||||||
|
qDeleteAll( m_table );
|
||||||
|
}
|
||||||
|
|
||||||
|
void startTimer( int ms, QskGestureRecognizer* recognizer )
|
||||||
|
{
|
||||||
|
Timer* timer = nullptr;
|
||||||
|
|
||||||
|
for ( auto t : qskAsConst( m_table ) )
|
||||||
|
{
|
||||||
|
if ( t->recognizer() == nullptr
|
||||||
|
|| t->recognizer() == recognizer )
|
||||||
|
{
|
||||||
|
timer = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( timer == nullptr )
|
||||||
|
{
|
||||||
|
timer = new Timer();
|
||||||
|
m_table += timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->start( ms, recognizer );
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopTimer( const QskGestureRecognizer* recognizer )
|
||||||
|
{
|
||||||
|
for ( auto timer : qskAsConst( m_table ) )
|
||||||
|
{
|
||||||
|
if ( timer->recognizer() == recognizer )
|
||||||
|
{
|
||||||
|
// we keep the timer to be used later again
|
||||||
|
timer->stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
Usually we have not more than one entry.
|
||||||
|
Only when having more than one screen we
|
||||||
|
might have mouse events to be processed
|
||||||
|
simultaneously.
|
||||||
|
*/
|
||||||
|
QVector< Timer* > m_table;
|
||||||
|
};
|
||||||
|
|
||||||
class PendingEvents : public QVector< QMouseEvent* >
|
class PendingEvents : public QVector< QMouseEvent* >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -101,6 +155,8 @@ namespace
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC( TimerTable, qskTimerTable )
|
||||||
|
|
||||||
class QskGestureRecognizer::PrivateData
|
class QskGestureRecognizer::PrivateData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -136,7 +192,7 @@ QskGestureRecognizer::QskGestureRecognizer():
|
||||||
|
|
||||||
QskGestureRecognizer::~QskGestureRecognizer()
|
QskGestureRecognizer::~QskGestureRecognizer()
|
||||||
{
|
{
|
||||||
Timer::instance()->stop( this );
|
qskTimerTable->stopTimer( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskGestureRecognizer::setWatchedItem( QQuickItem* item )
|
void QskGestureRecognizer::setWatchedItem( QQuickItem* item )
|
||||||
|
@ -286,7 +342,7 @@ bool QskGestureRecognizer::processEvent(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( m_data->timeout > 0 )
|
if ( m_data->timeout > 0 )
|
||||||
Timer::instance()->start( m_data->timeout, this );
|
qskTimerTable->startTimer( m_data->timeout, this );
|
||||||
|
|
||||||
setState( Pending );
|
setState( Pending );
|
||||||
}
|
}
|
||||||
|
@ -370,7 +426,7 @@ void QskGestureRecognizer::stateChanged( State from, State to )
|
||||||
|
|
||||||
void QskGestureRecognizer::accept()
|
void QskGestureRecognizer::accept()
|
||||||
{
|
{
|
||||||
Timer::instance()->stop( this );
|
qskTimerTable->stopTimer( this );
|
||||||
m_data->pendingEvents.reset();
|
m_data->pendingEvents.reset();
|
||||||
|
|
||||||
setState( Accepted );
|
setState( Accepted );
|
||||||
|
@ -426,7 +482,8 @@ void QskGestureRecognizer::abort()
|
||||||
|
|
||||||
void QskGestureRecognizer::reset()
|
void QskGestureRecognizer::reset()
|
||||||
{
|
{
|
||||||
Timer::instance()->stop( this );
|
qskTimerTable->stopTimer( this );
|
||||||
|
|
||||||
m_data->watchedItem->setKeepMouseGrab( false );
|
m_data->watchedItem->setKeepMouseGrab( false );
|
||||||
m_data->pendingEvents.reset();
|
m_data->pendingEvents.reset();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue