Merge lp:~dandrader/unity8/updateMouseTouchAdaptor into lp:unity8

Proposed by Daniel d'Andrada on 2015-12-16
Status: Merged
Approved by: Albert Astals Cid on 2015-12-17
Approved revision: 2103
Merged at revision: 2120
Proposed branch: lp:~dandrader/unity8/updateMouseTouchAdaptor
Merge into: lp:unity8
Diff against target: 715 lines (+288/-59)
14 files modified
CMakeLists.txt (+10/-0)
debian/control (+5/-1)
src/CMakeLists.txt (+13/-7)
src/Dash/CMakeLists.txt (+8/-8)
src/Dash/main.cpp (+9/-5)
src/MouseTouchAdaptor.cpp (+180/-21)
src/MouseTouchAdaptor.h (+10/-3)
src/ShellApplication.cpp (+5/-5)
src/ShellApplication.h (+12/-4)
src/UnityCommandLineParser.cpp (+6/-0)
src/UnityCommandLineParser.h (+8/-0)
tests/qmltests/CMakeLists.txt (+1/-1)
tests/utils/modules/Unity/Test/CMakeLists.txt (+8/-1)
tests/utils/modules/Unity/Test/plugin.cpp (+13/-3)
To merge this branch: bzr merge lp:~dandrader/unity8/updateMouseTouchAdaptor
Reviewer Review Type Date Requested Status
Albert Astals Cid (community) 2015-12-16 Approve on 2015-12-17
PS Jenkins bot continuous-integration Needs Fixing on 2015-12-16
Review via email: mp+280718@code.launchpad.net

Commit Message

Have "make tryFoo" work with Qt 5.5

Update MouseTouchAdaptor to use XInput2, as per Qt 5.5
+ Don't build MouseTouchAdaptor on ARM
+ remove unused context property from unity8-dash

Description of the Change

* Are there any related MPs required for this MP to build/function as expected? Please list.
No

* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes

* Did you make sure that your branch does not contain spurious tags?
Yes

* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
Not applicable

* If you changed the UI, has there been a design review?
Not applicable

To post a comment you must log in.
2102. By Daniel d'Andrada on 2015-12-16

Sort

PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:2101
http://jenkins.qa.ubuntu.com/job/unity8-ci/6964/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5815/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/379/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1675/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/378/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1570/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1570/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/377/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/376/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4493/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5828
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5828/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26114
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/144/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/378
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/378/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26113

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6964/rebuild

review: Needs Fixing (continuous-integration)
Albert Astals Cid (aacid) wrote :

      Start 21: testUnityTest
21/23 Test #21: testUnityTest ....................***Exception: SegFault 0.04 sec

review: Needs Fixing
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:2102
http://jenkins.qa.ubuntu.com/job/unity8-ci/6966/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5818/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/381/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1677/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/380/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1572/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1572/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/379/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/378/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4497/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5831
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5831/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26122
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/146/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/380
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/380/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26123

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6966/rebuild

review: Needs Fixing (continuous-integration)
2103. By Daniel d'Andrada on 2015-12-16

Test now needs a graphical environment

Daniel d'Andrada (dandrader) wrote :

On 16/12/2015 14:19, Albert Astals Cid wrote:
> Review: Needs Fixing
>
> Start 21: testUnityTest
> 21/23 Test #21: testUnityTest ....................***Exception: SegFault 0.04 sec
>

Fixed.

PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:2103
http://jenkins.qa.ubuntu.com/job/unity8-ci/6967/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5821/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/382/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1678
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/381
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1573
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1573
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/380
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/379
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4498/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5834
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5834/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26126
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/147/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/381
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/381/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26125

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6967/rebuild

review: Needs Fixing (continuous-integration)
Albert Astals Cid (aacid) wrote :

 * Did you perform an exploratory manual test run of the code change and any related functionality?
Yes

 * Did CI run pass?
known broken tests fixed elsewhere

 * Did you make sure that the branch does not contain spurious tags?
