Merge lp:~zsombi/ubuntu-ui-toolkit/fixTouchAdaptor into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Merged
Approved by: Cris Dywan
Approved revision: 1934
Merged at revision: 1925
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/fixTouchAdaptor
Merge into: lp:ubuntu-ui-toolkit/staging
Diff against target: 1388 lines (+656/-425)
19 files modified
debian/control (+3/-0)
debian/libubuntutoolkit5-dev.install (+2/-0)
src/Ubuntu/Test/plugin/plugin.pri (+3/-5)
src/Ubuntu/Test/plugin/testplugin.cpp (+3/-11)
src/Ubuntu/Test/plugin/uctestextras.cpp (+7/-23)
src/Ubuntu/Test/plugin/uctestextras.h (+0/-1)
src/Ubuntu/UbuntuToolkit/UbuntuToolkit.pro (+13/-3)
src/Ubuntu/UbuntuToolkit/mousetouchadaptor.cpp (+71/-131)
src/Ubuntu/UbuntuToolkit/mousetouchadaptor.h (+27/-24)
src/Ubuntu/UbuntuToolkit/mousetouchadaptor_p.h (+77/-0)
src/Ubuntu/UbuntuToolkit/mousetouchadaptor_x11.cpp (+350/-0)
tests/autopilot/ubuntuuitoolkit/tests/test_touchadaptor.py (+38/-0)
tests/autopilot/ubuntuuitoolkit/tests/test_touchadaptor.qml (+51/-0)
tests/unit_x11/tst_components/tst_adaptivepagelayout.qml (+1/-0)
ubuntu-sdk.pro (+4/-1)
ubuntu-ui-toolkit-launcher/MouseTouchAdaptor.cpp (+0/-159)
ubuntu-ui-toolkit-launcher/MouseTouchAdaptor.h (+0/-50)
ubuntu-ui-toolkit-launcher/launcher.cpp (+3/-12)
ubuntu-ui-toolkit-launcher/ubuntu-ui-toolkit-launcher.pro (+3/-5)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/fixTouchAdaptor
Reviewer Review Type Date Requested Status
ubuntu-sdk-build-bot continuous-integration Approve
Cris Dywan Approve
Review via email: mp+290858@code.launchpad.net

Commit message

Move MouseTouchAdaptor into UbuntuToolkit library. Fix adaptor code for Xenial.

To post a comment you must log in.
1924. By Zsombor Egri

missing license header added

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
1925. By Zsombor Egri

revert unwanted change

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
1926. By Zsombor Egri

add missing headers

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
1927. By Zsombor Egri

build dependenci to drive UbuntuToolkit lib to be built first

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
1928. By Zsombor Egri

wrapped and sorted

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

Is the XCB 1.9.3 struct ABI specific to Qt's use or XCB itself? Is there any way to check that it's correct, either by Debian dependencies, or compile guards? Or some uni test that sanity-checks the value? Or a warning if the struct looks funny? Maybe there's no good way to handle this, just thinking out loud here.

Also it seems redundant to issue "MouseTouchAdaptor not available on this architecture" in setEnabled when it's always issued from registerTouchDevices regardless of the platform guards. A test case for this would seem useful also because despite "indirect" test coverage immediate failures would be much clearer than unexpected funny results.
Maybe even remove the touchDevices() function from the launcher to avoid false-positives because we have duplicate checks of the touch device? Though that last one could also be a separate mini MR.

review: Needs Information
1929. By Zsombor Egri

staging sync

1930. By Zsombor Egri

load page synchronously if that's what we want to test

Revision history for this message
Zsombor Egri (zsombi) wrote :

> Is the XCB 1.9.3 struct ABI specific to Qt's use or XCB itself? Is there any
> way to check that it's correct, either by Debian dependencies, or compile
> guards? Or some uni test that sanity-checks the value? Or a warning if the
> struct looks funny? Maybe there's no good way to handle this, just thinking
> out loud here.

That's a good question, I haven't seen any version check in Unity8 either... would be good though if we could at least guard the package...

>
> Also it seems redundant to issue "MouseTouchAdaptor not available on this
> architecture" in setEnabled when it's always issued from registerTouchDevices
> regardless of the platform guards. A test case for this would seem useful also
> because despite "indirect" test coverage immediate failures would be much
> clearer than unexpected funny results.
> Maybe even remove the touchDevices() function from the launcher to avoid
> false-positives because we have duplicate checks of the touch device? Though
> that last one could also be a separate mini MR.

I was thinking to flag out completely the use of the MouseTouchAdaptor, but then QML code would fail if the API would not be available on certain architectures... However as long as we keep X11 tests separate from the rest, those will not run on ARM....

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
1931. By Zsombor Egri

add autopilot test guarding mouse to touch conversion

1932. By Zsombor Egri

remove touch device detection from launcher; warn if touch simulation is not available on the platform in constructor, and initialize native event listener only for the valid platforms

1933. By Zsombor Egri

staging sync

Revision history for this message
Cris Dywan (kalikiana) wrote :

You need to set mouseEnabled: false on the MultiPointTouchArea for this test to work - otherwise it succeeds even if the touch emulation is not happening, such as can be seen by removing the -touch argument from the test case.

review: Needs Fixing
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
1934. By Zsombor Egri

disable mouse handling on MPTA

Revision history for this message
Cris Dywan (kalikiana) wrote :

Sweet. Thanks for the AP test and cleaning up the conditionals!

