Merge lp:~zsombi/ubuntu-ui-toolkit/fixTouchAdaptor into lp:ubuntu-ui-toolkit/staging
- fixTouchAdaptor
- Merge into staging
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 |
Related bugs: |
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.
Description of the change
- 1924. By Zsombor Egri
-
missing license header added
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
- 1925. By Zsombor Egri
-
revert unwanted change
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1923
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1923
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1923
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1925
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1925
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
- 1926. By Zsombor Egri
-
add missing headers
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1925
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1925
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1926
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1926
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1926
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1926
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 1927. By Zsombor Egri
-
build dependenci to drive UbuntuToolkit lib to be built first
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1927
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1927
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1927
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1927
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 1928. By Zsombor Egri
-
wrapped and sorted
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1928
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1928
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1928
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
FAILED: Continuous integration, rev:1928
https:/
Executed test runs:
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1928
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1928
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1928
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1928
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1928
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1928
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1928
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1928
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
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 registerTouchDe
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.
- 1929. By Zsombor Egri
-
staging sync
- 1930. By Zsombor Egri
-
load page synchronously if that's what we want to test
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 registerTouchDe
> 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....
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1930
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1930
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1930
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1930
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 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
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.
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1933
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1933
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1933
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1933
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
- 1934. By Zsombor Egri
-
disable mouse handling on MPTA
Cris Dywan (kalikiana) wrote : | # |
Sweet. Thanks for the AP test and cleaning up the conditionals!
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1934
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1934
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1934
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1934
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1934
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1934
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1934
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
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 |
FAILED: Continuous integration, rev:1923 /jenkins. ubuntu. com/ubuntu- sdk/job/ ubuntu- ui-toolkit- ci-i386- gles-stable/ 354/ /jenkins. ubuntu. com/ubuntu- sdk/job/ generic- update- mp/2264/ console
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild: /jenkins. ubuntu. com/ubuntu- sdk/job/ ubuntu- ui-toolkit- ci-i386- gles-stable/ 354/rebuild
https:/