Yes

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-12-03 19:36:58 +0000
3+++ CMakeLists.txt 2015-12-16 18:06:16 +0000
4@@ -128,6 +128,16 @@
5 set(STDOUT_LOGGER "-o" "-,txt")
6 endif()
7
8+execute_process(COMMAND arch OUTPUT_VARIABLE ARCH)
9+if (NOT ARCH MATCHES "arm*")
10+ set(ENABLE_TOUCH_EMULATION true)
11+ add_definitions(-DUNITY8_ENABLE_TOUCH_EMULATION)
12+ pkg_check_modules(MOUSETOUCHADAPTOR_LIBS REQUIRED x11 xcb xi)
13+else()
14+ set(ENABLE_TOUCH_EMULATION false)
15+ message(STATUS "Touch emulation support disabled.")
16+endif()
17+
18 # add subdirectories to build
19 add_subdirectory(include)
20 add_subdirectory(libs)
21
22=== modified file 'debian/control'
23--- debian/control 2015-12-08 15:37:20 +0000
24+++ debian/control 2015-12-16 18:06:16 +0000
25@@ -31,7 +31,11 @@
26 libudev-dev,
27 libunity-api-dev (>= 7.104),
28 libusermetricsoutput1-dev,
29- libxcb1-dev,
30+# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
31+ libx11-dev[!armhf],
32+ libxcb1-dev[!armhf],
33+ libxi-dev[!armhf],
34+# End of X11 libs
35 pkg-config,
36 python3-all:any,
37 python3-setuptools,
38
39=== modified file 'src/CMakeLists.txt'
40--- src/CMakeLists.txt 2015-10-02 21:50:07 +0000
41+++ src/CMakeLists.txt 2015-12-16 18:06:16 +0000
42@@ -16,10 +16,9 @@
43 ${CMAKE_SOURCE_DIR}/tests/*.svg
44 )
45
46-add_executable(${SHELL_APP}
47+set(SOURCE_FILES
48 ApplicationArguments.cpp
49 main.cpp
50- MouseTouchAdaptor.cpp
51 CachingNetworkManagerFactory.cpp
52 SecondaryWindow.cpp
53 ShellApplication.cpp
54@@ -28,15 +27,22 @@
55 ${QML_FILES} # This is to make qml and image files appear in the IDE's project tree
56 )
57
58+if (ENABLE_TOUCH_EMULATION)
59+ set(SOURCE_FILES ${SOURCE_FILES} MouseTouchAdaptor.cpp)
60+endif()
61+
62+pkg_check_modules(ANDROID_PROPERTIES REQUIRED libandroid-properties)
63+add_executable(${SHELL_APP} ${SOURCE_FILES})
64 qt5_use_modules(${SHELL_APP} Gui Qml Quick Test)
65
66-pkg_check_modules(NEEDED_LIBS REQUIRED xcb libandroid-properties)
67-if (NOT "${NEEDED_LIBS_INCLUDE_DIRS}" STREQUAL "")
68- set_target_properties(${SHELL_APP} PROPERTIES INCLUDE_DIRECTORIES ${NEEDED_LIBS_INCLUDE_DIRS})
69+if (NOT "${ANDROID_PROPERTIES_INCLUDE_DIRS}" STREQUAL "")
70+ set_target_properties(${SHELL_APP} PROPERTIES INCLUDE_DIRECTORIES ${ANDROID_PROPERTIES_INCLUDE_DIRS})
71 endif()
72-target_link_libraries(${SHELL_APP} ${NEEDED_LIBS_LDFLAGS})
73+target_link_libraries(${SHELL_APP} ${ANDROID_PROPERTIES_LDFLAGS} UbuntuGestures connectivity-qt1)
74
75-target_link_libraries(${SHELL_APP} UbuntuGestures connectivity-qt1)
76+if (ENABLE_TOUCH_EMULATION)
77+ target_link_libraries(${SHELL_APP} ${MOUSETOUCHADAPTOR_LIBS_LDFLAGS})
78+endif()
79
80 # For it to find libUbuntuGestures.so
81 set_target_properties(${SHELL_APP} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}")
82
83=== modified file 'src/Dash/CMakeLists.txt'
84--- src/Dash/CMakeLists.txt 2015-03-06 04:44:11 +0000
85+++ src/Dash/CMakeLists.txt 2015-12-16 18:06:16 +0000
86@@ -1,25 +1,25 @@
87 set(DASH_SRCS
88 main.cpp
89- ../ApplicationArguments.cpp
90- ../MouseTouchAdaptor.cpp
91 ../CachingNetworkManagerFactory.cpp
92 )
93
94+if (ENABLE_TOUCH_EMULATION)
95+ set(DASH_SRCS ${DASH_SRCS} ../MouseTouchAdaptor.cpp)
96+endif()
97+
98 add_executable(unity8-dash ${DASH_SRCS})
99
100 qt5_use_modules(unity8-dash Gui Qml Quick Test)
101
102-pkg_check_modules(NEEDED_LIBS REQUIRED xcb libandroid-properties)
103-if (NOT "${NEEDED_LIBS_INCLUDE_DIRS}" STREQUAL "")
104- set_target_properties(unity8-dash PROPERTIES INCLUDE_DIRECTORIES ${NEEDED_LIBS_INCLUDE_DIRS})
105-endif()
106-target_link_libraries(unity8-dash ${NEEDED_LIBS_LDFLAGS})
107-
108 # For it to find libUbuntuGestures.so, needed by Ubuntu.Gestures QML module.
109 set_target_properties(unity8-dash PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}")
110
111 target_link_libraries(unity8-dash UbuntuGestures connectivity-qt1)
112
113+if (ENABLE_TOUCH_EMULATION)
114+ target_link_libraries(unity8-dash ${MOUSETOUCHADAPTOR_LIBS_LDFLAGS})
115+endif()
116+
117 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
118
119 # install binaries
120
121=== modified file 'src/Dash/main.cpp'
122--- src/Dash/main.cpp 2015-09-23 15:14:01 +0000
123+++ src/Dash/main.cpp 2015-12-16 18:06:16 +0000
124@@ -27,8 +27,9 @@
125 #include <libintl.h>
126
127 #include <paths.h>
128-#include "../MouseTouchAdaptor.h"
129-#include "../ApplicationArguments.h"
130+#ifdef UNITY8_ENABLE_TOUCH_EMULATION
131+ #include "../MouseTouchAdaptor.h"
132+#endif
133 #include "../CachingNetworkManagerFactory.h"
134
135 int main(int argc, const char *argv[])
136@@ -57,8 +58,6 @@
137 parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
138 parser.process(*application);
139
140- ApplicationArguments qmlArgs;
141-
142 if (getenv("QT_LOAD_TESTABILITY")) {
143 QLibrary testLib(QStringLiteral("qttestability"));
144 if (testLib.load()) {
145@@ -92,14 +91,15 @@
146 }
147
148 view->setTitle(QStringLiteral("Scopes"));
149- view->rootContext()->setContextProperty(QStringLiteral("applicationArguments"), &qmlArgs);
150
151+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
152 // You will need this if you want to interact with touch-only components using a mouse
153 // Needed only when manually testing on a desktop.
154 MouseTouchAdaptor *mouseTouchAdaptor = 0;
155 if (parser.isSet(mousetouchOption)) {
156 mouseTouchAdaptor = MouseTouchAdaptor::instance();
157 }
158+ #endif
159
160 QUrl source(::qmlDirectory() + "/Dash/DashApplication.qml");
161 prependImportPaths(view->engine(), ::overrideImportPaths());
162@@ -114,7 +114,11 @@
163 int result = application->exec();
164
165 delete view;
166+
167+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
168 delete mouseTouchAdaptor;
169+ #endif
170+
171 delete application;
172
173 return result;
174
175=== modified file 'src/MouseTouchAdaptor.cpp'
176--- src/MouseTouchAdaptor.cpp 2015-06-07 14:52:39 +0000
177+++ src/MouseTouchAdaptor.cpp 2015-12-16 18:06:16 +0000
178@@ -16,14 +16,56 @@
179 * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
180 */
181
182+
183+/* Some parts of the code were copied from the XCB platform plugin of the Qt Toolkit,
184+ * which is under the following license:
185+ */
186+
187+/****************************************************************************
188+**
189+** Copyright (C) 2015 The Qt Company Ltd.
190+** Contact: http://www.qt.io/licensing/
191+**
192+** This file is part of the .
193+**
194+** $QT_BEGIN_LICENSE:LGPL21$
195+** Commercial License Usage
196+** Licensees holding valid commercial Qt licenses may use this file in
197+** accordance with the commercial license agreement provided with the
198+** Software or, alternatively, in accordance with the terms contained in
199+** a written agreement between you and The Qt Company. For licensing terms
200+** and conditions see http://www.qt.io/terms-conditions. For further
201+** information use the contact form at http://www.qt.io/contact-us.
202+**
203+** GNU Lesser General Public License Usage
204+** Alternatively, this file may be used under the terms of the GNU Lesser
205+** General Public License version 2.1 or version 3 as published by the Free
206+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
207+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
208+** following information to ensure the GNU Lesser General Public License
209+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
210+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
211+**
212+** As a special exception, The Qt Company gives you certain additional
213+** rights. These rights are described in The Qt Company LGPL Exception
214+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
215+**
216+** $QT_END_LICENSE$
217+**
218+****************************************************************************/
219+
220 #include "MouseTouchAdaptor.h"
221
222+#include <qpa/qplatformnativeinterface.h>
223 #include <qpa/qwindowsysteminterface.h>
224
225 #include <QCoreApplication>
226 #include <QMouseEvent>
227 #include <QTest>
228
229+#include <X11/extensions/XInput2.h>
230+#include <X11/extensions/XI2proto.h>
231+
232 using QTest::QTouchEventSequence;
233
234 namespace {
235@@ -49,6 +91,8 @@
236 m_touchDevice = new QTouchDevice;
237 m_touchDevice->setType(QTouchDevice::TouchScreen);
238 QWindowSystemInterface::registerTouchDevice(m_touchDevice);
239+
240+ fetchXInput2Info();
241 }
242
243 MouseTouchAdaptor::~MouseTouchAdaptor()
244@@ -65,9 +109,114 @@
245 return g_instance;
246 }
247
248+void MouseTouchAdaptor::fetchXInput2Info()
249+{
250+ QPlatformNativeInterface *nativeInterface = qGuiApp->platformNativeInterface();
251+ Display *xDisplay = static_cast<Display*>(nativeInterface->nativeResourceForIntegration("Display"));
252+ if (xDisplay && XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
253+ int xiMajor = 2;
254+ m_xi2Minor = 2; // try 2.2 first, needed for TouchBegin/Update/End
255+ if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
256+ m_xi2Minor = 1; // for smooth scrolling 2.1 is enough
257+ if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
258+ m_xi2Minor = 0; // for tablet support 2.0 is enough
259+ m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest;
260+ } else
261+ m_xi2Enabled = true;
262+ } else {
263+ m_xi2Enabled = true;
264+ }
265+ }
266+}
267+
268+// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
269+// - "pad0" became "extension"
270+// - "pad1" and "pad" became "pad0"
271+// New and old version of this struct share the following fields:
272+// NOTE: API might change again in the next release of xcb in which case this comment will
273+// need to be updated to reflect the reality.
274+typedef struct qt_xcb_ge_event_t {
275+ uint8_t response_type;
276+ uint8_t extension;
277+ uint16_t sequence;
278+ uint32_t length;
279+ uint16_t event_type;
280+} qt_xcb_ge_event_t;
281+
282+bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *ev, int opCode)
283+{
284+ qt_xcb_ge_event_t *event = (qt_xcb_ge_event_t *)ev;
285+ // xGenericEvent has "extension" on the second byte, the same is true for xcb_ge_event_t starting from
286+ // the xcb version 1.9.3, prior to that it was called "pad0".
287+ if (event->extension == opCode) {
288+ // xcb event structs contain stuff that wasn't on the wire, the full_sequence field
289+ // adds an extra 4 bytes and generic events cookie data is on the wire right after the standard 32 bytes.
290+ // Move this data back to have the same layout in memory as it was on the wire
291+ // and allow casting, overwriting the full_sequence field.
292+ memmove((char*) event + 32, (char*) event + 36, event->length * 4);
293+ return true;
294+ }
295+ return false;
296+}
297+
298+static inline qreal fixed1616ToReal(FP1616 val)
299+{
300+ return qreal(val) / 0x10000;
301+}
302+
303+bool MouseTouchAdaptor::xi2HandleEvent(xcb_ge_event_t *event)
304+{
305+ if (!xi2PrepareXIGenericDeviceEvent(event, m_xiOpCode)) {
306+ return false;
307+ }
308+
309+ xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
310+ xXIDeviceEvent *xiDeviceEvent = 0;
311+
312+ switch (xiEvent->evtype) {
313+ case XI_ButtonPress:
314+ case XI_ButtonRelease:
315+ case XI_Motion:
316+ xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
317+ break;
318+ default:
319+ break;
320+ }
321+
322+ if (!xiDeviceEvent) {
323+ return false;
324+ }
325+
326+ switch (xiDeviceEvent->evtype) {
327+ case XI_ButtonPress:
328+ return handleButtonPress(
329+ static_cast<WId>(xiDeviceEvent->event),
330+ xiDeviceEvent->detail,
331+ fixed1616ToReal(xiDeviceEvent->event_x),
332+ fixed1616ToReal(xiDeviceEvent->event_y));
333+ case XI_ButtonRelease:
334+ return handleButtonRelease(
335+ static_cast<WId>(xiDeviceEvent->event),
336+ xiDeviceEvent->detail,
337+ fixed1616ToReal(xiDeviceEvent->event_x),
338+ fixed1616ToReal(xiDeviceEvent->event_y));
339+ case XI_Motion:
340+ return handleMotionNotify(
341+ static_cast<WId>(xiDeviceEvent->event),
342+ fixed1616ToReal(xiDeviceEvent->event_x),
343+ fixed1616ToReal(xiDeviceEvent->event_y));
344+ return true;
345+ default:
346+ return false;
347+ }
348+}
349+
350+
351 bool MouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType,
352 void * message, long * /*result*/)
353 {
354+ static int eventCount = 0;
355+ eventCount++;
356 if (!m_enabled) {
357 return false;
358 }
359@@ -81,32 +230,42 @@
360 xcb_generic_event_t *xcbEvent = static_cast<xcb_generic_event_t *>(message);
361
362 switch (xcbEvent->response_type & ~0x80) {
363- case XCB_BUTTON_PRESS:
364- return handleButtonPress(reinterpret_cast<xcb_button_press_event_t *>(xcbEvent));
365- break;
366- case XCB_BUTTON_RELEASE:
367- return handleButtonRelease(reinterpret_cast<xcb_button_release_event_t *>(xcbEvent));
368- break;
369- case XCB_MOTION_NOTIFY:
370- return handleMotionNotify(reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent));
371- break;
372+ case XCB_BUTTON_PRESS: {
373+ auto pressEvent = reinterpret_cast<xcb_button_press_event_t *>(xcbEvent);
374+ return handleButtonPress(static_cast<WId>(pressEvent->event), pressEvent->detail,
375+ pressEvent->event_x, pressEvent->event_y);
376+ }
377+ case XCB_BUTTON_RELEASE: {
378+ auto releaseEvent = reinterpret_cast<xcb_button_release_event_t *>(xcbEvent);
379+ return handleButtonRelease(static_cast<WId>(releaseEvent->event), releaseEvent->detail,
380+ releaseEvent->event_x, releaseEvent->event_y);
381+ }
382+ case XCB_MOTION_NOTIFY: {
383+ auto motionEvent = reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent);
384+ return handleMotionNotify(static_cast<WId>(motionEvent->event), motionEvent->event_x, motionEvent->event_y);
385+ }
386+ case XCB_GE_GENERIC:
387+ if (m_xi2Enabled) {
388+ return xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(xcbEvent));
389+ } else {
390+ return false;
391+ }
392 default:
393 return false;
394- break;
395 };
396 }
397
398-bool MouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
399+bool MouseTouchAdaptor::handleButtonPress(WId windowId, uint32_t detail, int x, int y)
400 {
401- Qt::MouseButton button = translateMouseButton(pressEvent->detail);
402+ Qt::MouseButton button = translateMouseButton(detail);
403
404 // Just eat the event if it wasn't a left mouse press
405 if (button != Qt::LeftButton)
406 return true;
407
408- QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
409+ QWindow *targetWindow = findQWindowWithXWindowID(windowId);
410
411- QPoint windowPos(pressEvent->event_x / targetWindow->devicePixelRatio(), pressEvent->event_y / targetWindow->devicePixelRatio());
412+ QPoint windowPos(x / targetWindow->devicePixelRatio(), y / targetWindow->devicePixelRatio());
413
414 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
415 false /* autoCommit */);
416@@ -117,17 +276,17 @@
417 return true;
418 }
419
420-bool MouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseEvent)
421+bool MouseTouchAdaptor::handleButtonRelease(WId windowId, uint32_t detail, int x, int y)
422 {
423- Qt::MouseButton button = translateMouseButton(releaseEvent->detail);
424+ Qt::MouseButton button = translateMouseButton(detail);
425
426 // Just eat the event if it wasn't a left mouse release
427 if (button != Qt::LeftButton)
428 return true;
429
430- QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
431+ QWindow *targetWindow = findQWindowWithXWindowID(windowId);
432
433- QPoint windowPos(releaseEvent->event_x / targetWindow->devicePixelRatio(), releaseEvent->event_y / targetWindow->devicePixelRatio());
434+ QPoint windowPos(x / targetWindow->devicePixelRatio(), y / targetWindow->devicePixelRatio());
435
436 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
437 false /* autoCommit */);
438@@ -138,15 +297,15 @@
439 return true;
440 }
441
442-bool MouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event)
443+bool MouseTouchAdaptor::handleMotionNotify(WId windowId, int x, int y)
444 {
445 if (!m_leftButtonIsPressed) {
446 return true;
447 }
448
449- QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
450+ QWindow *targetWindow = findQWindowWithXWindowID(windowId);
451
452- QPoint windowPos(event->event_x / targetWindow->devicePixelRatio(), event->event_y / targetWindow->devicePixelRatio());
453+ QPoint windowPos(x / targetWindow->devicePixelRatio(), y / targetWindow->devicePixelRatio());
454
455 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
456 false /* autoCommit */);
457
458=== modified file 'src/MouseTouchAdaptor.h'
459--- src/MouseTouchAdaptor.h 2015-03-02 12:41:17 +0000
460+++ src/MouseTouchAdaptor.h 2015-12-16 18:06:16 +0000
461@@ -21,6 +21,7 @@
462
463 #include <QtCore/QAbstractNativeEventFilter>
464 #include <QWindow>
465+
466 #include <xcb/xcb.h>
467
468 class QMouseEvent;
469@@ -47,16 +48,22 @@
470
471 private:
472 MouseTouchAdaptor();
473+ void fetchXInput2Info();
474+ bool xi2HandleEvent(xcb_ge_event_t *event);
475
476- bool handleButtonPress(xcb_button_press_event_t *pressEvent);
477- bool handleButtonRelease(xcb_button_release_event_t *releaseEvent);
478- bool handleMotionNotify(xcb_motion_notify_event_t *event);
479+ bool handleButtonPress(WId windowId, uint32_t detail, int x, int y);
480+ bool handleButtonRelease(WId windowId, uint32_t detail, int x, int y);
481+ bool handleMotionNotify(WId windowId, int x, int y);
482 QWindow *findQWindowWithXWindowID(WId windowId);
483
484 QTouchDevice *m_touchDevice;
485 bool m_leftButtonIsPressed;
486
487 bool m_enabled;
488+
489+ bool m_xi2Enabled{false};
490+ int m_xi2Minor{-1};
491+ int m_xiOpCode, m_xiEventBase, m_xiErrorBase;
492 };
493
494 #endif // MOUSE_TOUCH_ADAPTOR_H
495
496=== modified file 'src/ShellApplication.cpp'
497--- src/ShellApplication.cpp 2015-11-20 15:31:46 +0000
498+++ src/ShellApplication.cpp 2015-12-16 18:06:16 +0000
499@@ -28,15 +28,10 @@
500 // local
501 #include <paths.h>
502 #include "CachingNetworkManagerFactory.h"
503-#include "MouseTouchAdaptor.h"
504 #include "UnityCommandLineParser.h"
505
506 ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
507 : QGuiApplication(argc, argv)
508- , m_shellView(nullptr)
509- , m_secondaryWindow(nullptr)
510- , m_mouseTouchAdaptor(nullptr)
511- , m_qmlEngine(nullptr)
512 {
513
514 setApplicationName(QStringLiteral("unity8"));
515@@ -89,11 +84,14 @@
516 m_shellView->setFlags(Qt::FramelessWindowHint);
517 }
518
519+
520+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
521 // You will need this if you want to interact with touch-only components using a mouse
522 // Needed only when manually testing on a desktop.
523 if (parser.hasMouseToTouch()) {
524 m_mouseTouchAdaptor = MouseTouchAdaptor::instance();
525 }
526+ #endif
527
528
529 // Some hard-coded policy for now.
530@@ -134,8 +132,10 @@
531 delete m_secondaryWindow;
532 m_secondaryWindow = nullptr;
533
534+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
535 delete m_mouseTouchAdaptor;
536 m_mouseTouchAdaptor = nullptr;
537+ #endif
538
539 delete m_qmlEngine;
540 m_qmlEngine = nullptr;
541
542=== modified file 'src/ShellApplication.h'
543--- src/ShellApplication.h 2015-10-20 15:19:42 +0000
544+++ src/ShellApplication.h 2015-12-16 18:06:16 +0000
545@@ -23,7 +23,11 @@
546 #include <QScopedPointer>
547
548 #include "ApplicationArguments.h"
549+
550+#ifdef UNITY8_ENABLE_TOUCH_EMULATION
551 #include "MouseTouchAdaptor.h"
552+#endif
553+
554 #include "SecondaryWindow.h"
555 #include "ShellView.h"
556
557@@ -46,10 +50,14 @@
558 void setupQmlEngine(bool isMirServer);
559 QString m_deviceName;
560 ApplicationArguments m_qmlArgs;
561- ShellView *m_shellView;
562- SecondaryWindow *m_secondaryWindow;
563- MouseTouchAdaptor *m_mouseTouchAdaptor;
564- QQmlEngine *m_qmlEngine;
565+ ShellView *m_shellView{nullptr};
566+ SecondaryWindow *m_secondaryWindow{nullptr};
567+
568+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
569+ MouseTouchAdaptor *m_mouseTouchAdaptor{nullptr};
570+ #endif
571+
572+ QQmlEngine *m_qmlEngine{nullptr};
573 };
574
575 #endif // SHELLAPPLICATION_H
576
577=== modified file 'src/UnityCommandLineParser.cpp'
578--- src/UnityCommandLineParser.cpp 2015-09-14 09:11:08 +0000
579+++ src/UnityCommandLineParser.cpp 2015-12-16 18:06:16 +0000
580@@ -37,9 +37,11 @@
581 QStringLiteral("Run without window borders"));
582 parser.addOption(framelessOption);
583
584+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
585 QCommandLineOption mousetouchOption(QStringLiteral("mousetouch"),
586 QStringLiteral("Allow the mouse to provide touch input"));
587 parser.addOption(mousetouchOption);
588+ #endif
589
590 QCommandLineOption windowGeometryOption(QStringList() << QStringLiteral("windowgeometry"),
591 QStringLiteral("Specify the window geometry as [<width>x<height>]"), QStringLiteral("windowgeometry"), QStringLiteral("1"));
592@@ -75,7 +77,11 @@
593
594 m_hasTestability = parser.isSet(testabilityOption);
595 m_hasFrameless = parser.isSet(framelessOption);
596+
597+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
598 m_hasMouseToTouch = parser.isSet(mousetouchOption);
599+ #endif
600+
601 m_hasFullscreen = parser.isSet(fullscreenOption);
602 m_deviceName = parser.value(devicenameOption);
603 resolveMode(parser, modeOption);
604
605=== modified file 'src/UnityCommandLineParser.h'
606--- src/UnityCommandLineParser.h 2015-04-20 13:20:10 +0000
607+++ src/UnityCommandLineParser.h 2015-12-16 18:06:16 +0000
608@@ -28,7 +28,11 @@
609 QSize windowGeometry() const { return m_windowGeometry; }
610 bool hasTestability() const { return m_hasTestability; }
611 bool hasFrameless() const { return m_hasFrameless; }
612+
613+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
614 bool hasMouseToTouch() const { return m_hasMouseToTouch; }
615+ #endif
616+
617 bool hasFullscreen() const { return m_hasFullscreen; }
618 QString deviceName() const { return m_deviceName; }
619 QString mode() const { return m_mode; }
620@@ -43,7 +47,11 @@
621 QSize m_windowGeometry;
622 bool m_hasTestability;
623 bool m_hasFrameless;
624+
625+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
626 bool m_hasMouseToTouch;
627+ #endif
628+
629 bool m_hasFullscreen;
630 QString m_deviceName;
631 QString m_mode;
632
633=== modified file 'tests/qmltests/CMakeLists.txt'
634--- tests/qmltests/CMakeLists.txt 2015-11-26 16:36:53 +0000
635+++ tests/qmltests/CMakeLists.txt 2015-12-16 18:06:16 +0000
636@@ -87,4 +87,4 @@
637 add_unity8_qmltest(Stages Splash)
638 add_unity8_qmltest(Tutorial Tutorial LIGHTDM)
639 add_unity8_qmltest(Wizard Wizard ENVIRONMENT "OXIDE_NO_SANDBOX=1")
640-add_unity8_qmlunittest(utils/Unity/Test UnityTest)
641+add_unity8_qmltest(utils/Unity/Test UnityTest)
642
643=== modified file 'tests/utils/modules/Unity/Test/CMakeLists.txt'
644--- tests/utils/modules/Unity/Test/CMakeLists.txt 2015-03-02 12:41:17 +0000
645+++ tests/utils/modules/Unity/Test/CMakeLists.txt 2015-12-16 18:06:16 +0000
646@@ -13,12 +13,19 @@
647 testutil.cpp
648 plugin.cpp
649 TouchEventSequenceWrapper.cpp
650- ${CMAKE_SOURCE_DIR}/src/MouseTouchAdaptor.cpp
651 )
652
653+if (ENABLE_TOUCH_EMULATION)
654+ set(UnityTestQML_SOURCES ${UnityTestQML_SOURCES} ${CMAKE_SOURCE_DIR}/src/MouseTouchAdaptor.cpp)
655+endif()
656+
657 add_library(UnityTestQml MODULE ${UnityTestQML_SOURCES})
658 target_link_libraries(UnityTestQml UbuntuGestures)
659
660+if (ENABLE_TOUCH_EMULATION)
661+ target_link_libraries(UnityTestQml ${MOUSETOUCHADAPTOR_LIBS_LDFLAGS})
662+endif()
663+
664 qt5_use_modules(UnityTestQml Core Quick Test)
665
666 export_qmlfiles(Unity.Test Unity/Test)
667
668=== modified file 'tests/utils/modules/Unity/Test/plugin.cpp'
669--- tests/utils/modules/Unity/Test/plugin.cpp 2015-03-02 12:41:17 +0000
670+++ tests/utils/modules/Unity/Test/plugin.cpp 2015-12-16 18:06:16 +0000
671@@ -17,7 +17,11 @@
672
673 #include "plugin.h"
674 #include "testutil.h"
675+
676+#ifdef UNITY8_ENABLE_TOUCH_EMULATION
677 #include <MouseTouchAdaptor.h>
678+#endif
679+
680 #include "TouchEventSequenceWrapper.h"
681
682 #include <qqml.h>
683@@ -27,23 +31,29 @@
684 {
685 return new TestUtil();
686 }
687+
688+#ifdef UNITY8_ENABLE_TOUCH_EMULATION
689 QObject *getMouseTouchAdaptorQMLSingleton(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */)
690 {
691 return MouseTouchAdaptor::instance();
692 }
693+#endif
694+
695 } // anonymous namespace
696
697 void UnityTestPlugin::registerTypes(const char *uri)
698 {
699 Q_ASSERT(QLatin1String(uri) == QLatin1String("Unity.Test"));
700
701- // Ensure the instance gets created
702- MouseTouchAdaptor::instance();
703-
704 // @uri Unity.Test
705 qmlRegisterSingletonType<TestUtil>(uri, 0, 1, "Util", testutil_provider);
706 qmlRegisterUncreatableType<TouchEventSequenceWrapper>(uri, 0, 1, "TouchEventSequence",
707 "You cannot directly create a TouchEventSequence object.");
708+
709+ #ifdef UNITY8_ENABLE_TOUCH_EMULATION
710+ // Ensure the instance gets created
711+ MouseTouchAdaptor::instance();
712 qmlRegisterSingletonType<MouseTouchAdaptor>(uri, 0, 1, "MouseTouchAdaptor",
713 getMouseTouchAdaptorQMLSingleton);
714+ #endif
715 }

Subscribers

People subscribed via source and target branches