Merge lp:~andreas-pokorny/qtmir/store-and-recover-cookie-and-input-device-id into lp:qtmir

Proposed by Andreas Pokorny
Status: Merged
Approved by: Daniel d'Andrada
Approved revision: 611
Merged at revision: 624
Proposed branch: lp:~andreas-pokorny/qtmir/store-and-recover-cookie-and-input-device-id
Merge into: lp:qtmir
Diff against target: 402 lines (+175/-34)
4 files modified
src/platforms/mirserver/eventbuilder.cpp (+69/-15)
src/platforms/mirserver/eventbuilder.h (+11/-6)
src/platforms/mirserver/qteventfeeder.cpp (+10/-9)
tests/mirserver/EventBuilder/eventbuilder_test.cpp (+85/-4)
To merge this branch: bzr merge lp:~andreas-pokorny/qtmir/store-and-recover-cookie-and-input-device-id
Reviewer Review Type Date Requested Status
Daniel d'Andrada (community) Approve
Unity8 CI Bot (community) continuous-integration Approve
Review via email: mp+318528@code.launchpad.net

Commit message

Attach MirInputDeviceId and the MirCookie to input events

Similar to the tracking of relative motion the cookie and input device ids of mir events are stored in the EventBuilder for later recovery

Description of the change

This expands the storage and recovery of input event properties that cannot be reflected with a regular QtEvent onto the optional cookie and the input device id. The Input device id is crucial in tracking the key states in mirclient. E.g. the MirInputDeviceState event which is sent on focus change containing the pressed keys and toggled modifier states per devices, refers to the keyboards by using the input device id.

Since this is in the same area of the code and dnd is needed soon the cookie attribute of the MirInputEvent is also stored.

To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:609
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/531/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4241
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4269
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4104
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4104/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4104
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4104/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4104
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4104/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4104
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4104/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4104
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4104/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4104
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4104/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/531/rebuild

review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Please update copyright years in the files you modified.

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

With this branch I'm getting tons of "qtmir.mir.input: EventBuilder::makeMirEvent didn't find EventInfo with timestamp xxx" messages

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

Worth passing the timestamp to QtEventFeeder::dispatchPointer() to avoid calculating it twice

610. By Andreas Pokorny

Move storing of EventInfo into dispatch* methods

QtEventFeeder::dispatch is only used by tests.

611. By Andreas Pokorny

update years

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:610
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/553/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/4307/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4335
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4168
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4168/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4168
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4168/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4168
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4168/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4168/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4168
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4168/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4168
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4168/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/553/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:611
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/554/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4308
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4336
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4170
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4170/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4170
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4170/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4170
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4170/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4170
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4170/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4170
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4170/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4170
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4170/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/554/rebuild

