Merge lp:~dandrader/qtmir/oneUpDownPerEvent-lp1437357 into lp:qtmir

Proposed by Daniel d'Andrada
Status: Merged
Approved by: Gerry Boland
Approved revision: 331
Merged at revision: 332
Proposed branch: lp:~dandrader/qtmir/oneUpDownPerEvent-lp1437357
Merge into: lp:qtmir
Diff against target: 505 lines (+268/-46)
7 files modified
src/common/debughelpers.cpp (+47/-0)
src/common/debughelpers.h (+5/-1)
src/platforms/mirserver/CMakeLists.txt (+5/-3)
src/platforms/mirserver/qteventfeeder.cpp (+66/-23)
src/platforms/mirserver/qteventfeeder.h (+4/-1)
tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h (+5/-0)
tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp (+136/-18)
To merge this branch: bzr merge lp:~dandrader/qtmir/oneUpDownPerEvent-lp1437357
Reviewer Review Type Date Requested Status
Gerry Boland (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+254937@code.launchpad.net

Commit message

When synthesizing touch releases for absent touches, send them in separate events

As there can be only one touch pressed or released per event.

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.

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

To post a comment you must log in.
330. By Daniel d'Andrada

Remove leftover

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote :

Would catching the exception be easier than all this work?
And is there a Mir bug so we can keep track of Mir fixing their input stream to us? All this event stream sanitizing should be unnecessary.

+#include "../../common/debughelpers.h"
better to include ../../common as a source of headers

-Q_LOGGING_CATEGORY(QTMIR_MIR_INPUT, "qtmir.mir.input")
+Q_LOGGING_CATEGORY(QTMIR_MIR_INPUT, "qtmir.mir.input", QtWarningMsg)
what does this give us?

Was unable to reproduce a crash on devel-proposed, but I find no regressions while testing it

review: Needs Fixing
331. By Daniel d'Andrada

add src/common to platform/mirserver include dirs

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

On 16/04/15 08:22, Gerry Boland wrote:
> Review: Needs Fixing
>
> Would catching the exception be easier than all this work?

I don't see the point. The mir exception is thrown when we try to send a
MirEvent containing more than one touch press or release. We shouldn't
be doing that in the first place.

> And is there a Mir bug so we can keep track of Mir fixing their input stream to us? All this event stream sanitizing should be unnecessary.

There's this one at least: https://bugs.launchpad.net/mir/+bug/1439285

>
>
> +#include "../../common/debughelpers.h"
> better to include ../../common as a source of headers
Done.
> -Q_LOGGING_CATEGORY(QTMIR_MIR_INPUT, "qtmir.mir.input")
> +Q_LOGGING_CATEGORY(QTMIR_MIR_INPUT, "qtmir.mir.input", QtWarningMsg)
> what does this give us?
It means that by default only warnings or more severe message types
(criticals) will be logged. So we won't spam logs with debug messages by
default. This is particularly important here as I added a debug messages
for every single input event coming or leaving QtEventFeeder.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote :

LGTM, thank you

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/common/debughelpers.cpp'
2--- src/common/debughelpers.cpp 2015-02-19 23:03:14 +0000
3+++ src/common/debughelpers.cpp 2015-04-16 13:38:31 +0000
4@@ -207,3 +207,50 @@
5 return "???";
6 }
7 }
8+
9+QString mirTouchEventToString(MirTouchInputEvent const* event)
10+{
11+ const int pointerCount = mir_touch_input_event_get_touch_count(event);
12+
13+ QString string("MirTouchInputEvent(");
14+
15+ for (int i = 0; i < pointerCount; ++i) {
16+
17+ if (i > 0) {
18+ string.append(",");
19+ }
20+
21+ MirTouchInputEventTouchAction touchAction = mir_touch_input_event_get_touch_action(event, i);
22+
23+ QString touchStr = QString("(id=%1,action=%2,x=%3,y=%4)")
24+ .arg(mir_touch_input_event_get_touch_id(event, i))
25+ .arg(mirTouchActionToString(touchAction))
26+ .arg(mir_touch_input_event_get_touch_axis_value(event, i, mir_touch_input_axis_x))
27+ .arg(mir_touch_input_event_get_touch_axis_value(event, i, mir_touch_input_axis_y));
28+
29+ string.append(touchStr);
30+ }
31+
32+ string.append(")");
33+
34+ return string;
35+}
36+
37+const char *mirTouchActionToString(MirTouchInputEventTouchAction touchAction)
38+{
39+ switch (touchAction)
40+ {
41+ case mir_touch_input_event_action_up:
42+ return "up";
43+ break;
44+ case mir_touch_input_event_action_down:
45+ return "down";
46+ break;
47+ case mir_touch_input_event_action_change:
48+ return "change";
49+ break;
50+ default:
51+ return "???";
52+ break;
53+ }
54+}
55
56=== modified file 'src/common/debughelpers.h'
57--- src/common/debughelpers.h 2014-08-27 11:51:28 +0000
58+++ src/common/debughelpers.h 2015-04-16 13:38:31 +0000
59@@ -1,5 +1,5 @@
60 /*
61- * Copyright (C) 2013-2014 Canonical, Ltd.
62+ * Copyright (C) 2013-2015 Canonical, Ltd.
63 *
64 * This program is free software: you can redistribute it and/or modify it under
65 * the terms of the GNU Lesser General Public License version 3, as published by
66@@ -20,6 +20,7 @@
67 #include <QString>
68
69 #include <mir_toolkit/common.h>
70+#include <mir_toolkit/events/input/input_event.h>
71
72 class QTouchEvent;
73
74@@ -35,4 +36,7 @@
75
76 const char *applicationStateToStr(int state);
77
78+QString mirTouchEventToString(MirTouchInputEvent const* event);
79+const char *mirTouchActionToString(MirTouchInputEventTouchAction touchAction);
80+
81 #endif // UBUNTUGESTURES_DEBUG_HELPER_H
82
83=== modified file 'src/platforms/mirserver/CMakeLists.txt'
84--- src/platforms/mirserver/CMakeLists.txt 2015-01-28 14:25:36 +0000
85+++ src/platforms/mirserver/CMakeLists.txt 2015-04-16 13:38:31 +0000
86@@ -18,9 +18,11 @@
87 endforeach(item ${Qt5Gui_PRIVATE_INCLUDE_DIRS})
88
89 include_directories(
90+ ${CMAKE_SOURCE_DIR}/src/common
91+
92 ${MIRCOMMON_INCLUDE_DIRS}
93 ${MIRSERVER_INCLUDE_DIRS}
94-
95+
96 ${URL_DISPATCHER_INCLUDE_DIRS}
97 ${PROTOBUF_INCLUDE_DIRS}
98 ${EGL_INCLUDE_DIRS}
99@@ -37,7 +39,7 @@
100 add_definitions(-DBYTE_ORDER=__BYTE_ORDER)
101
102 set(MIRSERVER_QPA_PLUGIN_SRC
103- ../../common/debughelpers.cpp
104+ ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
105 mirshell.cpp
106 qteventfeeder.cpp
107 plugin.cpp
108@@ -74,7 +76,7 @@
109 ${EGL_LDFLAGS}
110 ${GL_LIBRARIES}
111 ${LTTNG_LIBRARIES}
112-
113+
114 ${QT5PLATFORM_SUPPORT_LDFLAGS}
115 # TODO Qt5Platform support LDFLAGS dont provide actual required ldflags...
116 # I found these were needed...perhaps there is some way to query qmake/qconfig?
117
118=== modified file 'src/platforms/mirserver/qteventfeeder.cpp'
119--- src/platforms/mirserver/qteventfeeder.cpp 2015-02-19 23:03:14 +0000
120+++ src/platforms/mirserver/qteventfeeder.cpp 2015-04-16 13:38:31 +0000
121@@ -30,7 +30,10 @@
122
123 #include <QDebug>
124
125-Q_LOGGING_CATEGORY(QTMIR_MIR_INPUT, "qtmir.mir.input")
126+// common dir
127+#include <debughelpers.h>
128+
129+Q_LOGGING_CATEGORY(QTMIR_MIR_INPUT, "qtmir.mir.input", QtWarningMsg)
130
131 // XKB Keysyms which do not map directly to Qt types (i.e. Unicode points)
132 static const uint32_t KeyTable[] = {
133@@ -355,6 +358,7 @@
134 return;
135
136 auto tev = mir_input_event_get_touch_input_event(event);
137+ qCDebug(QTMIR_MIR_INPUT) << "Received" << qPrintable(mirTouchEventToString(tev));
138
139 // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That
140 // needs to be fixed as soon as the compat input lib adds query support.
141@@ -398,9 +402,10 @@
142
143 // Qt needs a happy, sane stream of touch events. So let's make sure we're not forwarding
144 // any insanity.
145- validateTouches(touchPoints);
146+ validateTouches(mir_input_event_get_event_time(event) / 1000000, touchPoints);
147
148 // Touch event propagation.
149+ qCDebug(QTMIR_MIR_INPUT) << "Sending to Qt" << qPrintable(touchesToString(touchPoints));
150 mQtWindowSystem->handleTouchEvent(
151 //scales down the nsec_t (int64) to fit a ulong, precision lost but time difference suitable
152 mir_input_event_get_event_time(event) / 1000000,
153@@ -429,7 +434,8 @@
154 Q_UNUSED(when);
155 }
156
157-void QtEventFeeder::validateTouches(QList<QWindowSystemInterface::TouchPoint> &touchPoints)
158+void QtEventFeeder::validateTouches(ulong timestamp,
159+ QList<QWindowSystemInterface::TouchPoint> &touchPoints)
160 {
161 QSet<int> updatedTouches;
162
163@@ -446,21 +452,45 @@
164 }
165 }
166
167- // Release all unmentioned touches.
168- {
169- QHash<int, QWindowSystemInterface::TouchPoint>::iterator it = mActiveTouches.begin();
170- while (it != mActiveTouches.end()) {
171- if (!updatedTouches.contains(it.key())) {
172- qCWarning(QTMIR_MIR_INPUT)
173- << "There's a touch (id =" << it.key() << ") missing. Releasing it.";
174- it.value().state = Qt::TouchPointReleased;
175- touchPoints.append(it.value());
176- it = mActiveTouches.erase(it);
177- } else {
178- ++it;
179- }
180- }
181- }
182+ // Release all unmentioned touches, one by one.
183+ QHash<int, QWindowSystemInterface::TouchPoint>::iterator it = mActiveTouches.begin();
184+ while (it != mActiveTouches.end()) {
185+ if (!updatedTouches.contains(it.key())) {
186+ qCWarning(QTMIR_MIR_INPUT)
187+ << "There's a touch (id =" << it.key() << ") missing. Releasing it.";
188+ sendActiveTouchRelease(timestamp, it.key());
189+ it = mActiveTouches.erase(it);
190+ } else {
191+ ++it;
192+ }
193+ }
194+
195+ // update mActiveTouches
196+ for (int i = 0; i < touchPoints.count(); ++i) {
197+ auto &touchPoint = touchPoints.at(i);
198+ if (touchPoint.state == Qt::TouchPointReleased) {
199+ mActiveTouches.remove(touchPoint.id);
200+ } else {
201+ mActiveTouches[touchPoint.id] = touchPoint;
202+ }
203+ }
204+}
205+
206+void QtEventFeeder::sendActiveTouchRelease(ulong timestamp, int id)
207+{
208+ QList<QWindowSystemInterface::TouchPoint> touchPoints = mActiveTouches.values();
209+
210+ for (int i = 0; i < touchPoints.count(); ++i) {
211+ QWindowSystemInterface::TouchPoint &touchPoint = touchPoints[i];
212+ if (touchPoint.id == id) {
213+ touchPoint.state = Qt::TouchPointReleased;
214+ } else {
215+ touchPoint.state = Qt::TouchPointStationary;
216+ }
217+ }
218+
219+ qCDebug(QTMIR_MIR_INPUT) << "Sending to Qt" << qPrintable(touchesToString(touchPoints));
220+ mQtWindowSystem->handleTouchEvent(timestamp, mTouchDevice, touchPoints);
221 }
222
223 bool QtEventFeeder::validateTouch(QWindowSystemInterface::TouchPoint &touchPoint)
224@@ -475,7 +505,6 @@
225 << "). Making it move instead.";
226 touchPoint.state = Qt::TouchPointMoved;
227 }
228- mActiveTouches[touchPoint.id] = touchPoint;
229 break;
230 case Qt::TouchPointMoved:
231 if (!mActiveTouches.contains(touchPoint.id)) {
232@@ -484,7 +513,6 @@
233 << "). Making it press instead.";
234 touchPoint.state = Qt::TouchPointPressed;
235 }
236- mActiveTouches[touchPoint.id] = touchPoint;
237 break;
238 case Qt::TouchPointStationary:
239 if (!mActiveTouches.contains(touchPoint.id)) {
240@@ -493,7 +521,6 @@
241 << "). Making it press instead.";
242 touchPoint.state = Qt::TouchPointPressed;
243 }
244- mActiveTouches[touchPoint.id] = touchPoint;
245 break;
246 case Qt::TouchPointReleased:
247 if (!mActiveTouches.contains(touchPoint.id)) {
248@@ -501,8 +528,6 @@
249 << "Would release a touch that wasn't pressed before (id =" << touchPoint.id
250 << "). Ignoring it.";
251 ok = false;
252- } else {
253- mActiveTouches.remove(touchPoint.id);
254 }
255 break;
256 default:
257@@ -511,3 +536,21 @@
258
259 return ok;
260 }
261+
262+QString QtEventFeeder::touchesToString(const QList<struct QWindowSystemInterface::TouchPoint> &points)
263+{
264+ QString result;
265+ for (int i = 0; i < points.count(); ++i) {
266+ if (i > 0) {
267+ result.append(",");
268+ }
269+ const struct QWindowSystemInterface::TouchPoint &point = points.at(i);
270+ result.append(QString("(id=%1,state=%2,normalPosition=(%3,%4))")
271+ .arg(point.id)
272+ .arg(touchPointStateToString(point.state))
273+ .arg(point.normalPosition.x())
274+ .arg(point.normalPosition.y())
275+ );
276+ }
277+ return result;
278+}
279
280=== modified file 'src/platforms/mirserver/qteventfeeder.h'
281--- src/platforms/mirserver/qteventfeeder.h 2015-02-19 23:03:14 +0000
282+++ src/platforms/mirserver/qteventfeeder.h 2015-04-16 13:38:31 +0000
283@@ -71,8 +71,11 @@
284 void dispatchKey(MirInputEvent const* event);
285 void dispatchTouch(MirInputEvent const* event);
286 void dispatchPointer(MirInputEvent const* event);
287- void validateTouches(QList<QWindowSystemInterface::TouchPoint> &touchPoints);
288+ void validateTouches(ulong timestamp, QList<QWindowSystemInterface::TouchPoint> &touchPoints);
289 bool validateTouch(QWindowSystemInterface::TouchPoint &touchPoint);
290+ void sendActiveTouchRelease(ulong timestamp, int id);
291+
292+ QString touchesToString(const QList<struct QWindowSystemInterface::TouchPoint> &points);
293
294 QTouchDevice *mTouchDevice;
295 QtWindowSystemInterface *mQtWindowSystem;
296
297=== modified file 'tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h'
298--- tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h 2015-02-19 23:03:14 +0000
299+++ tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h 2015-04-16 13:38:31 +0000
300@@ -50,6 +50,11 @@
301 return arg.state == Qt::TouchPointReleased;
302 }
303
304+MATCHER(IsStationary, std::string(negation ? "isn't" : "is") + " stationary")
305+{
306+ return arg.state == Qt::TouchPointStationary;
307+}
308+
309 MATCHER(StateIsMoved, "state " + std::string(negation ? "isn't" : "is") + " 'moved'")
310 {
311 return arg.state == Qt::TouchPointMoved;
312
313=== modified file 'tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp'
314--- tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp 2015-02-19 23:03:14 +0000
315+++ tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp 2015-04-16 13:38:31 +0000
316@@ -40,10 +40,12 @@
317
318 // own gmock extensions
319 using ::testing::IsPressed;
320+using ::testing::IsStationary;
321 using ::testing::IsReleased;
322 using ::testing::HasId;
323 using ::testing::StateIsMoved;
324
325+// used by google mock in error messages
326 void PrintTo(const struct QWindowSystemInterface::TouchPoint& touchPoint, ::std::ostream* os) {
327 *os << "TouchPoint("
328 << "id=" << touchPoint.id
329@@ -51,6 +53,12 @@
330 << ")";
331 }
332
333+::std::ostream& operator<<(::std::ostream& os, QTouchDevice*) {
334+ // actually don't care about its contents. Just to avoit having a raw
335+ // pointer address being printed in google mock error messages.
336+ return os << "QTouchDevice*";
337+}
338+
339 class QtEventFeederTest : public ::testing::Test {
340 protected:
341 void SetUp() override;
342@@ -96,7 +104,7 @@
343 Then, Mir sends a MirEvent([touch(id=1,state=pressed)]). In MirEvents, every single active touch
344 point must be listed in the event even if it didn't change at all in the meantime. So that's a bug.
345 But instead of crashing or forwarding the bogus event stream down to Qt, QtEventFeeder should attempt
346- to fix the situation by synthesizing a touch[id=1,state=released] to be send along with the
347+ to fix the situation by synthesizing a touch[id=0,state=released] to be send along with the
348 touch(id=1,state=pressed) it got. So that Qt receives a correct touch event stream.
349 */
350 TEST_F(QtEventFeederTest, GenerateMissingTouchEnd)
351@@ -126,22 +134,133 @@
352
353 setIrrelevantMockWindowSystemExpectations();
354
355- EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,_,AllOf(SizeIs(2),
356- Contains(AllOf(HasId(0),IsReleased())),
357- Contains(AllOf(HasId(1),IsPressed()))
358- ),_)).Times(1);
359-
360- mirEvent.type = mir_event_type_motion;
361- mirEvent.motion.pointer_count = 1;
362- mirEvent.motion.pointer_coordinates[0].id = 1;
363- mirEvent.motion.pointer_coordinates[0].x = 20;
364- mirEvent.motion.pointer_coordinates[0].y = 20;
365- mirEvent.motion.pointer_coordinates[0].touch_major = 1;
366- mirEvent.motion.pointer_coordinates[0].touch_minor = 1;
367- mirEvent.motion.pointer_coordinates[0].pressure = 10;
368- mirEvent.motion.action = mir_motion_action_down;
369- mirEvent.motion.event_time = 125 * 1000000;
370-
371+ // There can be only one pressed or released touch per event
372+ {
373+ InSequence sequence;
374+
375+ EXPECT_CALL(*mockWindowSystem,
376+ handleTouchEvent(_,_,AllOf(SizeIs(1),
377+ Contains(AllOf(HasId(0),IsReleased()))
378+ ),_)).Times(1);
379+
380+ EXPECT_CALL(*mockWindowSystem,
381+ handleTouchEvent(_,_,AllOf(SizeIs(1),
382+ Contains(AllOf(HasId(1),IsPressed()))
383+ ),_)).Times(1);
384+ }
385+
386+ mirEvent.type = mir_event_type_motion;
387+ mirEvent.motion.pointer_count = 1;
388+ mirEvent.motion.pointer_coordinates[0].id = 1;
389+ mirEvent.motion.pointer_coordinates[0].x = 20;
390+ mirEvent.motion.pointer_coordinates[0].y = 20;
391+ mirEvent.motion.pointer_coordinates[0].touch_major = 1;
392+ mirEvent.motion.pointer_coordinates[0].touch_minor = 1;
393+ mirEvent.motion.pointer_coordinates[0].pressure = 10;
394+ mirEvent.motion.action = mir_motion_action_down;
395+ mirEvent.motion.event_time = 125 * 1000000;
396+
397+ qtEventFeeder->dispatch(mirEvent);
398+
399+ ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
400+}
401+
402+TEST_F(QtEventFeederTest, GenerateMissingTouchEnd2)
403+{
404+
405+ setIrrelevantMockWindowSystemExpectations();
406+
407+
408+ MirEvent mirEvent;
409+ mirEvent.type = mir_event_type_motion;
410+ mirEvent.motion.pointer_count = 1;
411+ mirEvent.motion.action = mir_motion_action_down;
412+ mirEvent.motion.pointer_coordinates[0].id = 0;
413+ mirEvent.motion.pointer_coordinates[0].x = 10;
414+ mirEvent.motion.pointer_coordinates[0].y = 10;
415+ mirEvent.motion.pointer_coordinates[0].touch_major = 1;
416+ mirEvent.motion.pointer_coordinates[0].touch_minor = 1;
417+ mirEvent.motion.pointer_coordinates[0].pressure = 10;
418+ mirEvent.motion.event_time = 123 * 1000000;
419+
420+ EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,_,AllOf(SizeIs(1),
421+ Contains(AllOf(HasId(0),
422+ IsPressed()))),_)).Times(1);
423+ qtEventFeeder->dispatch(mirEvent);
424+
425+ ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
426+
427+ // ---
428+
429+ setIrrelevantMockWindowSystemExpectations();
430+
431+ mirEvent.type = mir_event_type_motion;
432+ mirEvent.motion.pointer_count = 2;
433+ mirEvent.motion.action = mir_motion_action_pointer_down | (1 /*pointer index*/ << 8 /*shift*/);
434+ mirEvent.motion.pointer_coordinates[0].id = 0;
435+ mirEvent.motion.pointer_coordinates[0].x = 10;
436+ mirEvent.motion.pointer_coordinates[0].y = 10;
437+ mirEvent.motion.pointer_coordinates[0].touch_major = 1;
438+ mirEvent.motion.pointer_coordinates[0].touch_minor = 1;
439+ mirEvent.motion.pointer_coordinates[0].pressure = 10;
440+ mirEvent.motion.pointer_coordinates[1].id = 1;
441+ mirEvent.motion.pointer_coordinates[1].x = 20;
442+ mirEvent.motion.pointer_coordinates[1].y = 20;
443+ mirEvent.motion.pointer_coordinates[1].touch_major = 1;
444+ mirEvent.motion.pointer_coordinates[1].touch_minor = 1;
445+ mirEvent.motion.pointer_coordinates[1].pressure = 10;
446+ mirEvent.motion.event_time = 124 * 1000000;
447+
448+ EXPECT_CALL(*mockWindowSystem,
449+ handleTouchEvent(_,_,AllOf(SizeIs(2),
450+ Contains(AllOf(HasId(0), StateIsMoved())),
451+ Contains(AllOf(HasId(1), IsPressed()))
452+ ),_)).Times(1);
453+ qtEventFeeder->dispatch(mirEvent);
454+
455+ ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
456+
457+ // ---
458+
459+ setIrrelevantMockWindowSystemExpectations();
460+
461+ // touch 0 disappeared and touch 2 got pressed
462+ mirEvent.type = mir_event_type_motion;
463+ mirEvent.motion.pointer_count = 2;
464+ mirEvent.motion.action = mir_motion_action_pointer_down | (1 /*pointer index*/ << 8 /*shift*/);
465+ mirEvent.motion.pointer_coordinates[0].id = 1;
466+ mirEvent.motion.pointer_coordinates[0].x = 20;
467+ mirEvent.motion.pointer_coordinates[0].y = 20;
468+ mirEvent.motion.pointer_coordinates[0].touch_major = 1;
469+ mirEvent.motion.pointer_coordinates[0].touch_minor = 1;
470+ mirEvent.motion.pointer_coordinates[0].pressure = 10;
471+ mirEvent.motion.pointer_coordinates[1].id = 2;
472+ mirEvent.motion.pointer_coordinates[1].x = 30;
473+ mirEvent.motion.pointer_coordinates[1].y = 30;
474+ mirEvent.motion.pointer_coordinates[1].touch_major = 1;
475+ mirEvent.motion.pointer_coordinates[1].touch_minor = 1;
476+ mirEvent.motion.pointer_coordinates[1].pressure = 10;
477+ mirEvent.motion.event_time = 125 * 1000000;
478+
479+ // There can be only one pressed or released touch per event
480+ {
481+ InSequence sequence;
482+
483+ // first release touch 0
484+ EXPECT_CALL(*mockWindowSystem,
485+ handleTouchEvent(_,_,AllOf(SizeIs(2),
486+ Contains(AllOf(HasId(0), IsReleased())),
487+ Contains(AllOf(HasId(1), IsStationary()))
488+ ),_)).Times(1);
489+
490+ // then press touch 2
491+ EXPECT_CALL(*mockWindowSystem,
492+ handleTouchEvent(_,_,AllOf(SizeIs(2),
493+ Contains(AllOf(HasId(1), StateIsMoved())),
494+ Contains(AllOf(HasId(2), IsPressed()))
495+ ),_)).Times(1);
496+
497+ }
498 qtEventFeeder->dispatch(mirEvent);
499
500 ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
501@@ -192,4 +311,3 @@
502
503 ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
504 }
505-

Subscribers

People subscribed via source and target branches