on xenial help sign in
TouchDispatcher: synthesize MouseButtonDblClick events
19dc3daDaniel d'Andrada
libs/UbuntuGestures/DebugHelpers.cpp+1−1
@@ -83,7 +83,7 @@ QString mouseEventToString(const QMouseEvent *ev)
83 message.append("MouseButtonDblClick ");
83 message.append("MouseButtonDblClick ");
84 break;
84 break;
85 case QEvent::MouseMove:
85 case QEvent::MouseMove:
86− message.append("MouseButtonMove ");
86+ message.append("MouseMove ");
87 break;
87 break;
88 default:
88 default:
89 message.append("INVALID_MOUSE_EVENT_TYPE ");
89 message.append("INVALID_MOUSE_EVENT_TYPE ");
plugins/Ubuntu/Gestures/TouchDispatcher.cpp+43
@@ -16,7 +16,9 @@
16
16
17#include "TouchDispatcher.h"
17#include "TouchDispatcher.h"
18
18
19+#include <QGuiApplication>
19#include <QScopedPointer>
20#include <QScopedPointer>
21+#include <QStyleHints>
20
22
21#pragma GCC diagnostic push
23#pragma GCC diagnostic push
22#pragma GCC diagnostic ignored "-pedantic"
24#pragma GCC diagnostic ignored "-pedantic"
@@ -32,6 +34,7 @@
32TouchDispatcher::TouchDispatcher()
34TouchDispatcher::TouchDispatcher()
33 : m_status(NoActiveTouch)
35 : m_status(NoActiveTouch)
34 , m_touchMouseId(-1)
36 , m_touchMouseId(-1)
37+ , m_touchMousePressTimestamp(0)
35{
38{
36}
39}
37
40
@@ -148,6 +151,18 @@ void TouchDispatcher::dispatchTouchBegin(
148 #endif
151 #endif
149 m_status = DeliveringMouseEvents;
152 m_status = DeliveringMouseEvents;
150 m_touchMouseId = targetTouchPoints.at(0).id();
153 m_touchMouseId = targetTouchPoints.at(0).id();
154+
155+ if (checkIfDoubleClicked(timestamp)) {
156+ QScopedPointer<QMouseEvent> doubleClickEvent(
157+ touchToMouseEvent(QEvent::MouseButtonDblClick, targetTouchPoints.at(0), timestamp,
158+ modifiers, false /* transformNeeded */));
159+ #if TOUCHDISPATCHER_DEBUG
160+ qDebug() << "[TouchDispatcher] dispatching" << qPrintable(mouseEventToString(doubleClickEvent.data()))
161+ << "to" << m_targetItem.data();
162+ #endif
163+ QCoreApplication::sendEvent(targetItem, doubleClickEvent.data());
164+ }
165+
151 } else {
166 } else {
152 #if TOUCHDISPATCHER_DEBUG
167 #if TOUCHDISPATCHER_DEBUG
153 qDebug() << "[TouchDispatcher] Item rejected the QMouseEvent.";
168 qDebug() << "[TouchDispatcher] Item rejected the QMouseEvent.";
@@ -322,3 +337,31 @@ QMouseEvent *TouchDispatcher::touchToMouseEvent(
322 //QGuiApplicationPrivate::setMouseEventSource(me, Qt::MouseEventSynthesizedByQt);
337 //QGuiApplicationPrivate::setMouseEventSource(me, Qt::MouseEventSynthesizedByQt);
323 return me;
338 return me;
324}
339}
340+
341+/*
342+ Copied from qquickwindow.cpp which has:
343+ Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
344+ Under GPL 3.0 license.
345+*/
346+bool TouchDispatcher::checkIfDoubleClicked(ulong newPressEventTimestamp)
347+{
348+ bool doubleClicked;
349+
350+ if (m_touchMousePressTimestamp == 0) {
351+ // just initialize the variable
352+ m_touchMousePressTimestamp = newPressEventTimestamp;
353+ doubleClicked = false;
354+ } else {
355+ ulong timeBetweenPresses = newPressEventTimestamp - m_touchMousePressTimestamp;
356+ ulong doubleClickInterval = static_cast<ulong>(qApp->styleHints()->
357+ mouseDoubleClickInterval());
358+ doubleClicked = timeBetweenPresses < doubleClickInterval;
359+ if (doubleClicked) {
360+ m_touchMousePressTimestamp = 0;
361+ } else {
362+ m_touchMousePressTimestamp = newPressEventTimestamp;
363+ }
364+ }
365+
366+ return doubleClicked;
367+}
plugins/Ubuntu/Gestures/TouchDispatcher.h+3
@@ -71,6 +71,8 @@ private:
71 QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p,
71 QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p,
72 ulong timestamp, Qt::KeyboardModifiers modifiers, bool transformNeeded = true);
72 ulong timestamp, Qt::KeyboardModifiers modifiers, bool transformNeeded = true);
73
73
74+ bool checkIfDoubleClicked(ulong newPressEventTimestamp);
75+
74 QPointer<QQuickItem> m_targetItem;
76 QPointer<QQuickItem> m_targetItem;
75
77
76 enum {
78 enum {
@@ -81,6 +83,7 @@ private:
81 } m_status;
83 } m_status;
82
84
83 int m_touchMouseId;
85 int m_touchMouseId;
86+ ulong m_touchMousePressTimestamp;
84};
87};
85
88
86#endif // UBUNTU_TOUCH_DISPATCHER_H
89#endif // UBUNTU_TOUCH_DISPATCHER_H
tests/plugins/Ubuntu/Gestures/GestureTest.cpp+6
@@ -90,6 +90,7 @@ DummyItem::DummyItem(QQuickItem *parent)
90 mousePressEventHandler = defaultMouseEventHandler;
90 mousePressEventHandler = defaultMouseEventHandler;
91 mouseMoveEventHandler = defaultMouseEventHandler;
91 mouseMoveEventHandler = defaultMouseEventHandler;
92 mouseReleaseEventHandler = defaultMouseEventHandler;
92 mouseReleaseEventHandler = defaultMouseEventHandler;
93+ mouseDoubleClickEventHandler = defaultMouseEventHandler;
93}
94}
94
95
95void DummyItem::touchEvent(QTouchEvent *event)
96void DummyItem::touchEvent(QTouchEvent *event)
@@ -113,6 +114,11 @@ void DummyItem::mouseReleaseEvent(QMouseEvent *event)
113 mouseReleaseEventHandler(event);
114 mouseReleaseEventHandler(event);
114}
115}
115
116
117+void DummyItem::mouseDoubleClickEvent(QMouseEvent *event)
118+{
119+ mouseDoubleClickEventHandler(event);
120+}
121+
116void DummyItem::defaultTouchEventHandler(QTouchEvent *event)
122void DummyItem::defaultTouchEventHandler(QTouchEvent *event)
117{
123{
118 event->accept();
124 event->accept();
tests/plugins/Ubuntu/Gestures/GestureTest.h+2
@@ -52,12 +52,14 @@ public:
52 std::function<void(QMouseEvent*)> mousePressEventHandler;
52 std::function<void(QMouseEvent*)> mousePressEventHandler;
53 std::function<void(QMouseEvent*)> mouseMoveEventHandler;
53 std::function<void(QMouseEvent*)> mouseMoveEventHandler;
54 std::function<void(QMouseEvent*)> mouseReleaseEventHandler;
54 std::function<void(QMouseEvent*)> mouseReleaseEventHandler;
55+ std::function<void(QMouseEvent*)> mouseDoubleClickEventHandler;
55protected:
56protected:
56 void touchEvent(QTouchEvent *event) override;
57 void touchEvent(QTouchEvent *event) override;
57
58
58 void mousePressEvent(QMouseEvent *event) override;
59 void mousePressEvent(QMouseEvent *event) override;
59 void mouseMoveEvent(QMouseEvent *event) override;
60 void mouseMoveEvent(QMouseEvent *event) override;
60 void mouseReleaseEvent(QMouseEvent *event) override;
61 void mouseReleaseEvent(QMouseEvent *event) override;
62+ void mouseDoubleClickEvent(QMouseEvent *event) override;
61private:
63private:
62 static void defaultTouchEventHandler(QTouchEvent *event);
64 static void defaultTouchEventHandler(QTouchEvent *event);
63 static void defaultMouseEventHandler(QMouseEvent *event);
65 static void defaultMouseEventHandler(QMouseEvent *event);
tests/plugins/Ubuntu/Gestures/tst_TouchDispatcher.cpp+59
@@ -16,6 +16,7 @@
16
16
17#include <QtTest>
17#include <QtTest>
18#include <QQuickView>
18#include <QQuickView>
19+#include <QStyleHints>
19
20
20#include "GestureTest.h"
21#include "GestureTest.h"
21
22
@@ -29,6 +30,8 @@ public:
29private Q_SLOTS:
30private Q_SLOTS:
30 void sendMouseEventIfTouchIgnored_data();
31 void sendMouseEventIfTouchIgnored_data();
31 void sendMouseEventIfTouchIgnored();
32 void sendMouseEventIfTouchIgnored();
33+ void mouseDoubleClick_data();
34+ void mouseDoubleClick();
32};
35};
33
36
34tst_TouchDispatcher::tst_TouchDispatcher()
37tst_TouchDispatcher::tst_TouchDispatcher()
@@ -85,6 +88,62 @@ void tst_TouchDispatcher::sendMouseEventIfTouchIgnored()
85 QCOMPARE(gotMousePressEvent, shouldGetMousePress);
88 QCOMPARE(gotMousePressEvent, shouldGetMousePress);
86}
89}
87
90
91+void tst_TouchDispatcher::mouseDoubleClick_data()
92+{
93+ QTest::addColumn<ulong>("timeBetweenClicks");
94+ QTest::addColumn<bool>("shouldSendDoubleClick");
95+
96+ QTest::newRow("double click") << static_cast<ulong>(qApp->styleHints()->mouseDoubleClickInterval() / 10) << true;
97+ QTest::newRow("two separate clicks") << static_cast<ulong>(qApp->styleHints()->mouseDoubleClickInterval() * 2) << false;
98+}
99+
100+void tst_TouchDispatcher::mouseDoubleClick()
101+{
102+ QFETCH(ulong, timeBetweenClicks);
103+ QFETCH(bool, shouldSendDoubleClick);
104+ DummyItem *dummyItem = new DummyItem(m_view->rootObject());
105+ dummyItem->setAcceptedMouseButtons(Qt::LeftButton);
106+
107+ TouchDispatcher touchDispatcher;
108+ touchDispatcher.setTargetItem(dummyItem);
109+
110+ bool gotDoubleClickEvent = false;
111+ dummyItem->mouseDoubleClickEventHandler = [&](QMouseEvent *event) {
112+ gotDoubleClickEvent = true;
113+ event->accept();
114+ };
115+
116+ dummyItem->touchEventHandler = [&](QTouchEvent *event) {
117+ event->ignore();
118+ };
119+
120+ ulong doubleClickInterval = static_cast<ulong>(qApp->styleHints()->mouseDoubleClickInterval());
121+
122+ QList<QTouchEvent::TouchPoint> touchPoints;
123+ {
124+ QTouchEvent::TouchPoint touchPoint;
125+ touchPoint.setId(0);
126+ touchPoint.setState(Qt::TouchPointPressed);
127+ touchPoints.append(touchPoint);
128+ }
129+ ulong timestamp = 12345;
130+
131+ touchDispatcher.dispatch(QEvent::TouchBegin, m_device, Qt::NoModifier, touchPoints, m_view, timestamp);
132+
133+ touchPoints[0].setState(Qt::TouchPointReleased);
134+ timestamp += doubleClickInterval / 10;
135+
136+ touchDispatcher.dispatch(QEvent::TouchEnd, m_device, Qt::NoModifier, touchPoints, m_view, timestamp);
137+
138+ touchPoints[0].setId(1);
139+ touchPoints[0].setState(Qt::TouchPointPressed);
140+ timestamp += timeBetweenClicks;
141+
142+ touchDispatcher.dispatch(QEvent::TouchBegin, m_device, Qt::NoModifier, touchPoints, m_view, timestamp);
143+
144+ QCOMPARE(gotDoubleClickEvent, shouldSendDoubleClick);
145+}
146+
88QTEST_MAIN(tst_TouchDispatcher)
147QTEST_MAIN(tst_TouchDispatcher)
89
148
90#include "tst_TouchDispatcher.moc"
149#include "tst_TouchDispatcher.moc"