review: Approve (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Looking good.

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

* Did CI run pass? If not, please explain why.
Yes

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platforms/mirserver/eventbuilder.cpp'
2--- src/platforms/mirserver/eventbuilder.cpp 2016-09-08 22:46:57 +0000
3+++ src/platforms/mirserver/eventbuilder.cpp 2017-03-03 10:39:42 +0000
4@@ -1,5 +1,5 @@
5 /*
6- * Copyright (C) 2016 Canonical, Ltd.
7+ * Copyright (C) 2016-2017 Canonical, Ltd.
8 *
9 * This program is free software: you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License version 3, as published by
11@@ -22,6 +22,7 @@
12 #include <timestamp.h>
13
14 #include <mir_toolkit/event.h>
15+#include <mir_toolkit/mir_cookie.h>
16
17 #include <QDebug>
18
19@@ -104,10 +105,10 @@
20 m_instance = nullptr;
21 }
22
23-void EventBuilder::store(const MirPointerEvent *mirPointerEvent, ulong qtTimestamp)
24+void EventBuilder::store(const MirInputEvent *mirInputEvent, ulong qtTimestamp)
25 {
26 EventInfo &eventInfo = m_eventInfoVector[m_nextIndex];
27- eventInfo.store(mirPointerEvent, qtTimestamp);
28+ eventInfo.store(mirInputEvent, qtTimestamp);
29
30 m_nextIndex = (m_nextIndex + 1) % m_eventInfoVector.size();
31
32@@ -136,21 +137,24 @@
33
34 float relativeX = 0.;
35 float relativeY = 0.;
36+ MirInputDeviceId deviceId = 0;
37+ std::vector<uint8_t> cookie{};
38
39- EventInfo *eventInfo = nullptr;
40 // Timestamp will be zero in case of synthetic events. Particularly synthetic QHoverEvents caused
41 // by item movement under a stationary mouse pointer.
42 if (qtEvent->timestamp() != 0) {
43- eventInfo = findInfo(qtEvent->timestamp());
44+ auto eventInfo = findInfo(qtEvent->timestamp());
45 if (eventInfo) {
46 relativeX = eventInfo->relativeX;
47 relativeY = eventInfo->relativeY;
48+ deviceId = eventInfo->deviceId;
49+ cookie = eventInfo->cookie;
50 } else {
51 qCWarning(QTMIR_MIR_INPUT) << "EventBuilder::makeMirEvent didn't find EventInfo with timestamp" << qtEvent->timestamp();
52 }
53 }
54
55- return mir::events::make_event(0 /*DeviceID */, timestamp, std::vector<uint8_t>{} /* cookie */, modifiers, action,
56+ return mir::events::make_event(deviceId, timestamp, cookie, modifiers, action,
57 buttons, x, y, 0 /*hscroll*/, 0 /*vscroll*/, relativeX, relativeY);
58 }
59
60@@ -160,11 +164,24 @@
61 auto modifiers = getMirModifiersFromQt(qtEvent->modifiers());
62 auto buttons = getMirButtonsFromQt(qtEvent->buttons());
63
64+ MirInputDeviceId deviceId = 0;
65+ std::vector<uint8_t> cookie{};
66+
67 QPointF mirScroll(qtEvent->angleDelta());
68 // QWheelEvent::DefaultDeltasPerStep = 120 but not defined on vivid
69 mirScroll /= 120.0f;
70
71- return mir::events::make_event(0 /*DeviceID */, timestamp, std::vector<uint8_t>{} /* cookie */, modifiers, mir_pointer_action_motion,
72+ if (qtEvent->timestamp() != 0) {
73+ auto eventInfo = findInfo(qtEvent->timestamp());
74+ if (eventInfo) {
75+ deviceId = eventInfo->deviceId;
76+ cookie = eventInfo->cookie;
77+ } else {
78+ qCWarning(QTMIR_MIR_INPUT) << "EventBuilder::makeMirEvent didn't find EventInfo with timestamp" << qtEvent->timestamp();
79+ }
80+ }
81+
82+ return mir::events::make_event(deviceId, timestamp, cookie, modifiers, mir_pointer_action_motion,
83 buttons, qtEvent->x(), qtEvent->y(),
84 mirScroll.x(), mirScroll.y(),
85 0, 0);
86@@ -186,9 +203,21 @@
87 }
88 if (qtEvent->isAutoRepeat())
89 action = mir_keyboard_action_repeat;
90-
91- return mir::events::make_event(0 /* DeviceID */, uncompressTimestamp<qtmir::Timestamp>(qtmir::Timestamp(qtEvent->timestamp())),
92- std::vector<uint8_t>{} /* cookie */, action, qtEvent->nativeVirtualKey(),
93+ MirInputDeviceId deviceId = 0;
94+ std::vector<uint8_t> cookie{};
95+
96+ if (qtEvent->timestamp() != 0) {
97+ auto eventInfo = findInfo(qtEvent->timestamp());
98+ if (eventInfo) {
99+ deviceId = eventInfo->deviceId;
100+ cookie = eventInfo->cookie;
101+ } else {
102+ qCWarning(QTMIR_MIR_INPUT) << "EventBuilder::makeMirEvent didn't find EventInfo with timestamp" << qtEvent->timestamp();
103+ }
104+ }
105+
106+ return mir::events::make_event(deviceId, uncompressTimestamp<qtmir::Timestamp>(qtmir::Timestamp(qtEvent->timestamp())),
107+ cookie, action, qtEvent->nativeVirtualKey(),
108 qtEvent->nativeScanCode(),
109 qtEvent->nativeModifiers());
110 }
111@@ -198,9 +227,22 @@
112 Qt::TouchPointStates /* qtTouchPointStates */,
113 ulong qtTimestamp)
114 {
115+ MirInputDeviceId deviceId = 0;
116+ std::vector<uint8_t> cookie{};
117+
118+ if (qtTimestamp != 0) {
119+ auto eventInfo = findInfo(qtTimestamp);
120+ if (eventInfo) {
121+ deviceId = eventInfo->deviceId;
122+ cookie = eventInfo->cookie;
123+ } else {
124+ qCWarning(QTMIR_MIR_INPUT) << "EventBuilder::makeMirEvent didn't find EventInfo with timestamp" << qtTimestamp;
125+ }
126+ }
127+
128 auto modifiers = getMirModifiersFromQt(qmods);
129- auto ev = mir::events::make_event(0, uncompressTimestamp<qtmir::Timestamp>(qtmir::Timestamp(qtTimestamp)),
130- std::vector<uint8_t>{} /* cookie */, modifiers);
131+ auto ev = mir::events::make_event(deviceId, uncompressTimestamp<qtmir::Timestamp>(qtmir::Timestamp(qtTimestamp)),
132+ cookie, modifiers);
133
134 for (int i = 0; i < qtTouchPoints.count(); ++i) {
135 auto touchPoint = qtTouchPoints.at(i);
136@@ -241,9 +283,21 @@
137 return nullptr;
138 }
139
140-void EventBuilder::EventInfo::store(const MirPointerEvent *pev, ulong qtTimestamp)
141+void EventBuilder::EventInfo::store(const MirInputEvent *iev, ulong qtTimestamp)
142 {
143 this->qtTimestamp = qtTimestamp;
144- relativeX = mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_x);
145- relativeY = mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_y);
146+ deviceId = mir_input_event_get_device_id(iev);
147+ if (mir_input_event_has_cookie(iev))
148+ {
149+ auto cookie_ptr = mir_input_event_get_cookie(iev);
150+ cookie.resize(mir_cookie_buffer_size(cookie_ptr));
151+ mir_cookie_to_buffer(cookie_ptr, cookie.data(), cookie.size());
152+ mir_cookie_release(cookie_ptr);
153+ }
154+ if (mir_input_event_type_pointer == mir_input_event_get_type(iev))
155+ {
156+ auto pev = mir_input_event_get_pointer_event(iev);
157+ relativeX = mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_x);
158+ relativeY = mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_y);
159+ }
160 }
161
162=== modified file 'src/platforms/mirserver/eventbuilder.h'
163--- src/platforms/mirserver/eventbuilder.h 2016-09-08 22:46:57 +0000
164+++ src/platforms/mirserver/eventbuilder.h 2017-03-03 10:39:42 +0000
165@@ -1,5 +1,5 @@
166 /*
167- * Copyright (C) 2016 Canonical, Ltd.
168+ * Copyright (C) 2016-2017 Canonical, Ltd.
169 *
170 * This program is free software: you can redistribute it and/or modify it under
171 * the terms of the GNU Lesser General Public License version 3, as published by
172@@ -46,7 +46,7 @@
173
174 /* Stores information that cannot be carried by QInputEvents so that it can be fully
175 reconstructed later given the same qtTimestamp */
176- void store(const MirPointerEvent *mirPointerEvent, ulong qtTimestamp);
177+ void store(const MirInputEvent *mirInputEvent, ulong qtTimestamp);
178
179 /*
180 Builds a MirEvent version of the given QInputEvent using also extra data from the
181@@ -58,7 +58,10 @@
182 mir::EventUPtr reconstructMirEvent(QHoverEvent *qtEvent);
183
184 /*
185- Makes a MirEvent version of the given QInputEvent
186+ Makes a MirEvent version of the given QInputEvent using also extra data from the
187+ MirInputEvent that caused it.
188+
189+ See also: store()
190 */
191 mir::EventUPtr makeMirEvent(QWheelEvent *qtEvent);
192 mir::EventUPtr makeMirEvent(QKeyEvent *qtEvent);
193@@ -69,8 +72,10 @@
194 private:
195 class EventInfo {
196 public:
197- void store(const MirPointerEvent *mirPointerEvent, ulong qtTimestamp);
198+ void store(const MirInputEvent *mirInputEvent, ulong qtTimestamp);
199 ulong qtTimestamp;
200+ MirInputDeviceId deviceId;
201+ std::vector<uint8_t> cookie;
202 float relativeX{0};
203 float relativeY{0};
204 };
205@@ -85,8 +90,8 @@
206
207 When MirInputEvents are dispatched through a QML scene, not all of its information can be carried
208 by QInputEvents. Some information is lost. Thus further on, if we want to transform a QInputEvent back into
209- its original MirInputEvent so that it can be consumed by a mir::scene::Surface, we have to reach out to
210- this EventRegistry to get the missing bits.
211+ its original MirInputEvent so that it can be consumed by a mir::scene::Surface and properly handled by mir clients
212+ we have to reach out to this EventRegistry to get the missing bits.
213
214 Given the objective of this EventRegistry (MirInputEvent reconstruction after having gone through QQuickWindow input dispatch
215 as a QInputEvent), it stores information only about the most recent MirInputEvents.
216
217=== modified file 'src/platforms/mirserver/qteventfeeder.cpp'
218--- src/platforms/mirserver/qteventfeeder.cpp 2017-01-02 14:41:06 +0000
219+++ src/platforms/mirserver/qteventfeeder.cpp 2017-03-03 10:39:42 +0000
220@@ -1,5 +1,5 @@
221 /*
222- * Copyright (C) 2013-2016 Canonical, Ltd.
223+ * Copyright (C) 2013-2017 Canonical, Ltd.
224 *
225 * This program is free software: you can redistribute it and/or modify it under
226 * the terms of the GNU Lesser General Public License version 3, as published by
227@@ -598,9 +598,10 @@
228
229 void QtEventFeeder::dispatchPointer(const MirPointerEvent *pev)
230 {
231+ auto iev = mir_pointer_event_input_event(pev);
232 auto timestamp = qtmir::compressTimestamp<qtmir::Timestamp>(
233- std::chrono::nanoseconds(mir_input_event_get_event_time(
234- mir_pointer_event_input_event(pev))));
235+ std::chrono::nanoseconds(mir_input_event_get_event_time(iev)));
236+ EventBuilder::instance()->store(iev, timestamp.count());
237 auto action = mir_pointer_event_action(pev);
238 qCDebug(QTMIR_MIR_INPUT) << "Received" << qPrintable(mirPointerEventToString(pev));
239
240@@ -616,8 +617,6 @@
241 case mir_pointer_action_button_down:
242 case mir_pointer_action_motion:
243 {
244- EventBuilder::instance()->store(pev, timestamp.count());
245-
246 const float hDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_hscroll);
247 const float vDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll);
248
249@@ -637,9 +636,10 @@
250
251 void QtEventFeeder::dispatchKey(const MirKeyboardEvent *kev)
252 {
253+ auto iev = mir_keyboard_event_input_event(kev);
254 auto timestamp = qtmir::compressTimestamp<qtmir::Timestamp>(
255- std::chrono::nanoseconds(mir_input_event_get_event_time(
256- mir_keyboard_event_input_event(kev))));
257+ std::chrono::nanoseconds(mir_input_event_get_event_time(iev)));
258+ EventBuilder::instance()->store(iev, timestamp.count());
259
260 xkb_keysym_t xk_sym = mir_keyboard_event_key_code(kev);
261
262@@ -687,9 +687,10 @@
263
264 void QtEventFeeder::dispatchTouch(const MirTouchEvent *tev)
265 {
266+ auto iev = mir_touch_event_input_event(tev);
267 auto timestamp = qtmir::compressTimestamp<qtmir::Timestamp>(
268- std::chrono::nanoseconds(mir_input_event_get_event_time(
269- mir_touch_event_input_event(tev))));
270+ std::chrono::nanoseconds(mir_input_event_get_event_time(iev)));
271+ EventBuilder::instance()->store(iev, timestamp.count());
272
273 tracepoint(qtmirserver, touchEventDispatch_start, std::chrono::nanoseconds(timestamp).count());
274
275
276=== modified file 'tests/mirserver/EventBuilder/eventbuilder_test.cpp'
277--- tests/mirserver/EventBuilder/eventbuilder_test.cpp 2016-09-08 22:46:57 +0000
278+++ tests/mirserver/EventBuilder/eventbuilder_test.cpp 2017-03-03 10:39:42 +0000
279@@ -1,5 +1,5 @@
280 /*
281- * Copyright (C) 2016 Canonical, Ltd.
282+ * Copyright (C) 2016-2017 Canonical, Ltd.
283 *
284 * This program is free software: you can redistribute it and/or modify it under
285 * the terms of the GNU Lesser General Public License version 3, as published by
286@@ -21,6 +21,7 @@
287 #include <QScopedPointer>
288
289 #include "mir/events/event_builders.h"
290+#include "mir_toolkit/mir_cookie.h"
291
292 using namespace qtmir;
293
294@@ -48,7 +49,7 @@
295 std::vector<uint8_t>{} /* cookie */, mir_input_event_modifier_none, mir_pointer_action_motion, 0 /*buttons*/,
296 0 /*x*/, 0 /*y*/, 0 /*hscroll*/, 0 /*vscroll*/, relativeX, relativeY);
297
298- eventBuilder->store(mir_input_event_get_pointer_event(mir_event_get_input_event(mirEvent.get())), qtTimestamp);
299+ eventBuilder->store(mir_event_get_input_event(mirEvent.get()), qtTimestamp);
300 }
301
302 // And store some other unrelated events in between
303@@ -56,13 +57,13 @@
304 mir::EventUPtr mirEvent = mir::events::make_event(0 /*DeviceID */, std::chrono::nanoseconds(222)/*timestamp*/,
305 std::vector<uint8_t>{} /* cookie */, mir_input_event_modifier_none, mir_pointer_action_motion, 0 /*buttons*/,
306 0 /*x*/, 0 /*y*/, 0 /*hscroll*/, 0 /*vscroll*/, relativeX + 3.3, relativeY + 3.3);
307- eventBuilder->store(mir_input_event_get_pointer_event(mir_event_get_input_event(mirEvent.get())), qtTimestamp + 10);
308+ eventBuilder->store(mir_event_get_input_event(mirEvent.get()), qtTimestamp + 10);
309 }
310 {
311 mir::EventUPtr mirEvent = mir::events::make_event(0 /*DeviceID */, std::chrono::nanoseconds(333)/*timestamp*/,
312 std::vector<uint8_t>{} /* cookie */, mir_input_event_modifier_none, mir_pointer_action_motion, 0 /*buttons*/,
313 0 /*x*/, 0 /*y*/, 0 /*hscroll*/, 0 /*vscroll*/, relativeX + 4.4, relativeY + 4.4);
314- eventBuilder->store(mir_input_event_get_pointer_event(mir_event_get_input_event(mirEvent.get())), qtTimestamp + 20);
315+ eventBuilder->store(mir_event_get_input_event(mirEvent.get()), qtTimestamp + 20);
316 }
317
318 QMouseEvent mouseEvent(QEvent::MouseMove, QPointF(0,0) /*localPos*/, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
319@@ -75,3 +76,83 @@
320 EXPECT_EQ(relativeX, mir_pointer_event_axis_value(newMirPointerEvent, mir_pointer_axis_relative_x));
321 EXPECT_EQ(relativeY, mir_pointer_event_axis_value(newMirPointerEvent, mir_pointer_axis_relative_y));
322 }
323+
324+TEST_F(EventBuilderTest, ReconstructCookies)
325+{
326+ QScopedPointer<EventBuilder> eventBuilder(new EventBuilder);
327+
328+ std::vector<uint8_t> cookie{0xd7, 0x56, 0xf1, 0xb7, 0xd8, 0xba};
329+
330+ ulong qtTimestamp = 12345;
331+
332+ // Store the event whose data we will get later when reconstructing it.
333+ {
334+ mir::EventUPtr mirEvent = mir::events::make_event(0 /*DeviceID */, std::chrono::nanoseconds(111)/*timestamp*/,
335+ cookie, mir_input_event_modifier_none, mir_pointer_action_button_down, mir_pointer_button_primary/*buttons*/,
336+ 0 /*x*/, 0 /*y*/, 0 /*hscroll*/, 0 /*vscroll*/, 0 /*relativeX*/, 0 /*relativeY*/);
337+
338+ eventBuilder->store(mir_event_get_input_event(mirEvent.get()), qtTimestamp);
339+ }
340+
341+ // And store some other unrelated events in between
342+ {
343+ mir::EventUPtr mirEvent = mir::events::make_event(0 /*DeviceID */, std::chrono::nanoseconds(222)/*timestamp*/,
344+ std::vector<uint8_t>{} /* cookie */, mir_input_event_modifier_none, mir_pointer_action_motion, 0 /*buttons*/,
345+ 0 /*x*/, 0 /*y*/, 0 /*hscroll*/, 0 /*vscroll*/, 0 /*relativeX*/, 0 /*relativeY*/);
346+ eventBuilder->store(mir_event_get_input_event(mirEvent.get()), qtTimestamp + 10);
347+ }
348+ {
349+ mir::EventUPtr mirEvent = mir::events::make_event(0 /*DeviceID */, std::chrono::nanoseconds(333)/*timestamp*/,
350+ std::vector<uint8_t>{} /* cookie */, mir_input_event_modifier_none, mir_pointer_action_motion, 0 /*buttons*/,
351+ 0 /*x*/, 0 /*y*/, 0 /*hscroll*/, 0 /*vscroll*/, 0 /*relativeX*/, 0 /*relativeY*/);
352+ eventBuilder->store(mir_event_get_input_event(mirEvent.get()), qtTimestamp + 20);
353+ }
354+
355+ QMouseEvent mouseEvent(QEvent::MouseMove, QPointF(0,0) /*localPos*/, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
356+ mouseEvent.setTimestamp(qtTimestamp); // this is what identifies this Qt event with the first Mir event stored.
357+
358+ mir::EventUPtr newMirEvent = eventBuilder->reconstructMirEvent(&mouseEvent);
359+
360+ // The reconstructed event should have the same relative axes values as the mir event stored with the same timestamp
361+ auto input_event = mir_event_get_input_event(newMirEvent.get());
362+ auto cookie_ptr = mir_input_event_get_cookie(input_event);
363+ std::vector<uint8_t> cookieFromPointerEvent;
364+ cookieFromPointerEvent.resize(mir_cookie_buffer_size(cookie_ptr));
365+ mir_cookie_to_buffer(cookie_ptr, cookieFromPointerEvent.data(), cookieFromPointerEvent.size());
366+ mir_cookie_release(cookie_ptr);
367+ EXPECT_EQ(cookieFromPointerEvent, cookie);
368+}
369+
370+TEST_F(EventBuilderTest, ReconstructDeviceId)
371+{
372+ QScopedPointer<EventBuilder> eventBuilder(new EventBuilder);
373+
374+ MirInputDeviceId deviceId = 17;
375+ ulong qtTimestamp = 12345;
376+
377+ // Store the event whose data we will get later when reconstructing it.
378+ {
379+ mir::EventUPtr mirEvent = mir::events::make_event(deviceId, std::chrono::nanoseconds(111)/*timestamp*/,
380+ std::vector<uint8_t>{}/*cookie*/, mir_keyboard_action_down, 70, 50,
381+ mir_input_event_modifier_none);
382+
383+ eventBuilder->store(mir_event_get_input_event(mirEvent.get()), qtTimestamp);
384+ }
385+
386+ // And store some other unrelated events in between
387+ {
388+ mir::EventUPtr mirEvent = mir::events::make_event(0 /*DeviceID */, std::chrono::nanoseconds(222)/*timestamp*/,
389+ std::vector<uint8_t>{} /* cookie */, mir_input_event_modifier_none, mir_pointer_action_motion, 0 /*buttons*/,
390+ 0 /*x*/, 0 /*y*/, 0 /*hscroll*/, 0 /*vscroll*/, 0 /*relativeX*/,0 /*relativeY*/);
391+ eventBuilder->store(mir_event_get_input_event(mirEvent.get()), qtTimestamp + 10);
392+ }
393+
394+ QKeyEvent keyEvent(QEvent::KeyPress, 70, Qt::NoModifier);
395+ keyEvent.setTimestamp(qtTimestamp); // this is what identifies this Qt event with the first Mir event stored.
396+
397+ mir::EventUPtr newMirEvent = eventBuilder->makeMirEvent(&keyEvent);
398+
399+ // The reconstructed event should have the same relative axes values as the mir event stored with the same timestamp
400+ auto input_event = mir_event_get_input_event(newMirEvent.get());
401+ EXPECT_EQ(deviceId, mir_input_event_get_device_id(input_event));
402+}

Subscribers

People subscribed via source and target branches