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
=== modified file 'src/common/debughelpers.cpp'
--- src/common/debughelpers.cpp 2015-02-19 23:03:14 +0000
+++ src/common/debughelpers.cpp 2015-04-16 13:38:31 +0000
@@ -207,3 +207,50 @@
207 return "???";207 return "???";
208 }208 }
209}209}
210
211QString mirTouchEventToString(MirTouchInputEvent const* event)
212{
213 const int pointerCount = mir_touch_input_event_get_touch_count(event);
214
215 QString string("MirTouchInputEvent(");
216
217 for (int i = 0; i < pointerCount; ++i) {
218
219 if (i > 0) {
220 string.append(",");
221 }
222
223 MirTouchInputEventTouchAction touchAction = mir_touch_input_event_get_touch_action(event, i);
224
225 QString touchStr = QString("(id=%1,action=%2,x=%3,y=%4)")
226 .arg(mir_touch_input_event_get_touch_id(event, i))
227 .arg(mirTouchActionToString(touchAction))
228 .arg(mir_touch_input_event_get_touch_axis_value(event, i, mir_touch_input_axis_x))
229 .arg(mir_touch_input_event_get_touch_axis_value(event, i, mir_touch_input_axis_y));
230
231 string.append(touchStr);
232 }
233
234 string.append(")");
235
236 return string;
237}
238
239const char *mirTouchActionToString(MirTouchInputEventTouchAction touchAction)
240{
241 switch (touchAction)
242 {
243 case mir_touch_input_event_action_up:
244 return "up";
245 break;
246 case mir_touch_input_event_action_down:
247 return "down";
248 break;
249 case mir_touch_input_event_action_change:
250 return "change";
251 break;
252 default:
253 return "???";
254 break;
255 }
256}
210257
=== modified file 'src/common/debughelpers.h'
--- src/common/debughelpers.h 2014-08-27 11:51:28 +0000
+++ src/common/debughelpers.h 2015-04-16 13:38:31 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2013-2014 Canonical, Ltd.2 * Copyright (C) 2013-2015 Canonical, Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it under4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by5 * the terms of the GNU Lesser General Public License version 3, as published by
@@ -20,6 +20,7 @@
20#include <QString>20#include <QString>
2121
22#include <mir_toolkit/common.h>22#include <mir_toolkit/common.h>
23#include <mir_toolkit/events/input/input_event.h>
2324
24class QTouchEvent;25class QTouchEvent;
2526
@@ -35,4 +36,7 @@
3536
36const char *applicationStateToStr(int state);37const char *applicationStateToStr(int state);
3738
39QString mirTouchEventToString(MirTouchInputEvent const* event);
40const char *mirTouchActionToString(MirTouchInputEventTouchAction touchAction);
41
38#endif // UBUNTUGESTURES_DEBUG_HELPER_H42#endif // UBUNTUGESTURES_DEBUG_HELPER_H
3943
=== modified file 'src/platforms/mirserver/CMakeLists.txt'
--- src/platforms/mirserver/CMakeLists.txt 2015-01-28 14:25:36 +0000
+++ src/platforms/mirserver/CMakeLists.txt 2015-04-16 13:38:31 +0000
@@ -18,9 +18,11 @@
18endforeach(item ${Qt5Gui_PRIVATE_INCLUDE_DIRS})18endforeach(item ${Qt5Gui_PRIVATE_INCLUDE_DIRS})
1919
20include_directories(20include_directories(
21 ${CMAKE_SOURCE_DIR}/src/common
22
21 ${MIRCOMMON_INCLUDE_DIRS}23 ${MIRCOMMON_INCLUDE_DIRS}
22 ${MIRSERVER_INCLUDE_DIRS}24 ${MIRSERVER_INCLUDE_DIRS}
23 25
24 ${URL_DISPATCHER_INCLUDE_DIRS}26 ${URL_DISPATCHER_INCLUDE_DIRS}
25 ${PROTOBUF_INCLUDE_DIRS}27 ${PROTOBUF_INCLUDE_DIRS}
26 ${EGL_INCLUDE_DIRS}28 ${EGL_INCLUDE_DIRS}
@@ -37,7 +39,7 @@
37add_definitions(-DBYTE_ORDER=__BYTE_ORDER)39add_definitions(-DBYTE_ORDER=__BYTE_ORDER)
3840
39set(MIRSERVER_QPA_PLUGIN_SRC41set(MIRSERVER_QPA_PLUGIN_SRC
40 ../../common/debughelpers.cpp42 ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
41 mirshell.cpp43 mirshell.cpp
42 qteventfeeder.cpp44 qteventfeeder.cpp
43 plugin.cpp45 plugin.cpp
@@ -74,7 +76,7 @@
74 ${EGL_LDFLAGS}76 ${EGL_LDFLAGS}
75 ${GL_LIBRARIES}77 ${GL_LIBRARIES}
76 ${LTTNG_LIBRARIES}78 ${LTTNG_LIBRARIES}
77 79
78 ${QT5PLATFORM_SUPPORT_LDFLAGS}80 ${QT5PLATFORM_SUPPORT_LDFLAGS}
79 # TODO Qt5Platform support LDFLAGS dont provide actual required ldflags...81 # TODO Qt5Platform support LDFLAGS dont provide actual required ldflags...
80 # I found these were needed...perhaps there is some way to query qmake/qconfig?82 # I found these were needed...perhaps there is some way to query qmake/qconfig?
8183
=== modified file 'src/platforms/mirserver/qteventfeeder.cpp'
--- src/platforms/mirserver/qteventfeeder.cpp 2015-02-19 23:03:14 +0000
+++ src/platforms/mirserver/qteventfeeder.cpp 2015-04-16 13:38:31 +0000
@@ -30,7 +30,10 @@
3030
31#include <QDebug>31#include <QDebug>
3232
33Q_LOGGING_CATEGORY(QTMIR_MIR_INPUT, "qtmir.mir.input")33// common dir
34#include <debughelpers.h>
35
36Q_LOGGING_CATEGORY(QTMIR_MIR_INPUT, "qtmir.mir.input", QtWarningMsg)
3437
35// XKB Keysyms which do not map directly to Qt types (i.e. Unicode points)38// XKB Keysyms which do not map directly to Qt types (i.e. Unicode points)
36static const uint32_t KeyTable[] = {39static const uint32_t KeyTable[] = {
@@ -355,6 +358,7 @@
355 return;358 return;
356359
357 auto tev = mir_input_event_get_touch_input_event(event);360 auto tev = mir_input_event_get_touch_input_event(event);
361 qCDebug(QTMIR_MIR_INPUT) << "Received" << qPrintable(mirTouchEventToString(tev));
358362
359 // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That363 // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That
360 // needs to be fixed as soon as the compat input lib adds query support.364 // needs to be fixed as soon as the compat input lib adds query support.
@@ -398,9 +402,10 @@
398402
399 // Qt needs a happy, sane stream of touch events. So let's make sure we're not forwarding403 // Qt needs a happy, sane stream of touch events. So let's make sure we're not forwarding
400 // any insanity.404 // any insanity.
401 validateTouches(touchPoints);405 validateTouches(mir_input_event_get_event_time(event) / 1000000, touchPoints);
402406
403 // Touch event propagation.407 // Touch event propagation.
408 qCDebug(QTMIR_MIR_INPUT) << "Sending to Qt" << qPrintable(touchesToString(touchPoints));
404 mQtWindowSystem->handleTouchEvent(409 mQtWindowSystem->handleTouchEvent(
405 //scales down the nsec_t (int64) to fit a ulong, precision lost but time difference suitable410 //scales down the nsec_t (int64) to fit a ulong, precision lost but time difference suitable
406 mir_input_event_get_event_time(event) / 1000000,411 mir_input_event_get_event_time(event) / 1000000,
@@ -429,7 +434,8 @@
429 Q_UNUSED(when);434 Q_UNUSED(when);
430}435}
431436
432void QtEventFeeder::validateTouches(QList<QWindowSystemInterface::TouchPoint> &touchPoints)437void QtEventFeeder::validateTouches(ulong timestamp,
438 QList<QWindowSystemInterface::TouchPoint> &touchPoints)
433{439{
434 QSet<int> updatedTouches;440 QSet<int> updatedTouches;
435441
@@ -446,21 +452,45 @@
446 }452 }
447 }453 }
448454
449 // Release all unmentioned touches.455 // Release all unmentioned touches, one by one.
450 {456 QHash<int, QWindowSystemInterface::TouchPoint>::iterator it = mActiveTouches.begin();
451 QHash<int, QWindowSystemInterface::TouchPoint>::iterator it = mActiveTouches.begin();457 while (it != mActiveTouches.end()) {
452 while (it != mActiveTouches.end()) {458 if (!updatedTouches.contains(it.key())) {
453 if (!updatedTouches.contains(it.key())) {459 qCWarning(QTMIR_MIR_INPUT)
454 qCWarning(QTMIR_MIR_INPUT)460 << "There's a touch (id =" << it.key() << ") missing. Releasing it.";
455 << "There's a touch (id =" << it.key() << ") missing. Releasing it.";461 sendActiveTouchRelease(timestamp, it.key());
456 it.value().state = Qt::TouchPointReleased;462 it = mActiveTouches.erase(it);
457 touchPoints.append(it.value());463 } else {
458 it = mActiveTouches.erase(it);464 ++it;
459 } else {465 }
460 ++it;466 }
461 }467
462 }468 // update mActiveTouches
463 }469 for (int i = 0; i < touchPoints.count(); ++i) {
470 auto &touchPoint = touchPoints.at(i);
471 if (touchPoint.state == Qt::TouchPointReleased) {
472 mActiveTouches.remove(touchPoint.id);
473 } else {
474 mActiveTouches[touchPoint.id] = touchPoint;
475 }
476 }
477}
478
479void QtEventFeeder::sendActiveTouchRelease(ulong timestamp, int id)
480{
481 QList<QWindowSystemInterface::TouchPoint> touchPoints = mActiveTouches.values();
482
483 for (int i = 0; i < touchPoints.count(); ++i) {
484 QWindowSystemInterface::TouchPoint &touchPoint = touchPoints[i];
485 if (touchPoint.id == id) {
486 touchPoint.state = Qt::TouchPointReleased;
487 } else {
488 touchPoint.state = Qt::TouchPointStationary;
489 }
490 }
491
492 qCDebug(QTMIR_MIR_INPUT) << "Sending to Qt" << qPrintable(touchesToString(touchPoints));
493 mQtWindowSystem->handleTouchEvent(timestamp, mTouchDevice, touchPoints);
464}494}
465495
466bool QtEventFeeder::validateTouch(QWindowSystemInterface::TouchPoint &touchPoint)496bool QtEventFeeder::validateTouch(QWindowSystemInterface::TouchPoint &touchPoint)
@@ -475,7 +505,6 @@
475 << "). Making it move instead.";505 << "). Making it move instead.";
476 touchPoint.state = Qt::TouchPointMoved;506 touchPoint.state = Qt::TouchPointMoved;
477 }507 }
478 mActiveTouches[touchPoint.id] = touchPoint;
479 break;508 break;
480 case Qt::TouchPointMoved:509 case Qt::TouchPointMoved:
481 if (!mActiveTouches.contains(touchPoint.id)) {510 if (!mActiveTouches.contains(touchPoint.id)) {
@@ -484,7 +513,6 @@
484 << "). Making it press instead.";513 << "). Making it press instead.";
485 touchPoint.state = Qt::TouchPointPressed;514 touchPoint.state = Qt::TouchPointPressed;
486 }515 }
487 mActiveTouches[touchPoint.id] = touchPoint;
488 break;516 break;
489 case Qt::TouchPointStationary:517 case Qt::TouchPointStationary:
490 if (!mActiveTouches.contains(touchPoint.id)) {518 if (!mActiveTouches.contains(touchPoint.id)) {
@@ -493,7 +521,6 @@
493 << "). Making it press instead.";521 << "). Making it press instead.";
494 touchPoint.state = Qt::TouchPointPressed;522 touchPoint.state = Qt::TouchPointPressed;
495 }523 }
496 mActiveTouches[touchPoint.id] = touchPoint;
497 break;524 break;
498 case Qt::TouchPointReleased:525 case Qt::TouchPointReleased:
499 if (!mActiveTouches.contains(touchPoint.id)) {526 if (!mActiveTouches.contains(touchPoint.id)) {
@@ -501,8 +528,6 @@
501 << "Would release a touch that wasn't pressed before (id =" << touchPoint.id528 << "Would release a touch that wasn't pressed before (id =" << touchPoint.id
502 << "). Ignoring it.";529 << "). Ignoring it.";
503 ok = false;530 ok = false;
504 } else {
505 mActiveTouches.remove(touchPoint.id);
506 }531 }
507 break;532 break;
508 default:533 default:
@@ -511,3 +536,21 @@
511536
512 return ok;537 return ok;
513}538}
539
540QString QtEventFeeder::touchesToString(const QList<struct QWindowSystemInterface::TouchPoint> &points)
541{
542 QString result;
543 for (int i = 0; i < points.count(); ++i) {
544 if (i > 0) {
545 result.append(",");
546 }
547 const struct QWindowSystemInterface::TouchPoint &point = points.at(i);
548 result.append(QString("(id=%1,state=%2,normalPosition=(%3,%4))")
549 .arg(point.id)
550 .arg(touchPointStateToString(point.state))
551 .arg(point.normalPosition.x())
552 .arg(point.normalPosition.y())
553 );
554 }
555 return result;
556}
514557
=== modified file 'src/platforms/mirserver/qteventfeeder.h'
--- src/platforms/mirserver/qteventfeeder.h 2015-02-19 23:03:14 +0000
+++ src/platforms/mirserver/qteventfeeder.h 2015-04-16 13:38:31 +0000
@@ -71,8 +71,11 @@
71 void dispatchKey(MirInputEvent const* event);71 void dispatchKey(MirInputEvent const* event);
72 void dispatchTouch(MirInputEvent const* event);72 void dispatchTouch(MirInputEvent const* event);
73 void dispatchPointer(MirInputEvent const* event);73 void dispatchPointer(MirInputEvent const* event);
74 void validateTouches(QList<QWindowSystemInterface::TouchPoint> &touchPoints);74 void validateTouches(ulong timestamp, QList<QWindowSystemInterface::TouchPoint> &touchPoints);
75 bool validateTouch(QWindowSystemInterface::TouchPoint &touchPoint);75 bool validateTouch(QWindowSystemInterface::TouchPoint &touchPoint);
76 void sendActiveTouchRelease(ulong timestamp, int id);
77
78 QString touchesToString(const QList<struct QWindowSystemInterface::TouchPoint> &points);
7679
77 QTouchDevice *mTouchDevice;80 QTouchDevice *mTouchDevice;
78 QtWindowSystemInterface *mQtWindowSystem;81 QtWindowSystemInterface *mQtWindowSystem;
7982
=== modified file 'tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h'
--- tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h 2015-02-19 23:03:14 +0000
+++ tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h 2015-04-16 13:38:31 +0000
@@ -50,6 +50,11 @@
50 return arg.state == Qt::TouchPointReleased;50 return arg.state == Qt::TouchPointReleased;
51}51}
5252
53MATCHER(IsStationary, std::string(negation ? "isn't" : "is") + " stationary")
54{
55 return arg.state == Qt::TouchPointStationary;
56}
57
53MATCHER(StateIsMoved, "state " + std::string(negation ? "isn't" : "is") + " 'moved'")58MATCHER(StateIsMoved, "state " + std::string(negation ? "isn't" : "is") + " 'moved'")
54{59{
55 return arg.state == Qt::TouchPointMoved;60 return arg.state == Qt::TouchPointMoved;
5661
=== modified file 'tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp'
--- tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp 2015-02-19 23:03:14 +0000
+++ tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp 2015-04-16 13:38:31 +0000
@@ -40,10 +40,12 @@
4040
41// own gmock extensions41// own gmock extensions
42using ::testing::IsPressed;42using ::testing::IsPressed;
43using ::testing::IsStationary;
43using ::testing::IsReleased;44using ::testing::IsReleased;
44using ::testing::HasId;45using ::testing::HasId;
45using ::testing::StateIsMoved;46using ::testing::StateIsMoved;
4647
48// used by google mock in error messages
47void PrintTo(const struct QWindowSystemInterface::TouchPoint& touchPoint, ::std::ostream* os) {49void PrintTo(const struct QWindowSystemInterface::TouchPoint& touchPoint, ::std::ostream* os) {
48 *os << "TouchPoint("50 *os << "TouchPoint("
49 << "id=" << touchPoint.id51 << "id=" << touchPoint.id
@@ -51,6 +53,12 @@
51 << ")";53 << ")";
52}54}
5355
56::std::ostream& operator<<(::std::ostream& os, QTouchDevice*) {
57 // actually don't care about its contents. Just to avoit having a raw
58 // pointer address being printed in google mock error messages.
59 return os << "QTouchDevice*";
60}
61
54class QtEventFeederTest : public ::testing::Test {62class QtEventFeederTest : public ::testing::Test {
55protected:63protected:
56 void SetUp() override;64 void SetUp() override;
@@ -96,7 +104,7 @@
96 Then, Mir sends a MirEvent([touch(id=1,state=pressed)]). In MirEvents, every single active touch104 Then, Mir sends a MirEvent([touch(id=1,state=pressed)]). In MirEvents, every single active touch
97 point must be listed in the event even if it didn't change at all in the meantime. So that's a bug.105 point must be listed in the event even if it didn't change at all in the meantime. So that's a bug.
98 But instead of crashing or forwarding the bogus event stream down to Qt, QtEventFeeder should attempt106 But instead of crashing or forwarding the bogus event stream down to Qt, QtEventFeeder should attempt
99 to fix the situation by synthesizing a touch[id=1,state=released] to be send along with the107 to fix the situation by synthesizing a touch[id=0,state=released] to be send along with the
100 touch(id=1,state=pressed) it got. So that Qt receives a correct touch event stream.108 touch(id=1,state=pressed) it got. So that Qt receives a correct touch event stream.
101 */109 */
102TEST_F(QtEventFeederTest, GenerateMissingTouchEnd)110TEST_F(QtEventFeederTest, GenerateMissingTouchEnd)
@@ -126,22 +134,133 @@
126134
127 setIrrelevantMockWindowSystemExpectations();135 setIrrelevantMockWindowSystemExpectations();
128136
129 EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,_,AllOf(SizeIs(2),137 // There can be only one pressed or released touch per event
130 Contains(AllOf(HasId(0),IsReleased())),138 {
131 Contains(AllOf(HasId(1),IsPressed()))139 InSequence sequence;
132 ),_)).Times(1);140
133141 EXPECT_CALL(*mockWindowSystem,
134 mirEvent.type = mir_event_type_motion;142 handleTouchEvent(_,_,AllOf(SizeIs(1),
135 mirEvent.motion.pointer_count = 1;143 Contains(AllOf(HasId(0),IsReleased()))
136 mirEvent.motion.pointer_coordinates[0].id = 1;144 ),_)).Times(1);
137 mirEvent.motion.pointer_coordinates[0].x = 20;145
138 mirEvent.motion.pointer_coordinates[0].y = 20;146 EXPECT_CALL(*mockWindowSystem,
139 mirEvent.motion.pointer_coordinates[0].touch_major = 1;147 handleTouchEvent(_,_,AllOf(SizeIs(1),
140 mirEvent.motion.pointer_coordinates[0].touch_minor = 1;148 Contains(AllOf(HasId(1),IsPressed()))
141 mirEvent.motion.pointer_coordinates[0].pressure = 10;149 ),_)).Times(1);
142 mirEvent.motion.action = mir_motion_action_down;150 }
143 mirEvent.motion.event_time = 125 * 1000000;151
144152 mirEvent.type = mir_event_type_motion;
153 mirEvent.motion.pointer_count = 1;
154 mirEvent.motion.pointer_coordinates[0].id = 1;
155 mirEvent.motion.pointer_coordinates[0].x = 20;
156 mirEvent.motion.pointer_coordinates[0].y = 20;
157 mirEvent.motion.pointer_coordinates[0].touch_major = 1;
158 mirEvent.motion.pointer_coordinates[0].touch_minor = 1;
159 mirEvent.motion.pointer_coordinates[0].pressure = 10;
160 mirEvent.motion.action = mir_motion_action_down;
161 mirEvent.motion.event_time = 125 * 1000000;
162
163 qtEventFeeder->dispatch(mirEvent);
164
165 ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
166}
167
168TEST_F(QtEventFeederTest, GenerateMissingTouchEnd2)
169{
170
171 setIrrelevantMockWindowSystemExpectations();
172
173
174 MirEvent mirEvent;
175 mirEvent.type = mir_event_type_motion;
176 mirEvent.motion.pointer_count = 1;
177 mirEvent.motion.action = mir_motion_action_down;
178 mirEvent.motion.pointer_coordinates[0].id = 0;
179 mirEvent.motion.pointer_coordinates[0].x = 10;
180 mirEvent.motion.pointer_coordinates[0].y = 10;
181 mirEvent.motion.pointer_coordinates[0].touch_major = 1;
182 mirEvent.motion.pointer_coordinates[0].touch_minor = 1;
183 mirEvent.motion.pointer_coordinates[0].pressure = 10;
184 mirEvent.motion.event_time = 123 * 1000000;
185
186 EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,_,AllOf(SizeIs(1),
187 Contains(AllOf(HasId(0),
188 IsPressed()))),_)).Times(1);
189 qtEventFeeder->dispatch(mirEvent);
190
191 ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
192
193 // ---
194
195 setIrrelevantMockWindowSystemExpectations();
196
197 mirEvent.type = mir_event_type_motion;
198 mirEvent.motion.pointer_count = 2;
199 mirEvent.motion.action = mir_motion_action_pointer_down | (1 /*pointer index*/ << 8 /*shift*/);
200 mirEvent.motion.pointer_coordinates[0].id = 0;
201 mirEvent.motion.pointer_coordinates[0].x = 10;
202 mirEvent.motion.pointer_coordinates[0].y = 10;
203 mirEvent.motion.pointer_coordinates[0].touch_major = 1;
204 mirEvent.motion.pointer_coordinates[0].touch_minor = 1;
205 mirEvent.motion.pointer_coordinates[0].pressure = 10;
206 mirEvent.motion.pointer_coordinates[1].id = 1;
207 mirEvent.motion.pointer_coordinates[1].x = 20;
208 mirEvent.motion.pointer_coordinates[1].y = 20;
209 mirEvent.motion.pointer_coordinates[1].touch_major = 1;
210 mirEvent.motion.pointer_coordinates[1].touch_minor = 1;
211 mirEvent.motion.pointer_coordinates[1].pressure = 10;
212 mirEvent.motion.event_time = 124 * 1000000;
213
214 EXPECT_CALL(*mockWindowSystem,
215 handleTouchEvent(_,_,AllOf(SizeIs(2),
216 Contains(AllOf(HasId(0), StateIsMoved())),
217 Contains(AllOf(HasId(1), IsPressed()))
218 ),_)).Times(1);
219 qtEventFeeder->dispatch(mirEvent);
220
221 ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
222
223 // ---
224
225 setIrrelevantMockWindowSystemExpectations();
226
227 // touch 0 disappeared and touch 2 got pressed
228 mirEvent.type = mir_event_type_motion;
229 mirEvent.motion.pointer_count = 2;
230 mirEvent.motion.action = mir_motion_action_pointer_down | (1 /*pointer index*/ << 8 /*shift*/);
231 mirEvent.motion.pointer_coordinates[0].id = 1;
232 mirEvent.motion.pointer_coordinates[0].x = 20;
233 mirEvent.motion.pointer_coordinates[0].y = 20;
234 mirEvent.motion.pointer_coordinates[0].touch_major = 1;
235 mirEvent.motion.pointer_coordinates[0].touch_minor = 1;
236 mirEvent.motion.pointer_coordinates[0].pressure = 10;
237 mirEvent.motion.pointer_coordinates[1].id = 2;
238 mirEvent.motion.pointer_coordinates[1].x = 30;
239 mirEvent.motion.pointer_coordinates[1].y = 30;
240 mirEvent.motion.pointer_coordinates[1].touch_major = 1;
241 mirEvent.motion.pointer_coordinates[1].touch_minor = 1;
242 mirEvent.motion.pointer_coordinates[1].pressure = 10;
243 mirEvent.motion.event_time = 125 * 1000000;
244
245 // There can be only one pressed or released touch per event
246 {
247 InSequence sequence;
248
249 // first release touch 0
250 EXPECT_CALL(*mockWindowSystem,
251 handleTouchEvent(_,_,AllOf(SizeIs(2),
252 Contains(AllOf(HasId(0), IsReleased())),
253 Contains(AllOf(HasId(1), IsStationary()))
254 ),_)).Times(1);
255
256 // then press touch 2
257 EXPECT_CALL(*mockWindowSystem,
258 handleTouchEvent(_,_,AllOf(SizeIs(2),
259 Contains(AllOf(HasId(1), StateIsMoved())),
260 Contains(AllOf(HasId(2), IsPressed()))
261 ),_)).Times(1);
262
263 }
145 qtEventFeeder->dispatch(mirEvent);264 qtEventFeeder->dispatch(mirEvent);
146265
147 ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));266 ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
@@ -192,4 +311,3 @@
192311
193 ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));312 ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem));
194}313}
195

Subscribers

People subscribed via source and target branches