review: Approve
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2016-03-24 09:14:57 +0000
3+++ debian/control 2016-04-07 16:01:36 +0000
4@@ -22,6 +22,9 @@
5 libqt5sql5-sqlite,
6 libqt5svg5-dev,
7 libudev-dev,
8+ libx11-dev[!armhf],
9+ libxcb1-dev[!armhf],
10+ libxi-dev[!armhf],
11 libxkbcommon-dev,
12 libxrender-dev,
13 locales,
14
15=== modified file 'debian/libubuntutoolkit5-dev.install'
16--- debian/libubuntutoolkit5-dev.install 2016-03-04 11:58:12 +0000
17+++ debian/libubuntutoolkit5-dev.install 2016-04-07 16:01:36 +0000
18@@ -1,11 +1,13 @@
19 usr/include/*/qt5/UbuntuToolkit/AsyncLoader
20 usr/include/*/qt5/UbuntuToolkit/ColorUtils
21+usr/include/*/qt5/UbuntuToolkit/MouseTouchAdaptor
22 usr/include/*/qt5/UbuntuToolkit/Tree
23 usr/include/*/qt5/UbuntuToolkit/UbuntuToolkit
24 usr/include/*/qt5/UbuntuToolkit/UbuntuToolkitDepends
25 usr/include/*/qt5/UbuntuToolkit/UbuntuToolkitVersion
26 usr/include/*/qt5/UbuntuToolkit/asyncloader.h
27 usr/include/*/qt5/UbuntuToolkit/colorutils.h
28+usr/include/*/qt5/UbuntuToolkit/mousetouchadaptor.h
29 usr/include/*/qt5/UbuntuToolkit/tree.h
30 usr/include/*/qt5/UbuntuToolkit/ubuntutoolkitglobal.h
31 usr/include/*/qt5/UbuntuToolkit/ubuntutoolkitversion.h
32
33=== modified file 'src/Ubuntu/Test/plugin/plugin.pri'
34--- src/Ubuntu/Test/plugin/plugin.pri 2016-02-25 02:29:05 +0000
35+++ src/Ubuntu/Test/plugin/plugin.pri 2016-04-07 16:01:36 +0000
36@@ -1,4 +1,4 @@
37-QT *= core-private qml qml-private quick quick-private gui-private testlib UbuntuGestures
38+QT *= core-private qml qml-private quick quick-private gui-private testlib UbuntuGestures UbuntuToolkit
39
40 equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) {
41 QT *= v8-private
42@@ -15,11 +15,9 @@
43 HEADERS += \
44 $$PWD/uctestcase.h \
45 $$PWD/testplugin.h \
46- $$PWD/uctestextras.h \
47- $$PWD/ucmousetouchadaptor.h \
48+ $$PWD/uctestextras.h
49
50 SOURCES += \
51 $$PWD/uctestcase.cpp \
52 $$PWD/testplugin.cpp \
53- $$PWD/uctestextras.cpp \
54- $$PWD/ucmousetouchadaptor.cpp \
55+ $$PWD/uctestextras.cpp
56
57=== modified file 'src/Ubuntu/Test/plugin/testplugin.cpp'
58--- src/Ubuntu/Test/plugin/testplugin.cpp 2015-10-21 08:33:21 +0000
59+++ src/Ubuntu/Test/plugin/testplugin.cpp 2016-04-07 16:01:36 +0000
60@@ -1,5 +1,5 @@
61 /*
62- * Copyright 2014 Canonical Ltd.
63+ * Copyright 2016 Canonical Ltd.
64 *
65 * This program is free software; you can redistribute it and/or modify
66 * it under the terms of the GNU Lesser General Public License as published by
67@@ -17,7 +17,7 @@
68 #include "testplugin.h"
69 #include <QtQml>
70 #include "uctestextras.h"
71-#include "ucmousetouchadaptor.h"
72+#include <MouseTouchAdaptor>
73
74 static QObject *registerExtras(QQmlEngine *engine, QJSEngine *scriptEngine)
75 {
76@@ -27,16 +27,8 @@
77 return new UCTestExtras;
78 }
79
80-static QObject *registerAdaptor(QQmlEngine *engine, QJSEngine *scriptEngine)
81-{
82- Q_UNUSED(engine)
83- Q_UNUSED(scriptEngine)
84-
85- return new UCMouseTouchAdaptor;
86-}
87-
88 void TestPlugin::registerTypes(const char *uri)
89 {
90 qmlRegisterSingletonType<UCTestExtras>(uri, 1, 0, "TestExtras", registerExtras);
91- qmlRegisterSingletonType<UCMouseTouchAdaptor>(uri, 1, 0, "MouseTouchAdaptor", registerAdaptor);
92+ qmlRegisterSingletonType<UbuntuToolkit::MouseTouchAdaptor>(uri, 1, 0, "MouseTouchAdaptor", UbuntuToolkit::MouseTouchAdaptor::registerQmlSingleton);
93 }
94
95=== modified file 'src/Ubuntu/Test/plugin/uctestextras.cpp'
96--- src/Ubuntu/Test/plugin/uctestextras.cpp 2015-12-17 15:23:26 +0000
97+++ src/Ubuntu/Test/plugin/uctestextras.cpp 2016-04-07 16:01:36 +0000
98@@ -1,5 +1,5 @@
99 /*
100- * Copyright 2014 Canonical Ltd.
101+ * Copyright 2016 Canonical Ltd.
102 *
103 * This program is free software; you can redistribute it and/or modify
104 * it under the terms of the GNU Lesser General Public License as published by
105@@ -23,6 +23,7 @@
106 #include <qpa/qwindowsysteminterface.h>
107 #include <private/qobject_p.h>
108 #include <QSysInfo>
109+#include <MouseTouchAdaptor>
110
111 const char *DEVICE_MISSING_MSG = "No touch device registered. Register one using registerTouchDevice() before using %1";
112
113@@ -40,7 +41,6 @@
114 return; \
115 }
116
117-QTouchDevice *UCTestExtras::m_touchDevice = 0;
118 UCTestExtras *UCTestExtras::m_testExtras = 0;
119
120 /*!
121@@ -118,24 +118,8 @@
122 */
123 void UCTestExtras::registerTouchDevice()
124 {
125- // check if there is any touch device registered in the system
126- if (!m_touchDevice) {
127- QList<const QTouchDevice*> touchDevices = QTouchDevice::devices();
128- Q_FOREACH(const QTouchDevice *device, touchDevices) {
129- if (device->type() == QTouchDevice::TouchScreen) {
130- m_touchDevice = const_cast<QTouchDevice*>(device);
131- break;
132- }
133- }
134- }
135- // if none, register one
136- if (!m_touchDevice) {
137- m_touchDevice = new QTouchDevice;
138- m_touchDevice->setType(QTouchDevice::TouchScreen);
139- QWindowSystemInterface::registerTouchDevice(m_touchDevice);
140- if (m_testExtras) {
141- Q_EMIT m_testExtras->touchDevicePresentChanged();
142- }
143+ if (UbuntuToolkit::MouseTouchAdaptor::registerTouchDevice() && m_testExtras) {
144+ Q_EMIT m_testExtras->touchDevicePresentChanged();
145 }
146 }
147
148@@ -148,7 +132,7 @@
149 void UCTestExtras::touchPress(int touchId, QQuickItem *item, const QPoint &point)
150 {
151 CHECK_TOUCH_DEVICE(touchId, item);
152- QTest::touchEvent(item->window(), m_touchDevice).press(touchId, item->mapToScene(point).toPoint(), item->window());
153+ QTest::touchEvent(item->window(), UbuntuToolkit::MouseTouchAdaptor::touchDevice()).press(touchId, item->mapToScene(point).toPoint(), item->window());
154 }
155 /*!
156 * \qmlmethod TestExtras::touchRelease(touchId, item, point)
157@@ -158,7 +142,7 @@
158 void UCTestExtras::touchRelease(int touchId, QQuickItem *item, const QPoint &point)
159 {
160 CHECK_TOUCH_DEVICE(touchId, item);
161- QTest::touchEvent(item->window(), m_touchDevice).release(touchId, item->mapToScene(point).toPoint(), item->window());
162+ QTest::touchEvent(item->window(), UbuntuToolkit::MouseTouchAdaptor::touchDevice()).release(touchId, item->mapToScene(point).toPoint(), item->window());
163 }
164 /*!
165 * \qmlmethod TestExtras::touchClick(touchId, item, point)
166@@ -207,7 +191,7 @@
167 void UCTestExtras::touchMove(int touchId, QQuickItem *item, const QPoint &point)
168 {
169 CHECK_TOUCH_DEVICE(touchId, item);
170- QTest::touchEvent(item->window(), m_touchDevice).move(touchId, item->mapToScene(point).toPoint(), item->window());
171+ QTest::touchEvent(item->window(), UbuntuToolkit::MouseTouchAdaptor::touchDevice()).move(touchId, item->mapToScene(point).toPoint(), item->window());
172 }
173 /*!
174 * \qmlmethod TestExtras::touchDrag(touchId, item, from, delta, steps = 5)
175
176=== modified file 'src/Ubuntu/Test/plugin/uctestextras.h'
177--- src/Ubuntu/Test/plugin/uctestextras.h 2015-12-17 14:42:40 +0000
178+++ src/Ubuntu/Test/plugin/uctestextras.h 2016-04-07 16:01:36 +0000
179@@ -53,7 +53,6 @@
180 static void mouseDragWithPoints(QQuickItem *item, QList<QPoint> points, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, int delay = -1);
181
182 private:
183- static QTouchDevice *m_touchDevice;
184 static UCTestExtras *m_testExtras;
185
186 friend class UCMouseTouchAdaptor;
187
188=== modified file 'src/Ubuntu/UbuntuToolkit/UbuntuToolkit.pro'
189--- src/Ubuntu/UbuntuToolkit/UbuntuToolkit.pro 2016-02-25 14:35:59 +0000
190+++ src/Ubuntu/UbuntuToolkit/UbuntuToolkit.pro 2016-04-07 16:01:36 +0000
191@@ -1,7 +1,14 @@
192 TEMPLATE=lib
193 TARGET=UbuntuToolkit
194
195-QT *= core-private gui-private qml qml-private quick quick-private
196+QT *= core-private gui-private qml qml-private quick quick-private testlib
197+
198+!contains(QT_ARCH, arm) {
199+ DEFINES += UBUNTUTOOLKIT_ENABLE_X11_TOUCH_EMULATION
200+ LIBS += -lX11 -lxcb -lXi
201+
202+ SOURCES += mousetouchadaptor_x11.cpp
203+}
204
205 CONFIG += dll no_keywords c++11
206
207@@ -17,9 +24,12 @@
208 ubuntutoolkitglobal.h \
209 tree.h \
210 asyncloader.h \
211- asyncloader_p.h
212+ asyncloader_p.h \
213+ mousetouchadaptor.h \
214+ mousetouchadaptor_p.h
215
216 SOURCES += \
217 colorutils.cpp \
218 tree.cpp \
219- asyncloader.cpp
220+ asyncloader.cpp \
221+ mousetouchadaptor.cpp
222
223=== renamed file 'src/Ubuntu/Test/plugin/ucmousetouchadaptor.cpp' => 'src/Ubuntu/UbuntuToolkit/mousetouchadaptor.cpp'
224--- src/Ubuntu/Test/plugin/ucmousetouchadaptor.cpp 2015-11-10 14:42:20 +0000
225+++ src/Ubuntu/UbuntuToolkit/mousetouchadaptor.cpp 2016-04-07 16:01:36 +0000
226@@ -1,5 +1,5 @@
227 /*
228- * Copyright (C) 2013,2015 Canonical, Ltd.
229+ * Copyright (C) 2013,2016 Canonical, Ltd.
230 *
231 * This program is free software; you can redistribute it and/or modify
232 * it under the terms of the GNU General Public License as published by
233@@ -14,36 +14,34 @@
234 * along with this program. If not, see <http://www.gnu.org/licenses/>.
235 *
236 * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
237+ * Zsombor Egri <zsomboir.egri@canonical.com>
238 */
239
240-#include "ucmousetouchadaptor.h"
241-#include "uctestextras.h"
242+#include "mousetouchadaptor_p.h"
243
244+#include <qpa/qplatformnativeinterface.h>
245 #include <qpa/qwindowsysteminterface.h>
246
247 #include <QCoreApplication>
248 #include <QMouseEvent>
249 #include <QTest>
250
251-using QTest::QTouchEventSequence;
252-
253-namespace {
254-
255-Qt::MouseButton translateMouseButton(xcb_button_t detail)
256+#ifdef UBUNTUTOOLKIT_ENABLE_X11_TOUCH_EMULATION
257+ #define ENABLE_TOUCH_EMULATION
258+#endif
259+
260+namespace UbuntuToolkit {
261+
262+QTouchDevice *MouseTouchAdaptor::m_touchDevice = nullptr;
263+
264+MouseTouchAdaptorPrivate::~MouseTouchAdaptorPrivate()
265 {
266- switch (detail) {
267- case 1: return Qt::LeftButton;
268- case 2: return Qt::MidButton;
269- case 3: return Qt::RightButton;
270- // Button values 4-7 are Wheel events
271- default: return Qt::NoButton;
272- }
273+ QCoreApplication::instance()->removeNativeEventFilter(this);
274 }
275-} // end of anonymous namespace
276
277 /*!
278 * \qmltype MouseTouchAdaptor
279- * \instantiates UCMouseTouchAdaptor
280+ * \instantiates MouseTouchAdaptor
281 * \inqmlmodule Ubuntu.Test 1.0
282 * \ingroup ubuntu-test
283 * \brief Singleton type turning mouse events into single finger touch events.
284@@ -60,109 +58,49 @@
285 * \endqml
286 *
287 */
288-UCMouseTouchAdaptor::UCMouseTouchAdaptor()
289- : QObject(nullptr)
290- , m_leftButtonIsPressed(false)
291- , m_enabled(true)
292-{
293- QCoreApplication::instance()->installNativeEventFilter(this);
294-
295- UCTestExtras::registerTouchDevice();
296- m_touchDevice = UCTestExtras::m_touchDevice;
297-}
298-
299-bool UCMouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType,
300- void * message, long * /*result*/)
301-{
302- if (!m_enabled) {
303- return false;
304- }
305-
306- if (eventType != "xcb_generic_event_t") {
307- // wrong backend.
308- qWarning("MouseTouchAdaptor: XCB backend not in use. Adaptor inoperative!");
309- return false;
310- }
311-
312- xcb_generic_event_t *xcbEvent = static_cast<xcb_generic_event_t *>(message);
313-
314- switch (xcbEvent->response_type & ~0x80) {
315- case XCB_BUTTON_PRESS:
316- return handleButtonPress(reinterpret_cast<xcb_button_press_event_t *>(xcbEvent));
317- break;
318- case XCB_BUTTON_RELEASE:
319- return handleButtonRelease(reinterpret_cast<xcb_button_release_event_t *>(xcbEvent));
320- break;
321- case XCB_MOTION_NOTIFY:
322- return handleMotionNotify(reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent));
323- break;
324- default:
325- return false;
326- break;
327- };
328-}
329-
330-bool UCMouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
331-{
332- Qt::MouseButton button = translateMouseButton(pressEvent->detail);
333-
334- // Just eat the event if it wasn't a left mouse press
335- if (button != Qt::LeftButton)
336- return true;
337-
338- QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
339-
340- QPoint windowPos(pressEvent->event_x / targetWindow->devicePixelRatio(), pressEvent->event_y / targetWindow->devicePixelRatio());
341-
342- QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
343- false /* autoCommit */);
344- touchEvent.press(0 /* touchId */, windowPos);
345- touchEvent.commit(false /* processEvents */);
346-
347- m_leftButtonIsPressed = true;
348- return true;
349-}
350-
351-bool UCMouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseEvent)
352-{
353- Qt::MouseButton button = translateMouseButton(releaseEvent->detail);
354-
355- // Just eat the event if it wasn't a left mouse release
356- if (button != Qt::LeftButton)
357- return true;
358-
359- QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
360-
361- QPoint windowPos(releaseEvent->event_x / targetWindow->devicePixelRatio(), releaseEvent->event_y / targetWindow->devicePixelRatio());
362-
363- QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
364- false /* autoCommit */);
365- touchEvent.release(0 /* touchId */, windowPos);
366- touchEvent.commit(false /* processEvents */);
367-
368- m_leftButtonIsPressed = false;
369- return true;
370-}
371-
372-bool UCMouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event)
373-{
374- if (!m_leftButtonIsPressed) {
375- return true;
376- }
377-
378- QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
379-
380- QPoint windowPos(event->event_x / targetWindow->devicePixelRatio(), event->event_y / targetWindow->devicePixelRatio());
381-
382- QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
383- false /* autoCommit */);
384- touchEvent.move(0 /* touchId */, windowPos);
385- touchEvent.commit(false /* processEvents */);
386-
387- return true;
388-}
389-
390-QWindow *UCMouseTouchAdaptor::findQWindowWithXWindowID(WId windowId)
391+MouseTouchAdaptor::MouseTouchAdaptor(QObject *parent)
392+ :
393+#ifdef UBUNTUTOOLKIT_ENABLE_X11_TOUCH_EMULATION
394+ QObject(*(new X11MouseTouchAdaptorPrivate), parent)
395+#else
396+ QObject(*(new MouseTouchAdaptorPrivate), parent)
397+#endif
398+{
399+#ifdef ENABLE_TOUCH_EMULATION
400+ registerTouchDevice();
401+#else
402+ qWarning() << "MouseTouchAdaptor not available on this architecture.";
403+#endif
404+ Q_D(MouseTouchAdaptor);
405+ d->init();
406+}
407+
408+// registers a test touch device, returns true if a device was found/registered
409+bool MouseTouchAdaptor::registerTouchDevice()
410+{
411+ // check if there is any touch device registered in the system
412+ if (!m_touchDevice) {
413+ QList<const QTouchDevice*> touchDevices = QTouchDevice::devices();
414+ Q_FOREACH(const QTouchDevice *device, touchDevices) {
415+ if (device->type() == QTouchDevice::TouchScreen) {
416+ m_touchDevice = const_cast<QTouchDevice*>(device);
417+ return true;
418+ }
419+ }
420+ }
421+ // if none, register one
422+#ifdef ENABLE_TOUCH_EMULATION
423+ if (!m_touchDevice) {
424+ m_touchDevice = new QTouchDevice;
425+ m_touchDevice->setType(QTouchDevice::TouchScreen);
426+ QWindowSystemInterface::registerTouchDevice(m_touchDevice);
427+ return true;
428+ }
429+#endif
430+ return false;
431+}
432+
433+QWindow *MouseTouchAdaptorPrivate::findQWindowWithXWindowID(WId windowId)
434 {
435 QWindowList windowList = QGuiApplication::topLevelWindows();
436 QWindow *foundWindow = nullptr;
437@@ -185,14 +123,16 @@
438 * \qmlproperty bool MouseTouchAdaptor::enabled
439 * Enables the mouse to touch conversion functionality. Defaults to true.
440 */
441-bool UCMouseTouchAdaptor::enabled() const
442-{
443- return m_enabled;
444-}
445-void UCMouseTouchAdaptor::setEnabled(bool value)
446-{
447- if (value != m_enabled) {
448- m_enabled = value;
449- Q_EMIT enabledChanged(value);
450- }
451-}
452+bool MouseTouchAdaptorPrivate::isEnabled() const
453+{
454+ return enabled;
455+}
456+void MouseTouchAdaptorPrivate::setEnabled(bool value)
457+{
458+ Q_UNUSED(value);
459+ qWarning() << "MouseTouchAdaptor not available on this architecture, thus cannot be enabled.";
460+}
461+
462+} // namespace UbuntuToolkit
463+
464+#include "moc_mousetouchadaptor.cpp"
465
466=== renamed file 'src/Ubuntu/Test/plugin/ucmousetouchadaptor.h' => 'src/Ubuntu/UbuntuToolkit/mousetouchadaptor.h'
467--- src/Ubuntu/Test/plugin/ucmousetouchadaptor.h 2015-10-21 08:33:21 +0000
468+++ src/Ubuntu/UbuntuToolkit/mousetouchadaptor.h 2016-04-07 16:01:36 +0000
469@@ -1,5 +1,5 @@
470 /*
471- * Copyright (C) 2013,2015 Canonical, Ltd.
472+ * Copyright (C) 2013,2016 Canonical, Ltd.
473 *
474 * This program is free software; you can redistribute it and/or modify
475 * it under the terms of the GNU General Public License as published by
476@@ -14,47 +14,50 @@
477 * along with this program. If not, see <http://www.gnu.org/licenses/>.
478 *
479 * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
480+ * Zsombor Egri <zsomboir.egri@canonical.com>
481 */
482
483 #ifndef MOUSE_TOUCH_ADAPTOR_H
484 #define MOUSE_TOUCH_ADAPTOR_H
485
486-#include <QtCore/QAbstractNativeEventFilter>
487-#include <QWindow>
488-#include <xcb/xcb.h>
489+#include "ubuntutoolkitglobal.h"
490+
491+#include <QtCore/QObject>
492
493 class QMouseEvent;
494 class QTouchDevice;
495+class QQmlEngine;
496+class QJSEngine;
497+
498+namespace UbuntuToolkit {
499
500 // Transforms QMouseEvents into single-finger QTouchEvents.
501-class UCMouseTouchAdaptor : public QObject, public QAbstractNativeEventFilter
502+class MouseTouchAdaptorPrivate;
503+class UBUNTUTOOLKIT_EXPORT MouseTouchAdaptor : public QObject
504 {
505 Q_OBJECT
506+ Q_PRIVATE_PROPERTY(MouseTouchAdaptor::d_func(), bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
507 public:
508- UCMouseTouchAdaptor();
509-
510- // Filters mouse events and posts the equivalent QTouchEvents.
511- bool nativeEventFilter(const QByteArray & eventType, void *message, long *result) override;
512-
513- Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
514-
515- bool enabled() const;
516- void setEnabled(bool value);
517+ explicit MouseTouchAdaptor(QObject *parent = Q_NULLPTR);
518+
519+ static bool registerTouchDevice();
520+ inline static QTouchDevice *touchDevice()
521+ {
522+ return m_touchDevice;
523+ }
524+ static QObject *registerQmlSingleton(QQmlEngine*, QJSEngine*)
525+ {
526+ return new MouseTouchAdaptor;
527+ }
528
529 Q_SIGNALS:
530 void enabledChanged(bool value);
531
532 private:
533-
534- bool handleButtonPress(xcb_button_press_event_t *pressEvent);
535- bool handleButtonRelease(xcb_button_release_event_t *releaseEvent);
536- bool handleMotionNotify(xcb_motion_notify_event_t *event);
537- QWindow *findQWindowWithXWindowID(WId windowId);
538-
539- QTouchDevice *m_touchDevice;
540- bool m_leftButtonIsPressed;
541-
542- bool m_enabled;
543+ Q_DECLARE_PRIVATE(MouseTouchAdaptor)
544+ static QTouchDevice *m_touchDevice;
545 };
546
547+} // namespace UbuntuToolkit
548+
549 #endif // MOUSE_TOUCH_ADAPTOR_H
550
551=== added file 'src/Ubuntu/UbuntuToolkit/mousetouchadaptor_p.h'
552--- src/Ubuntu/UbuntuToolkit/mousetouchadaptor_p.h 1970-01-01 00:00:00 +0000
553+++ src/Ubuntu/UbuntuToolkit/mousetouchadaptor_p.h 2016-04-07 16:01:36 +0000
554@@ -0,0 +1,77 @@
555+/*
556+ * Copyright (C) 2016 Canonical, Ltd.
557+ *
558+ * This program is free software; you can redistribute it and/or modify
559+ * it under the terms of the GNU General Public License as published by
560+ * the Free Software Foundation; version 3.
561+ *
562+ * This program is distributed in the hope that it will be useful,
563+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
564+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
565+ * GNU General Public License for more details.
566+ *
567+ * You should have received a copy of the GNU General Public License
568+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
569+ *
570+ * Authored by: Zsombor Egri <zsombor.egri@canonical.com>
571+ */
572+
573+#ifndef MOUSETOUCHADAPTOR_P
574+#define MOUSETOUCHADAPTOR_P
575+
576+#include "mousetouchadaptor.h"
577+#include <QtCore/private/qobject_p.h>
578+#include <QtCore/QAbstractNativeEventFilter>
579+#include <QWindow>
580+#include <xcb/xcb.h>
581+
582+namespace UbuntuToolkit {
583+
584+class MouseTouchAdaptorPrivate : public QObjectPrivate, public QAbstractNativeEventFilter
585+{
586+ Q_DECLARE_PUBLIC(MouseTouchAdaptor)
587+public:
588+ MouseTouchAdaptorPrivate() : QObjectPrivate() {}
589+ ~MouseTouchAdaptorPrivate();
590+
591+ virtual void init() {}
592+ virtual bool nativeEventFilter(const QByteArray & eventType, void *message, long *result)
593+ { Q_UNUSED(eventType); Q_UNUSED(message); Q_UNUSED(result); return false; }
594+ bool isEnabled() const;
595+ virtual void setEnabled(bool enabled);
596+
597+ QWindow *findQWindowWithXWindowID(WId windowId);
598+
599+ // fields
600+ bool enabled{false};
601+};
602+
603+#ifdef UBUNTUTOOLKIT_ENABLE_X11_TOUCH_EMULATION
604+class X11MouseTouchAdaptorPrivate : public MouseTouchAdaptorPrivate
605+{
606+ Q_DECLARE_PUBLIC(MouseTouchAdaptor)
607+public:
608+ X11MouseTouchAdaptorPrivate();
609+
610+ void init() Q_DECL_OVERRIDE;
611+ bool nativeEventFilter(const QByteArray & eventType, void *message, long *result) Q_DECL_OVERRIDE;
612+ void setEnabled(bool value);
613+
614+ bool xi2HandleEvent(xcb_ge_event_t *event);
615+ bool handleButtonPress(WId windowId, uint32_t detail, uint32_t modifiers, int x, int y);
616+ bool handleButtonRelease(WId windowId, uint32_t detail, uint32_t modifiers, int x, int y);
617+ bool handleMotionNotify(WId windowId, uint32_t modifiers, int x, int y);
618+
619+ bool m_leftButtonIsPressed;
620+ bool m_triPressModifier;
621+
622+ bool m_xi2Enabled{false};
623+ int m_xi2Minor{-1};
624+ int m_xiOpCode, m_xiEventBase, m_xiErrorBase;
625+};
626+#endif
627+
628+} // namespace UbuntuToolkit
629+
630+#endif // MOUSETOUCHADAPTOR_P
631+
632
633=== added file 'src/Ubuntu/UbuntuToolkit/mousetouchadaptor_x11.cpp'
634--- src/Ubuntu/UbuntuToolkit/mousetouchadaptor_x11.cpp 1970-01-01 00:00:00 +0000
635+++ src/Ubuntu/UbuntuToolkit/mousetouchadaptor_x11.cpp 2016-04-07 16:01:36 +0000
636@@ -0,0 +1,350 @@
637+/*
638+ * Copyright (C) 2016 Canonical, Ltd.
639+ *
640+ * This program is free software; you can redistribute it and/or modify
641+ * it under the terms of the GNU General Public License as published by
642+ * the Free Software Foundation; version 3.
643+ *
644+ * This program is distributed in the hope that it will be useful,
645+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
646+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
647+ * GNU General Public License for more details.
648+ *
649+ * You should have received a copy of the GNU General Public License
650+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
651+ *
652+ * Authored by: Zsombor Egri <zsombor.egri@canonical.com>
653+ */
654+
655+/* Some parts of the code were copied from the XCB platform plugin of the Qt Toolkit,
656+ * which is under the following license:
657+ */
658+
659+/****************************************************************************
660+**
661+** Copyright (C) 2015 The Qt Company Ltd.
662+** Contact: http://www.qt.io/licensing/
663+**
664+** This file is part of the .
665+**
666+** $QT_BEGIN_LICENSE:LGPL21$
667+** Commercial License Usage
668+** Licensees holding valid commercial Qt licenses may use this file in
669+** accordance with the commercial license agreement provided with the
670+** Software or, alternatively, in accordance with the terms contained in
671+** a written agreement between you and The Qt Company. For licensing terms
672+** and conditions see http://www.qt.io/terms-conditions. For further
673+** information use the contact form at http://www.qt.io/contact-us.
674+**
675+** GNU Lesser General Public License Usage
676+** Alternatively, this file may be used under the terms of the GNU Lesser
677+** General Public License version 2.1 or version 3 as published by the Free
678+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
679+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
680+** following information to ensure the GNU Lesser General Public License
681+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
682+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
683+**
684+** As a special exception, The Qt Company gives you certain additional
685+** rights. These rights are described in The Qt Company LGPL Exception
686+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
687+**
688+** $QT_END_LICENSE$
689+**
690+****************************************************************************/
691+
692+#include "mousetouchadaptor_p.h"
693+
694+#include <qpa/qplatformnativeinterface.h>
695+
696+#include <QCoreApplication>
697+#include <QMouseEvent>
698+#include <QTest>
699+
700+#include <X11/extensions/XInput2.h>
701+#include <X11/extensions/XI2proto.h>
702+
703+using QTest::QTouchEventSequence;
704+
705+namespace {
706+
707+const Qt::KeyboardModifiers TRI_PRESS_MODIFIER = Qt::ShiftModifier|Qt::ControlModifier|Qt::AltModifier;
708+
709+Qt::MouseButton translateMouseButton(xcb_button_t detail)
710+{
711+ switch (detail) {
712+ case 1: return Qt::LeftButton;
713+ case 2: return Qt::MidButton;
714+ case 3: return Qt::RightButton;
715+ // Button values 4-7 are Wheel events
716+ default: return Qt::NoButton;
717+ }
718+}
719+
720+Qt::KeyboardModifiers translateMofidier(uint32_t mod)
721+{
722+ Qt::KeyboardModifiers qtMod = Qt::NoModifier;
723+
724+ if (mod & 0x01) qtMod |= Qt::ShiftModifier;
725+ if (mod & 0x04) qtMod |= Qt::ControlModifier;
726+ if (mod & 0x08) qtMod |= Qt::AltModifier;
727+ if (mod & 0x80) qtMod |= Qt::MetaModifier;
728+
729+ return qtMod;
730+}
731+
732+} // end of anonymous namespace
733+
734+
735+namespace UbuntuToolkit {
736+
737+X11MouseTouchAdaptorPrivate::X11MouseTouchAdaptorPrivate()
738+ : m_leftButtonIsPressed(false)
739+ , m_triPressModifier(false)
740+{
741+ enabled = true;
742+}
743+
744+void X11MouseTouchAdaptorPrivate::init()
745+{
746+ QPlatformNativeInterface *nativeInterface = qGuiApp->platformNativeInterface();
747+ Display *xDisplay = static_cast<Display*>(nativeInterface->nativeResourceForIntegration("Display"));
748+ if (xDisplay && XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
749+ int xiMajor = 2;
750+ m_xi2Minor = 2; // try 2.2 first, needed for TouchBegin/Update/End
751+ if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
752+ m_xi2Minor = 1; // for smooth scrolling 2.1 is enough
753+ if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
754+ m_xi2Minor = 0; // for tablet support 2.0 is enough
755+ m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest;
756+ } else
757+ m_xi2Enabled = true;
758+ } else {
759+ m_xi2Enabled = true;
760+ }
761+ }
762+
763+ QCoreApplication::instance()->installNativeEventFilter(this);
764+}
765+
766+void X11MouseTouchAdaptorPrivate::setEnabled(bool value)
767+{
768+ if (value != enabled) {
769+ enabled = value;
770+ Q_EMIT q_func()->enabledChanged(value);
771+ }
772+}
773+
774+// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
775+// - "pad0" became "extension"
776+// - "pad1" and "pad" became "pad0"
777+// New and old version of this struct share the following fields:
778+// NOTE: API might change again in the next release of xcb in which case this comment will
779+// need to be updated to reflect the reality.
780+typedef struct qt_xcb_ge_event_t {
781+ uint8_t response_type;
782+ uint8_t extension;
783+ uint16_t sequence;
784+ uint32_t length;
785+ uint16_t event_type;
786+} qt_xcb_ge_event_t;
787+
788+bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *ev, int opCode)
789+{
790+ qt_xcb_ge_event_t *event = (qt_xcb_ge_event_t *)ev;
791+ // xGenericEvent has "extension" on the second byte, the same is true for xcb_ge_event_t starting from
792+ // the xcb version 1.9.3, prior to that it was called "pad0".
793+ if (event->extension == opCode) {
794+ // xcb event structs contain stuff that wasn't on the wire, the full_sequence field
795+ // adds an extra 4 bytes and generic events cookie data is on the wire right after the standard 32 bytes.
796+ // Move this data back to have the same layout in memory as it was on the wire
797+ // and allow casting, overwriting the full_sequence field.
798+ memmove((char*) event + 32, (char*) event + 36, event->length * 4);
799+ return true;
800+ }
801+ return false;
802+}
803+
804+static inline qreal fixed1616ToReal(FP1616 val)
805+{
806+ return qreal(val) / 0x10000;
807+}
808+
809+bool X11MouseTouchAdaptorPrivate::xi2HandleEvent(xcb_ge_event_t *event)
810+{
811+ if (!xi2PrepareXIGenericDeviceEvent(event, m_xiOpCode)) {
812+ return false;
813+ }
814+
815+ xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
816+ xXIDeviceEvent *xiDeviceEvent = 0;
817+
818+ switch (xiEvent->evtype) {
819+ case XI_ButtonPress:
820+ case XI_ButtonRelease:
821+ case XI_Motion:
822+ xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
823+ break;
824+ default:
825+ break;
826+ }
827+
828+ if (!xiDeviceEvent) {
829+ return false;
830+ }
831+
832+ switch (xiDeviceEvent->evtype) {
833+ case XI_ButtonPress:
834+ return handleButtonPress(
835+ static_cast<WId>(xiDeviceEvent->event),
836+ xiDeviceEvent->detail,
837+ xiDeviceEvent->mods.base_mods,
838+ fixed1616ToReal(xiDeviceEvent->event_x),
839+ fixed1616ToReal(xiDeviceEvent->event_y));
840+ case XI_ButtonRelease:
841+ return handleButtonRelease(
842+ static_cast<WId>(xiDeviceEvent->event),
843+ xiDeviceEvent->detail,
844+ xiDeviceEvent->mods.base_mods,
845+ fixed1616ToReal(xiDeviceEvent->event_x),
846+ fixed1616ToReal(xiDeviceEvent->event_y));
847+ case XI_Motion:
848+ return handleMotionNotify(
849+ static_cast<WId>(xiDeviceEvent->event),
850+ xiDeviceEvent->mods.base_mods,
851+ fixed1616ToReal(xiDeviceEvent->event_x),
852+ fixed1616ToReal(xiDeviceEvent->event_y));
853+ return true;
854+ default:
855+ return false;
856+ }
857+}
858+
859+bool X11MouseTouchAdaptorPrivate::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
860+{
861+ Q_UNUSED(result);
862+ static int eventCount = 0;
863+ eventCount++;
864+ if (!enabled) {
865+ return false;
866+ }
867+
868+ if (eventType != "xcb_generic_event_t") {
869+ // wrong backend.
870+ qWarning("MouseTouchAdaptor: XCB backend not in use. Adaptor inoperative!");
871+ return false;
872+ }
873+
874+ xcb_generic_event_t *xcbEvent = static_cast<xcb_generic_event_t *>(message);
875+
876+ switch (xcbEvent->response_type & ~0x80) {
877+ case XCB_BUTTON_PRESS: {
878+ auto pressEvent = reinterpret_cast<xcb_button_press_event_t *>(xcbEvent);
879+ return handleButtonPress(static_cast<WId>(pressEvent->event), pressEvent->detail, 0,
880+ pressEvent->event_x, pressEvent->event_y);
881+ }
882+ case XCB_BUTTON_RELEASE: {
883+ auto releaseEvent = reinterpret_cast<xcb_button_release_event_t *>(xcbEvent);
884+ return handleButtonRelease(static_cast<WId>(releaseEvent->event), releaseEvent->detail, 0,
885+ releaseEvent->event_x, releaseEvent->event_y);
886+ }
887+ case XCB_MOTION_NOTIFY: {
888+ auto motionEvent = reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent);
889+ return handleMotionNotify(static_cast<WId>(motionEvent->event), 0,
890+ motionEvent->event_x, motionEvent->event_y);
891+ }
892+ case XCB_GE_GENERIC:
893+ if (m_xi2Enabled) {
894+ return xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(xcbEvent));
895+ } else {
896+ return false;
897+ }
898+ default:
899+ return false;
900+ };
901+}
902+
903+bool X11MouseTouchAdaptorPrivate::handleButtonPress(WId windowId, uint32_t detail, uint32_t modifiers, int x, int y)
904+{
905+ Qt::MouseButton button = translateMouseButton(detail);
906+ Qt::KeyboardModifiers qtMod = translateMofidier(modifiers);
907+
908+ // Just eat the event if it wasn't a left mouse press
909+ if (button != Qt::LeftButton)
910+ return true;
911+
912+ QWindow *targetWindow = findQWindowWithXWindowID(windowId);
913+
914+ QPoint windowPos(x / targetWindow->devicePixelRatio(), y / targetWindow->devicePixelRatio());
915+
916+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, MouseTouchAdaptor::touchDevice(),
917+ false /* autoCommit */);
918+ touchEvent.press(0 /* touchId */, windowPos);
919+ if (qtMod == TRI_PRESS_MODIFIER) {
920+ touchEvent.press(1, windowPos);
921+ touchEvent.press(2, windowPos);
922+ m_triPressModifier = true;
923+ }
924+ touchEvent.commit(false /* processEvents */);
925+
926+ m_leftButtonIsPressed = true;
927+ return true;
928+}
929+
930+bool X11MouseTouchAdaptorPrivate::handleButtonRelease(WId windowId, uint32_t detail, uint32_t, int x, int y)
931+{
932+ Qt::MouseButton button = translateMouseButton(detail);
933+
934+ // Don't eat the event if it wasn't a left mouse press
935+ if (button != Qt::LeftButton)
936+ return false;
937+
938+ QWindow *targetWindow = findQWindowWithXWindowID(windowId);
939+
940+ QPoint windowPos(x / targetWindow->devicePixelRatio(), y / targetWindow->devicePixelRatio());
941+
942+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, MouseTouchAdaptor::touchDevice(),
943+ false /* autoCommit */);
944+ touchEvent.release(0 /* touchId */, windowPos);
945+ if (m_triPressModifier) {
946+ touchEvent.release(1, windowPos);
947+ touchEvent.release(2, windowPos);
948+ }
949+ touchEvent.commit(false /* processEvents */);
950+
951+ m_leftButtonIsPressed = false;
952+ m_triPressModifier = false;
953+ return true;
954+}
955+
956+bool X11MouseTouchAdaptorPrivate::handleMotionNotify(WId windowId, uint32_t modifiers, int x, int y)
957+{
958+ if (!m_leftButtonIsPressed) {
959+ return true;
960+ }
961+ Qt::KeyboardModifiers qtMod = translateMofidier(modifiers);
962+
963+ QWindow *targetWindow = findQWindowWithXWindowID(windowId);
964+
965+ QPoint windowPos(x / targetWindow->devicePixelRatio(), y / targetWindow->devicePixelRatio());
966+
967+ QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, MouseTouchAdaptor::touchDevice(),
968+ false /* autoCommit */);
969+ touchEvent.move(0 /* touchId */, windowPos);
970+ if (m_triPressModifier) {
971+ if (qtMod == TRI_PRESS_MODIFIER) {
972+ touchEvent.move(1, windowPos);
973+ touchEvent.move(2, windowPos);
974+ } else {
975+ // released modifiers
976+ touchEvent.release(1, windowPos);
977+ touchEvent.release(2, windowPos);
978+ m_triPressModifier = false;
979+ }
980+ }
981+ touchEvent.commit(false /* processEvents */);
982+
983+ return true;
984+}
985+
986+} // namespace UbuntuToolkit
987
988=== added file 'tests/autopilot/ubuntuuitoolkit/tests/test_touchadaptor.py'
989--- tests/autopilot/ubuntuuitoolkit/tests/test_touchadaptor.py 1970-01-01 00:00:00 +0000
990+++ tests/autopilot/ubuntuuitoolkit/tests/test_touchadaptor.py 2016-04-07 16:01:36 +0000
991@@ -0,0 +1,38 @@
992+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
993+#
994+# Copyright (C) 2016 Canonical Ltd.
995+#
996+# This program is free software; you can redistribute it and/or modify
997+# it under the terms of the GNU Lesser General Public License as published by
998+# the Free Software Foundation; version 3.
999+#
1000+# This program is distributed in the hope that it will be useful,
1001+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1002+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1003+# GNU Lesser General Public License for more details.
1004+#
1005+# You should have received a copy of the GNU Lesser General Public License
1006+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1007+
1008+import os
1009+from testtools.matchers import Equals
1010+from autopilot.matchers import Eventually
1011+from ubuntuuitoolkit import tests
1012+
1013+
1014+class TouchAdaptorTestCase(tests.QMLFileAppTestCase):
1015+ path = os.path.abspath(__file__)
1016+ dir_path = os.path.dirname(path)
1017+ test_qml_file_path = os.path.join(
1018+ dir_path, 'test_touchadaptor.qml')
1019+
1020+ def get_command_line(self, command_line):
1021+ command_line.append('-touch')
1022+ return command_line
1023+
1024+ def test_apparent_touch_screen(self):
1025+ touchArea = self.main_view.select_single(objectName="touchArea")
1026+ label = self.main_view.select_single(objectName="label")
1027+ # Trigger handlers as a courtesy to a watching person
1028+ self.pointing_device.click_object(touchArea)
1029+ self.assertThat(label.text, Eventually(Equals("Touched")))
1030
1031=== added file 'tests/autopilot/ubuntuuitoolkit/tests/test_touchadaptor.qml'
1032--- tests/autopilot/ubuntuuitoolkit/tests/test_touchadaptor.qml 1970-01-01 00:00:00 +0000
1033+++ tests/autopilot/ubuntuuitoolkit/tests/test_touchadaptor.qml 2016-04-07 16:01:36 +0000
1034@@ -0,0 +1,51 @@
1035+/*
1036+ * Copyright 2016 Canonical Ltd.
1037+ *
1038+ * This program is free software; you can redistribute it and/or modify
1039+ * it under the terms of the GNU Lesser General Public License as published by
1040+ * the Free Software Foundation; version 3.
1041+ *
1042+ * This program is distributed in the hope that it will be useful,
1043+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1044+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1045+ * GNU Lesser General Public License for more details.
1046+ *
1047+ * You should have received a copy of the GNU Lesser General Public License
1048+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1049+ */
1050+
1051+import QtQuick 2.4
1052+import Ubuntu.Components 1.3
1053+
1054+MainView {
1055+ width: units.gu(48)
1056+ height: units.gu(60)
1057+ objectName: "mainView"
1058+
1059+ Page {
1060+ title: "TouchAdaptor"
1061+
1062+ MultiPointTouchArea {
1063+ id: mpa
1064+ property bool touched: false
1065+ anchors.fill: parent
1066+ mouseEnabled: false
1067+ objectName: "touchArea"
1068+ touchPoints: TouchPoint {
1069+ id: point1
1070+ onPressedChanged: {
1071+ if (pressed) {
1072+ label.text = "Touched";
1073+ }
1074+ }
1075+ }
1076+
1077+ Label {
1078+ id: label
1079+ objectName: "label"
1080+ anchors.centerIn: parent
1081+ text: "Not touched"
1082+ }
1083+ }
1084+ }
1085+}
1086
1087=== modified file 'tests/unit_x11/tst_components/tst_adaptivepagelayout.qml'
1088--- tests/unit_x11/tst_components/tst_adaptivepagelayout.qml 2016-03-07 06:19:27 +0000
1089+++ tests/unit_x11/tst_components/tst_adaptivepagelayout.qml 2016-04-07 16:01:36 +0000
1090@@ -314,6 +314,7 @@
1091 ];
1092 }
1093 function test_forced_synchronous_loading_bug1540449(data) {
1094+ layout.asynchronous = false;
1095 layout[data.func](layout.primaryPage, data.page);
1096 waitForRendering(layout, 400);
1097
1098
1099=== modified file 'ubuntu-sdk.pro'
1100--- ubuntu-sdk.pro 2015-12-11 13:35:10 +0000
1101+++ ubuntu-sdk.pro 2016-04-07 16:01:36 +0000
1102@@ -8,7 +8,10 @@
1103 requires(qtHaveModule(quick))
1104 load(qt_parts)
1105
1106-SUBDIRS += po documentation app-launch-profiler ubuntu-ui-toolkit-launcher apicheck
1107+src_uitk_launcher.subdir = ubuntu-ui-toolkit-launcher
1108+src_uitk_launcher.depends = sub-src
1109+
1110+SUBDIRS += po documentation app-launch-profiler src_uitk_launcher apicheck
1111
1112 sub_tests.CONFIG -= no_default_target
1113 sub_tests.CONFIG -= no_default_install
1114
1115=== removed file 'ubuntu-ui-toolkit-launcher/MouseTouchAdaptor.cpp'
1116--- ubuntu-ui-toolkit-launcher/MouseTouchAdaptor.cpp 2014-06-16 09:50:56 +0000
1117+++ ubuntu-ui-toolkit-launcher/MouseTouchAdaptor.cpp 1970-01-01 00:00:00 +0000
1118@@ -1,159 +0,0 @@
1119-/*
1120- * Copyright 2014 Canonical Ltd.
1121- *
1122- * This program is free software; you can redistribute it and/or modify
1123- * it under the terms of the GNU Lesser General Public License as published by
1124- * the Free Software Foundation; version 3.
1125- *
1126- * This program is distributed in the hope that it will be useful,
1127- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1128- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1129- * GNU Lesser General Public License for more details.
1130- *
1131- * You should have received a copy of the GNU Lesser General Public License
1132- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1133- *
1134- * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
1135- *
1136- */
1137-
1138-#include "MouseTouchAdaptor.h"
1139-
1140-#include <qpa/qwindowsysteminterface.h>
1141-
1142-#include <QtGui/QMouseEvent>
1143-#include <QtTest/QTest>
1144-
1145-using QTest::QTouchEventSequence;
1146-
1147-namespace {
1148-Qt::MouseButton translateMouseButton(xcb_button_t detail)
1149-{
1150- switch (detail) {
1151- case 1: return Qt::LeftButton;
1152- case 2: return Qt::MidButton;
1153- case 3: return Qt::RightButton;
1154- // Button values 4-7 are Wheel events
1155- default: return Qt::NoButton;
1156- }
1157-}
1158-} // end of anonymous namespace
1159-
1160-MouseTouchAdaptor::MouseTouchAdaptor()
1161- : m_leftButtonIsPressed(false)
1162-{
1163- m_touchDevice = new QTouchDevice;
1164- m_touchDevice->setType(QTouchDevice::TouchScreen);
1165- QWindowSystemInterface::registerTouchDevice(m_touchDevice);
1166-}
1167-
1168-bool MouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType,
1169- void * message, long * /*result*/)
1170-{
1171- if (eventType != "xcb_generic_event_t") {
1172- // wrong backend.
1173- qWarning("MouseTouchAdaptor: XCB backend not in use. Adaptor inoperative!");
1174- return false;
1175- }
1176-
1177- xcb_generic_event_t *xcbEvent = static_cast<xcb_generic_event_t *>(message);
1178-
1179- switch (xcbEvent->response_type & ~0x80) {
1180- case XCB_BUTTON_PRESS:
1181- return handleButtonPress(reinterpret_cast<xcb_button_press_event_t *>(xcbEvent));
1182- break;
1183- case XCB_BUTTON_RELEASE:
1184- return handleButtonRelease(reinterpret_cast<xcb_button_release_event_t *>(xcbEvent));
1185- break;
1186- case XCB_MOTION_NOTIFY:
1187- return handleMotionNotify(reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent));
1188- break;
1189- default:
1190- return false;
1191- break;
1192- };
1193-}
1194-
1195-bool MouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
1196-{
1197- Qt::MouseButton button = translateMouseButton(pressEvent->detail);
1198-
1199- // Skip the event if it wasn't a left mouse press
1200- if (button != Qt::LeftButton) {
1201- return false;
1202- }
1203-
1204- QPoint windowPos(pressEvent->event_x, pressEvent->event_y);
1205-
1206- QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
1207-
1208- // no autoCommit
1209- QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice, false);
1210- touchEvent.press(0, windowPos);
1211- // do not process events when committed, let the events be processed with next event loop
1212- touchEvent.commit(false);
1213-
1214- m_leftButtonIsPressed = true;
1215- return true;
1216-}
1217-
1218-bool MouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseEvent)
1219-{
1220- Qt::MouseButton button = translateMouseButton(releaseEvent->detail);
1221-
1222- // Skip the event if it wasn't a left mouse release
1223- if (button != Qt::LeftButton) {
1224- return false;
1225- }
1226-
1227- QPoint windowPos(releaseEvent->event_x, releaseEvent->event_y);
1228-
1229- QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
1230-
1231- // no autoCommit
1232- QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice, false);
1233- touchEvent.release(0, windowPos);
1234- // do not process events when committed, let the events be processed with next event loop
1235- touchEvent.commit(false);
1236-
1237- m_leftButtonIsPressed = false;
1238- return true;
1239-}
1240-
1241-bool MouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event)
1242-{
1243- if (!m_leftButtonIsPressed) {
1244- return false;
1245- }
1246-
1247- QPoint windowPos(event->event_x, event->event_y);
1248-
1249- QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
1250-
1251- // no autoCommit
1252- QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice, false);
1253- touchEvent.move(0, windowPos);
1254- // do not process events when committed, let the events be processed with next event loop
1255- touchEvent.commit(false);
1256-
1257- return true;
1258-}
1259-
1260-QWindow *MouseTouchAdaptor::findQWindowWithXWindowID(WId windowId)
1261-{
1262- QWindowList windowList = QGuiApplication::topLevelWindows();
1263- QWindow *foundWindow = 0;
1264-
1265- int i = 0;
1266- while (!foundWindow && i < windowList.count()) {
1267- QWindow *window = windowList[i];
1268- if (window->winId() == windowId) {
1269- foundWindow = window;
1270- } else {
1271- ++i;
1272- }
1273- }
1274-
1275- Q_ASSERT(foundWindow);
1276- return foundWindow;
1277-}
1278
1279=== removed file 'ubuntu-ui-toolkit-launcher/MouseTouchAdaptor.h'
1280--- ubuntu-ui-toolkit-launcher/MouseTouchAdaptor.h 2014-06-16 09:50:56 +0000
1281+++ ubuntu-ui-toolkit-launcher/MouseTouchAdaptor.h 1970-01-01 00:00:00 +0000
1282@@ -1,50 +0,0 @@
1283-/*
1284- * Copyright 2014 Canonical Ltd.
1285- *
1286- * This program is free software; you can redistribute it and/or modify
1287- * it under the terms of the GNU Lesser General Public License as published by
1288- * the Free Software Foundation; version 3.
1289- *
1290- * This program is distributed in the hope that it will be useful,
1291- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1292- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1293- * GNU Lesser General Public License for more details.
1294- *
1295- * You should have received a copy of the GNU Lesser General Public License
1296- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1297- *
1298- * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
1299- *
1300- */
1301-
1302-#ifndef MOUSE_TOUCH_ADAPTOR_H
1303-#define MOUSE_TOUCH_ADAPTOR_H
1304-
1305-#include <QtCore/QAbstractNativeEventFilter>
1306-#include <QWindow>
1307-#include <xcb/xcb.h>
1308-
1309-class QMouseEvent;
1310-class QTouchDevice;
1311-
1312-// Transforms QMouseEvents into single-finger QTouchEvents.
1313-class MouseTouchAdaptor : public QAbstractNativeEventFilter {
1314-
1315-public:
1316- MouseTouchAdaptor();
1317-
1318- // Filters mouse events and posts the equivalent QTouchEvents.
1319- virtual bool nativeEventFilter(const QByteArray & eventType, void *message, long *result);
1320-
1321-private:
1322-
1323- bool handleButtonPress(xcb_button_press_event_t *pressEvent);
1324- bool handleButtonRelease(xcb_button_release_event_t *releaseEvent);
1325- bool handleMotionNotify(xcb_motion_notify_event_t *event);
1326- QWindow *findQWindowWithXWindowID(WId windowId);
1327-
1328- QTouchDevice *m_touchDevice;
1329- bool m_leftButtonIsPressed;
1330-};
1331-
1332-#endif // MOUSE_TOUCH_ADAPTOR_H
1333
1334=== modified file 'ubuntu-ui-toolkit-launcher/launcher.cpp'
1335--- ubuntu-ui-toolkit-launcher/launcher.cpp 2015-11-13 09:29:40 +0000
1336+++ ubuntu-ui-toolkit-launcher/launcher.cpp 2016-04-07 16:01:36 +0000
1337@@ -32,19 +32,10 @@
1338 #include <QtQuick/private/qsgcontext_p.h>
1339 #include <QtCore/QCommandLineParser>
1340 #include <QtCore/QCommandLineOption>
1341-#include "MouseTouchAdaptor.h"
1342+#include <MouseTouchAdaptor>
1343 #include <QtGui/QTouchDevice>
1344 #include <QtQml/qqml.h>
1345
1346-bool touchDevicePresent()
1347-{
1348- Q_FOREACH(const QTouchDevice *device, QTouchDevice::devices()) {
1349- if (device->type() == QTouchDevice::TouchScreen)
1350- return true;
1351- }
1352- return false;
1353-}
1354-
1355 static QObject *s_testRootObject = 0;
1356 static QObject *testRootObject(QQmlEngine *engine, QJSEngine *jsEngine)
1357 {
1358@@ -151,9 +142,9 @@
1359 view->setFlags(Qt::FramelessWindowHint);
1360 }
1361
1362- if (args.isSet(_enableTouch) && !touchDevicePresent()) {
1363+ if (args.isSet(_enableTouch)) {
1364 // has no effect if we have touch screen
1365- application.installNativeEventFilter(new MouseTouchAdaptor);
1366+ new UbuntuToolkit::MouseTouchAdaptor(&application);
1367 }
1368
1369 QUrl source(QUrl::fromLocalFile(filename));
1370
1371=== modified file 'ubuntu-ui-toolkit-launcher/ubuntu-ui-toolkit-launcher.pro'
1372--- ubuntu-ui-toolkit-launcher/ubuntu-ui-toolkit-launcher.pro 2015-11-19 08:45:15 +0000
1373+++ ubuntu-ui-toolkit-launcher/ubuntu-ui-toolkit-launcher.pro 2016-04-07 16:01:36 +0000
1374@@ -1,11 +1,9 @@
1375 TEMPLATE = app
1376 QT += qml quick
1377 # For setSharedOpenGLContext
1378-QT += core-private gui-private testlib quick-private
1379-CONFIG += no_keywords
1380-HEADERS += MouseTouchAdaptor.h
1381-SOURCES += launcher.cpp \
1382- MouseTouchAdaptor.cpp
1383+QT += core-private gui-private testlib quick-private UbuntuToolkit
1384+CONFIG += no_keywords c++11
1385+SOURCES += launcher.cpp
1386 installPath = $$[QT_INSTALL_PREFIX]/bin
1387 launcher.path = $$installPath
1388 launcher.files = ubuntu-ui-toolkit-launcher

Subscribers

People subscribed via source and target branches