Merge lp:~dandrader/qtmir/oneUpDownPerEvent-lp1437357 into lp:qtmir
- oneUpDownPerEvent-lp1437357
- Merge into trunk
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 | ||||
Related bugs: |
|
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.
- 330. By Daniel d'Andrada
-
Remove leftover
PS Jenkins bot (ps-jenkins) wrote : | # |
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 "../../
better to include ../../common as a source of headers
-Q_LOGGING_
+Q_LOGGING_
what does this give us?
Was unable to reproduce a crash on devel-proposed, but I find no regressions while testing it
- 331. By Daniel d'Andrada
-
add src/common to platform/mirserver include dirs
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:/
>
>
> +#include "../../
> better to include ../../common as a source of headers
Done.
> -Q_LOGGING_
> +Q_LOGGING_
> 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.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:331
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Gerry Boland (gerboland) wrote : | # |
LGTM, thank you
Preview Diff
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 | - |
PASSED: Continuous integration, rev:330 jenkins. qa.ubuntu. com/job/ qtmir-ci/ 245/ jenkins. qa.ubuntu. com/job/ qtmir-vivid- amd64-ci/ 96 jenkins. qa.ubuntu. com/job/ qtmir-vivid- armhf-ci/ 96 jenkins. qa.ubuntu. com/job/ qtmir-vivid- armhf-ci/ 96/artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/qtmir- ci/245/ rebuild
http://