on xenial help sign in
TouchDispatcher: synthesize MouseButtonDblClick events
commit19dc3da8dad210c0b51d3d7ab1957c4465028b09 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateMon 3 Nov 2014, 13:21 (12 years ago) parentc735225
6 files changed+114−1
libs/UbuntuGestures/DebugHelpers.cpp+1−1 plugins/Ubuntu/Gestures/TouchDispatcher.cpp+43 plugins/Ubuntu/Gestures/TouchDispatcher.h+3 tests/plugins/Ubuntu/Gestures/GestureTest.cpp+6 tests/plugins/Ubuntu/Gestures/GestureTest.h+2 tests/plugins/Ubuntu/Gestures/tst_TouchDispatcher.cpp+59
libs/UbuntuGestures/DebugHelpers.cpp+1−1
@@ -83,7 +83,7 @@ QString mouseEventToString(const QMouseEvent *ev)
8383 message.append("MouseButtonDblClick ");
8484 break;
8585 case QEvent::MouseMove:
86− message.append("MouseButtonMove ");
86+ message.append("MouseMove ");
8787 break;
8888 default:
8989 message.append("INVALID_MOUSE_EVENT_TYPE ");
plugins/Ubuntu/Gestures/TouchDispatcher.cpp+43
@@ -16,7 +16,9 @@
1616
1717#include "TouchDispatcher.h"
1818
19+#include <QGuiApplication>
1920#include <QScopedPointer>
21+#include <QStyleHints>
2022
2123#pragma GCC diagnostic push
2224#pragma GCC diagnostic ignored "-pedantic"
@@ -32,6 +34,7 @@
3234TouchDispatcher::TouchDispatcher()
3335 : m_status(NoActiveTouch)
3436 , m_touchMouseId(-1)
37+ , m_touchMousePressTimestamp(0)
3538{
3639}
3740
@@ -148,6 +151,18 @@ void TouchDispatcher::dispatchTouchBegin(
148151 #endif
149152 m_status = DeliveringMouseEvents;
150153 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+
151166 } else {
152167 #if TOUCHDISPATCHER_DEBUG
153168 qDebug() << "[TouchDispatcher] Item rejected the QMouseEvent.";
@@ -322,3 +337,31 @@ QMouseEvent *TouchDispatcher::touchToMouseEvent(
322337 //QGuiApplicationPrivate::setMouseEventSource(me, Qt::MouseEventSynthesizedByQt);
323338 return me;
324339}
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:
7171 QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p,
7272 ulong timestamp, Qt::KeyboardModifiers modifiers, bool transformNeeded = true);
7373
74+ bool checkIfDoubleClicked(ulong newPressEventTimestamp);
75+
7476 QPointer<QQuickItem> m_targetItem;
7577
7678 enum {
@@ -81,6 +83,7 @@ private:
8183 } m_status;
8284
8385 int m_touchMouseId;
86+ ulong m_touchMousePressTimestamp;
8487};
8588
8689#endif // UBUNTU_TOUCH_DISPATCHER_H
tests/plugins/Ubuntu/Gestures/GestureTest.cpp+6
@@ -90,6 +90,7 @@ DummyItem::DummyItem(QQuickItem *parent)
9090 mousePressEventHandler = defaultMouseEventHandler;
9191 mouseMoveEventHandler = defaultMouseEventHandler;
9292 mouseReleaseEventHandler = defaultMouseEventHandler;
93+ mouseDoubleClickEventHandler = defaultMouseEventHandler;
9394}
9495
9596void DummyItem::touchEvent(QTouchEvent *event)
@@ -113,6 +114,11 @@ void DummyItem::mouseReleaseEvent(QMouseEvent *event)
113114 mouseReleaseEventHandler(event);
114115}
115116
117+void DummyItem::mouseDoubleClickEvent(QMouseEvent *event)
118+{
119+ mouseDoubleClickEventHandler(event);
120+}
121+
116122void DummyItem::defaultTouchEventHandler(QTouchEvent *event)
117123{
118124 event->accept();
tests/plugins/Ubuntu/Gestures/GestureTest.h+2
@@ -52,12 +52,14 @@ public:
5252 std::function<void(QMouseEvent*)> mousePressEventHandler;
5353 std::function<void(QMouseEvent*)> mouseMoveEventHandler;
5454 std::function<void(QMouseEvent*)> mouseReleaseEventHandler;
55+ std::function<void(QMouseEvent*)> mouseDoubleClickEventHandler;
5556protected:
5657 void touchEvent(QTouchEvent *event) override;
5758
5859 void mousePressEvent(QMouseEvent *event) override;
5960 void mouseMoveEvent(QMouseEvent *event) override;
6061 void mouseReleaseEvent(QMouseEvent *event) override;
62+ void mouseDoubleClickEvent(QMouseEvent *event) override;
6163private:
6264 static void defaultTouchEventHandler(QTouchEvent *event);
6365 static void defaultMouseEventHandler(QMouseEvent *event);
tests/plugins/Ubuntu/Gestures/tst_TouchDispatcher.cpp+59
@@ -16,6 +16,7 @@
1616
1717#include <QtTest>
1818#include <QQuickView>
19+#include <QStyleHints>
1920
2021#include "GestureTest.h"
2122
@@ -29,6 +30,8 @@ public:
2930private Q_SLOTS:
3031 void sendMouseEventIfTouchIgnored_data();
3132 void sendMouseEventIfTouchIgnored();
33+ void mouseDoubleClick_data();
34+ void mouseDoubleClick();
3235};
3336
3437tst_TouchDispatcher::tst_TouchDispatcher()
@@ -85,6 +88,62 @@ void tst_TouchDispatcher::sendMouseEventIfTouchIgnored()
8588 QCOMPARE(gotMousePressEvent, shouldGetMousePress);
8689}
8790
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+
88147QTEST_MAIN(tst_TouchDispatcher)
89148
90149#include "tst_TouchDispatcher.moc"