@@ -62,6 +62,8 @@ namespace
6262const std::string DEFAULT_STREAM_ID ( " QmlStreamer" );
6363const QString GESTURES_CONTEXT_PROPERTY ( " deflectgestures" );
6464const QString WEBENGINEVIEW_OBJECT_NAME ( " webengineview" );
65+ const int TOUCH_TAPANDHOLD_DIST_PX = 20 ;
66+ const int TOUCH_TAPANDHOLD_TIMEOUT_MS = 200 ;
6567}
6668
6769class RenderControl : public QQuickRenderControl
@@ -109,6 +111,7 @@ QmlStreamer::Impl::Impl( const QString& qmlFile, const std::string& streamHost,
109111 , _streaming( false )
110112 , _streamHost( streamHost )
111113 , _streamId( streamId )
114+ , _mouseMode( false )
112115{
113116 // Expose stream gestures to qml objects
114117 _qmlEngine->rootContext ()->setContextProperty ( GESTURES_CONTEXT_PROPERTY,
@@ -135,6 +138,10 @@ QmlStreamer::Impl::Impl( const QString& qmlFile, const std::string& streamHost,
135138#else
136139 qWarning () << " DeflectQt was not compiled with WebEngineView support" ;
137140#endif
141+ connect ( &_mouseModeTimer, &QTimer::timeout, [this ]() {
142+ if ( _touchIsTapAndHold ( ))
143+ _switchFromTouchToMouseMode ();
144+ });
138145
139146 // Pass _context->format(), not format_. Format does not specify and color
140147 // buffer sizes, while the context, that has just been created, reports a
@@ -280,28 +287,49 @@ void QmlStreamer::Impl::_onPressed( double x_, double y_ )
280287 auto touchPoint = _makeTouchPoint ( 0 , { x_, y_ });
281288 touchPoint.setState ( Qt::TouchPointPressed );
282289
283- auto * e = new QTouchEvent ( QEvent::TouchBegin, &_device, Qt::NoModifier,
284- Qt::TouchPointPressed, { touchPoint } );
290+ _startMouseModeSwitchDetection ( touchPoint.pos ( ));
291+
292+ auto e = new QTouchEvent ( QEvent::TouchBegin, &_device, Qt::NoModifier,
293+ Qt::TouchPointPressed, { touchPoint } );
285294 QCoreApplication::postEvent ( _quickWindow, e );
286295}
287296
288297void QmlStreamer::Impl::_onMoved ( double x_, double y_ )
289298{
299+ if ( _mouseMode )
300+ {
301+ const QPoint pos ( x_ * width (), y_ * height ( ));
302+ _sendMouseEvent ( QEvent::MouseMove, pos );
303+ return ;
304+ }
305+
290306 auto touchPoint = _makeTouchPoint ( 0 , { x_, y_ });
291307 touchPoint.setState ( Qt::TouchPointMoved );
292308
293- auto * e = new QTouchEvent ( QEvent::TouchUpdate, &_device, Qt::NoModifier,
294- Qt::TouchPointMoved, { touchPoint } );
309+ if ( _mouseModeTimer.isActive ( ))
310+ _touchCurrentPos = touchPoint.pos ();
311+
312+ auto e = new QTouchEvent ( QEvent::TouchUpdate, &_device, Qt::NoModifier,
313+ Qt::TouchPointMoved, { touchPoint } );
295314 QCoreApplication::postEvent ( _quickWindow, e );
296315}
297316
298317void QmlStreamer::Impl::_onReleased ( double x_, double y_ )
299318{
319+ _mouseModeTimer.stop ();
320+ if ( _mouseMode )
321+ {
322+ const QPoint pos ( x_ * width (), y_ * height ( ));
323+ _sendMouseEvent ( QEvent::MouseButtonRelease, pos );
324+ _mouseMode = false ;
325+ return ;
326+ }
327+
300328 auto touchPoint = _makeTouchPoint ( 0 , { x_, y_ });
301329 touchPoint.setState ( Qt::TouchPointReleased );
302330
303- auto * e = new QTouchEvent ( QEvent::TouchEnd, &_device, Qt::NoModifier,
304- Qt::TouchPointReleased, { touchPoint } );
331+ auto e = new QTouchEvent ( QEvent::TouchEnd, &_device, Qt::NoModifier,
332+ Qt::TouchPointReleased, { touchPoint } );
305333 QCoreApplication::postEvent ( _quickWindow, e );
306334}
307335
@@ -489,6 +517,39 @@ void QmlStreamer::Impl::_updateSizes( const QSize& size_ )
489517 }
490518}
491519
520+ void QmlStreamer::Impl::_startMouseModeSwitchDetection ( const QPointF& pos )
521+ {
522+ auto item = _rootItem->childAt ( pos.x (), pos.y ());
523+ if ( item->objectName () == WEBENGINEVIEW_OBJECT_NAME )
524+ {
525+ _mouseModeTimer.start ( TOUCH_TAPANDHOLD_TIMEOUT_MS );
526+ _touchStartPos = pos;
527+ _touchCurrentPos = pos;
528+ }
529+ }
530+
531+ bool QmlStreamer::Impl::_touchIsTapAndHold ()
532+ {
533+ const auto distance = (_touchCurrentPos - _touchStartPos).manhattanLength ();
534+ return distance < TOUCH_TAPANDHOLD_DIST_PX;
535+ }
536+
537+ void QmlStreamer::Impl::_switchFromTouchToMouseMode ()
538+ {
539+ _onReleased ( _touchCurrentPos.x () / width (),
540+ _touchCurrentPos.y () / height ( ));
541+ _mouseMode = true ;
542+ _sendMouseEvent ( QEvent::MouseButtonPress, _touchCurrentPos );
543+ }
544+
545+ void QmlStreamer::Impl::_sendMouseEvent ( const QEvent::Type eventType,
546+ const QPointF& pos )
547+ {
548+ auto e = new QMouseEvent ( eventType, pos, Qt::LeftButton, Qt::LeftButton,
549+ Qt::NoModifier );
550+ QCoreApplication::postEvent ( _quickWindow, e );
551+ }
552+
492553QTouchEvent::TouchPoint
493554QmlStreamer::Impl::_makeTouchPoint ( const int id, const QPointF& normPos ) const
494555{
0 commit comments