workround for broken mouse grabbing ( >= Qt 5.8 ) added
This commit is contained in:
parent
e32c17df51
commit
5bf10f5cc5
|
@ -55,6 +55,44 @@ static inline QMouseEvent* qskClonedMouseEvent(
|
||||||
return clonedEvent;
|
return clonedEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qskGrabTouchMouse( QQuickItem* item )
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK( 5, 8, 0 )
|
||||||
|
auto wd = QQuickWindowPrivate::get( item->window() );
|
||||||
|
|
||||||
|
if ( wd->touchMouseDevice == nullptr )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
For synthesized mouse events QQuickWindow sends
|
||||||
|
an initial QEvent::MouseButtonPress before setting
|
||||||
|
touchMouseDevice/touchMouseId and a call of grabMouse
|
||||||
|
is stored in a pointerEvent for the generic mouse device.
|
||||||
|
Then all following synthesized mouse events are not grabbed
|
||||||
|
properly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for ( const auto event : wd->pointerEventInstances )
|
||||||
|
{
|
||||||
|
if ( auto touchEvent = event->asPointerTouchEvent() )
|
||||||
|
{
|
||||||
|
if ( touchEvent->isPressEvent() )
|
||||||
|
{
|
||||||
|
if ( const auto p = touchEvent->point( 0 ) )
|
||||||
|
{
|
||||||
|
wd->touchMouseDevice = touchEvent->device();
|
||||||
|
wd->touchMouseId = p->pointId();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
item->grabMouse();
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -336,7 +374,7 @@ bool QskGestureRecognizer::processEvent(
|
||||||
We grab the mouse for watchedItem and indicate, that we want
|
We grab the mouse for watchedItem and indicate, that we want
|
||||||
to keep it. From now on all mouse events should end up at watchedItem.
|
to keep it. From now on all mouse events should end up at watchedItem.
|
||||||
*/
|
*/
|
||||||
watchedItem->grabMouse();
|
qskGrabTouchMouse( watchedItem );
|
||||||
watchedItem->setKeepMouseGrab( true );
|
watchedItem->setKeepMouseGrab( true );
|
||||||
|
|
||||||
m_data->timestamp = mouseEvent->timestamp();
|
m_data->timestamp = mouseEvent->timestamp();
|
||||||
|
@ -403,30 +441,8 @@ bool QskGestureRecognizer::processEvent(
|
||||||
|
|
||||||
if ( m_data->state == Pending )
|
if ( m_data->state == Pending )
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
|
|
||||||
if ( mouseEvent->source() == Qt::MouseEventSynthesizedByQt )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
When replaying mouse events inside of handling synthesized
|
|
||||||
mouse event Qt runs into a situation where
|
|
||||||
QQuickWindow::mouseGrabberItem() returns the value from the
|
|
||||||
wrong input device. So we can't call reject() immediately.
|
|
||||||
|
|
||||||
Unfortunately this introduces a gap where other events might
|
|
||||||
be delivered before the QEvent::timer gets processed.
|
|
||||||
In the long run it might be better to record and replay
|
|
||||||
real touch events - what is necessary for multi touch gestures
|
|
||||||
anyway.
|
|
||||||
*/
|
|
||||||
qskTimerTable->stopTimer( this );
|
|
||||||
qskTimerTable->startTimer( 0, this );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
reject();
|
reject();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
releaseEvent( mouseEvent );
|
releaseEvent( mouseEvent );
|
||||||
|
@ -509,18 +525,8 @@ void QskGestureRecognizer::reject()
|
||||||
|
|
||||||
m_data->timestampProcessed = events.last()->timestamp();
|
m_data->timestampProcessed = events.last()->timestamp();
|
||||||
|
|
||||||
QCoreApplication::sendEvent( window, events[ 0 ] );
|
for ( auto event : events )
|
||||||
|
QCoreApplication::sendEvent( window, event );
|
||||||
/*
|
|
||||||
After resending the initial press someone else
|
|
||||||
might be interested in this sequence.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( window->mouseGrabberItem() )
|
|
||||||
{
|
|
||||||
for ( int i = 1; i < events.size(); i++ )
|
|
||||||
QCoreApplication::sendEvent( window, events[ i ] );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data->isReplayingEvents = false;
|
m_data->isReplayingEvents = false;
|
||||||
|
@ -535,19 +541,13 @@ void QskGestureRecognizer::reset()
|
||||||
{
|
{
|
||||||
qskTimerTable->stopTimer( this );
|
qskTimerTable->stopTimer( this );
|
||||||
|
|
||||||
if ( auto watchedItem = m_data->watchedItem )
|
if ( auto item = m_data->watchedItem )
|
||||||
{
|
{
|
||||||
watchedItem->setKeepMouseGrab( false );
|
item->setKeepMouseGrab( false );
|
||||||
|
item->ungrabMouse();
|
||||||
if ( auto window = watchedItem->window() )
|
|
||||||
{
|
|
||||||
if ( window->mouseGrabberItem() == m_data->watchedItem )
|
|
||||||
watchedItem->ungrabMouse();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data->pendingEvents.reset();
|
m_data->pendingEvents.reset();
|
||||||
|
|
||||||
m_data->timestamp = 0;
|
m_data->timestamp = 0;
|
||||||
|
|
||||||
setState( Idle );
|
setState( Idle );
|
||||||
|
|
Loading…
Reference in New Issue