Mir

Merge lp:~andreas-pokorny/mir/use-realtime-clock-for-input-events into lp:mir

Proposed by Andreas Pokorny
Status: Rejected
Rejected by: Andreas Pokorny
Proposed branch: lp:~andreas-pokorny/mir/use-realtime-clock-for-input-events
Merge into: lp:mir
Prerequisite: lp:~andreas-pokorny/mir/use-static-assert-to-ensure-entry-points-match
Diff against target: 1323 lines (+274/-181)
20 files modified
3rd_party/android-input/android/frameworks/native/libs/utils/Timers.cpp (+7/-19)
include/platform/mir/input/event_builder.h (+2/-1)
include/platform/mir/input/platform.h (+8/-2)
src/platforms/evdev/libinput_device.cpp (+34/-30)
src/platforms/evdev/libinput_device.h (+9/-3)
src/platforms/evdev/platform.cpp (+17/-17)
src/platforms/evdev/platform.h (+7/-1)
src/platforms/evdev/platform_factory.cpp (+5/-3)
src/platforms/mesa/server/x11/input/input.cpp (+4/-1)
src/platforms/mesa/server/x11/input/input_platform.cpp (+4/-4)
src/server/input/default_configuration.cpp (+23/-1)
src/server/input/default_event_builder.cpp (+19/-6)
tests/mir_test_framework/fake_input_device_impl.cpp (+10/-14)
tests/mir_test_framework/fake_input_device_impl.h (+8/-1)
tests/mir_test_framework/stub_input.cpp (+3/-2)
tests/mir_test_framework/stub_input_platform.cpp (+13/-2)
tests/mir_test_framework/stub_input_platform.h (+2/-1)
tests/unit-tests/input/evdev/test_evdev_input_platform.cpp (+3/-1)
tests/unit-tests/input/evdev/test_libinput_device.cpp (+94/-70)
tests/unit-tests/input/test_default_input_device_hub.cpp (+2/-2)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/use-realtime-clock-for-input-events
Reviewer Review Type Date Requested Status
Alexandros Frantzis (community) Approve
Alan Griffiths Needs Fixing
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+277390@code.launchpad.net

Commit message

Use the same clock for input events as the android-input stack and input resampling but not the rest of the system

This changes the ABI of input platform again - but we already bumped it for 0.18. Now input platforms receive a clock object
to use. Previously the evdev-input platform used the timestamp attached to input events. This had a bad impact on the input
resampling done on a client of a nested shell (curiously not so at the nested shell itself).

Description of the change

Not a fix for LP: #1515515 but related. With this input platforms may use the 'same' clock as a potential client. This is for now CLOCK_REALTIME, as we currently cannot switch to steady_clock since qt event feeder is not entirely clock agnostic.

We might have to rework the way mir events are transported through qtEvents to get this problem fixed.

To post a comment you must log in.
3101. By Andreas Pokorny on 2015-11-12

merge prereq

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

+ return std::chrono::nanoseconds(t.tv_sec*1000000000LL + t.tv_nsec);

Why not:

     return std::chrono::seconds(t.tv_sec) + std::chrono::nanoseconds(t.tv_nsec);

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

CLOCK_MONOTONIC seems like the obvious choice and CLOCK_REALTIME seems like a really bad one. Replicating a mistake in qtmir seems will make it difficult to correct in both codebases:

https://books.google.co.uk/books?id=sS7aPtrUuw4C&lpg=PA172&ots=-hd3SP-jyT&dq=97%20things%20two%20wrongs%20make%20a%20right&pg=PA172#v=onepage&q=97%20things%20two%20wrongs%20make%20a%20right&f=false

review: Needs Fixing
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> CLOCK_MONOTONIC seems like the obvious choice and CLOCK_REALTIME seems like a
> really bad one. Replicating a mistake in qtmir seems will make it difficult to
> correct in both codebases:
>
> https://books.google.co.uk/books?id=sS7aPtrUuw4C&lpg=PA172&ots=-hd3SP-jyT&dq=9
> 7%20things%20two%20wrongs%20make%20a%20right&pg=PA172#v=onepage&q=97%20things%
> 20two%20wrongs%20make%20a%20right&f=false

Yes thats why I started the attempt to use steady_clock for everything. I am still investigating why qtmir at some point not longer copies the timestamps provided by mir...

We were using CLOCK_REALTIME since beginning of the android-input stack in mir. This MP is not addressing that yet. It fixes some naming problems and introduces the concept of a mirserver controlled clock to the input sources..

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> We were using CLOCK_REALTIME since beginning of the android-input stack in
> mir. This MP is not addressing that yet. It fixes some naming problems and
> introduces the concept of a mirserver controlled clock to the input sources..

In that case this comment is misleading:

+// Fixed to CLOCK_REALTIME, see LP: #1515515 - note that all invocations in the code base
+// either request MONOTONIC or do not specify a clock, which then defaults to MONOTONIC.
+// Previously we used gettimeofday here and also ignored the clock parameter.

review: Needs Fixing
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good.

review: Approve
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

Ok I found the offender that injected timestamps from the wrong clock..

I will propose a ~switch~to~monotonic~clock~ MP instead.

Unmerged revisions

3101. By Andreas Pokorny on 2015-11-12

merge prereq

3100. By Andreas Pokorny on 2015-11-12

merge prereq

3099. By Andreas Pokorny on 2015-11-11

Use the same clock for input events as the android-input stack and input resampling and the rest of the system

This changes the ABI of input platform again - but we already bumped it for 0.18. Now input platforms receive a clock object
to use. Previously the evdev-input platform used the timestamp attached to input events. This had a bad impact on the input
resampling done on a client of a nested shell (curiously not so at the nested shell itself).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '3rd_party/android-input/android/frameworks/native/libs/utils/Timers.cpp'
2--- 3rd_party/android-input/android/frameworks/native/libs/utils/Timers.cpp 2015-08-18 01:35:15 +0000
3+++ 3rd_party/android-input/android/frameworks/native/libs/utils/Timers.cpp 2015-11-12 20:43:41 +0000
4@@ -32,26 +32,14 @@
5 #include <windows.h>
6 #endif
7
8-std::chrono::nanoseconds systemTime(int clock)
9+// Fixed to CLOCK_REALTIME, see LP: #1515515 - note that all invocations in the code base
10+// either request MONOTONIC or do not specify a clock, which then defaults to MONOTONIC.
11+// Previously we used gettimeofday here and also ignored the clock parameter.
12+std::chrono::nanoseconds systemTime(int)
13 {
14-#if defined(HAVE_POSIX_CLOCKS)
15- static const clockid_t clocks[] = {
16- CLOCK_REALTIME,
17- CLOCK_MONOTONIC,
18- CLOCK_PROCESS_CPUTIME_ID,
19- CLOCK_THREAD_CPUTIME_ID
20- };
21- struct timespec t;
22- t.tv_sec = t.tv_nsec = 0;
23- clock_gettime(clocks[clock], &t);
24- return std::chrono::nanoseconds(t.tv_sec)*1000000000LL + t.tv_nsec;
25-#else
26- // we don't support the clocks here.
27- struct timeval t;
28- t.tv_sec = t.tv_usec = 0;
29- gettimeofday(&t, NULL);
30- return std::chrono::nanoseconds(t.tv_sec)*1000000000LL + std::chrono::nanoseconds(t.tv_usec)*1000LL;
31-#endif
32+ timespec t;
33+ clock_gettime(CLOCK_REALTIME, &t);
34+ return std::chrono::nanoseconds(t.tv_sec*1000000000LL + t.tv_nsec);
35 }
36
37 int toMillisecondTimeoutDelay(std::chrono::nanoseconds referenceTime, std::chrono::nanoseconds timeoutTime)
38
39=== renamed file 'src/include/common/mir/time/clock.h' => 'include/common/mir/time/clock.h'
40=== modified file 'include/platform/mir/input/event_builder.h'
41--- include/platform/mir/input/event_builder.h 2015-11-04 07:43:28 +0000
42+++ include/platform/mir/input/event_builder.h 2015-11-12 20:43:41 +0000
43@@ -21,6 +21,7 @@
44 #define MIR_INPUT_EVENT_BUILDER_H_
45
46 #include "mir_toolkit/event.h"
47+#include "mir/time/types.h"
48 #include <memory>
49 #include <chrono>
50
51@@ -36,7 +37,7 @@
52 public:
53 EventBuilder() = default;
54 virtual ~EventBuilder() = default;
55- using Timestamp = std::chrono::nanoseconds;
56+ using Timestamp = mir::time::Timestamp;
57
58 virtual EventUPtr key_event(Timestamp timestamp, MirKeyboardAction action, xkb_keysym_t key_code, int scan_code) = 0;
59
60
61=== modified file 'include/platform/mir/input/platform.h'
62--- include/platform/mir/input/platform.h 2015-10-12 08:08:58 +0000
63+++ include/platform/mir/input/platform.h 2015-11-12 20:43:41 +0000
64@@ -33,6 +33,10 @@
65 {
66 class EmergencyCleanupRegistry;
67
68+namespace time
69+{
70+class Clock;
71+}
72 namespace dispatch
73 {
74 class Dispatchable;
75@@ -94,7 +98,8 @@
76 std::shared_ptr<options::Option> const& options,
77 std::shared_ptr<EmergencyCleanupRegistry> const& emergency_cleanup_registry,
78 std::shared_ptr<InputDeviceRegistry> const& input_device_registry,
79- std::shared_ptr<InputReport> const& report);
80+ std::shared_ptr<InputReport> const& report,
81+ std::shared_ptr<time::Clock> const& clock);
82
83 typedef void(*AddPlatformOptions)(
84 boost::program_options::options_description& config);
85@@ -126,7 +131,8 @@
86 std::shared_ptr<mir::options::Option> const& options,
87 std::shared_ptr<mir::EmergencyCleanupRegistry> const& emergency_cleanup_registry,
88 std::shared_ptr<mir::input::InputDeviceRegistry> const& input_device_registry,
89- std::shared_ptr<mir::input::InputReport> const& report);
90+ std::shared_ptr<mir::input::InputReport> const& report,
91+ std::shared_ptr<mir::time::Clock> const& clock);
92
93 /**
94 * Function used to add additional configuration options
95
96=== modified file 'src/platforms/evdev/libinput_device.cpp'
97--- src/platforms/evdev/libinput_device.cpp 2015-11-05 13:13:10 +0000
98+++ src/platforms/evdev/libinput_device.cpp 2015-11-12 20:43:41 +0000
99@@ -22,6 +22,7 @@
100 #include "evdev_device_detection.h"
101 #include "button_utils.h"
102
103+#include "mir/time/clock.h"
104 #include "mir/input/input_sink.h"
105 #include "mir/input/input_report.h"
106 #include "mir/input/device_capability.h"
107@@ -51,11 +52,16 @@
108
109 void null_deleter(MirEvent *) {}
110
111-}
112-
113-mie::LibInputDevice::LibInputDevice(std::shared_ptr<mi::InputReport> const& report, char const* path,
114- LibInputDevicePtr dev)
115- : report{report}, accumulated_touch_event{nullptr, null_deleter}, pointer_pos{0, 0}, button_state{0}
116+auto ns_offset(mir::time::Timestamp const& ts)
117+{
118+ return std::chrono::duration_cast<std::chrono::nanoseconds>(ts.time_since_epoch()).count();
119+}
120+
121+}
122+
123+mie::LibInputDevice::LibInputDevice(std::shared_ptr<mi::InputReport> const& report,
124+ std::shared_ptr<time::Clock> const& clock, char const* path, LibInputDevicePtr dev)
125+ : report{report}, clock{clock}, accumulated_touch_event{nullptr, null_deleter}, pointer_pos{0, 0}, button_state{0}
126 {
127 add_device_of_group(path, std::move(dev));
128 }
129@@ -122,7 +128,7 @@
130 // Not yet provided by libinput.
131 break;
132 case LIBINPUT_EVENT_TOUCH_FRAME:
133- sink->handle_input(get_accumulated_touch_event(0ns));
134+ sink->handle_input(get_accumulated_touch_event());
135 accumulated_touch_event.reset();
136 break;
137 default:
138@@ -132,19 +138,19 @@
139
140 mir::EventUPtr mie::LibInputDevice::convert_event(libinput_event_keyboard* keyboard)
141 {
142- std::chrono::nanoseconds const time = std::chrono::microseconds(libinput_event_keyboard_get_time_usec(keyboard));
143+ auto const now = clock->now();
144 auto const action = libinput_event_keyboard_get_key_state(keyboard) == LIBINPUT_KEY_STATE_PRESSED ?
145 mir_keyboard_action_down :
146 mir_keyboard_action_up;
147 auto const code = libinput_event_keyboard_get_key(keyboard);
148- report->received_event_from_kernel(time.count(), EV_KEY, code, action);
149+ report->received_event_from_kernel(ns_offset(now), EV_KEY, code, action);
150
151- return builder->key_event(time, action, xkb_keysym_t{0}, code);
152+ return builder->key_event(now, action, xkb_keysym_t{0}, code);
153 }
154
155 mir::EventUPtr mie::LibInputDevice::convert_button_event(libinput_event_pointer* pointer)
156 {
157- std::chrono::nanoseconds const time = std::chrono::microseconds(libinput_event_pointer_get_time_usec(pointer));
158+ auto const now = clock->now();
159 auto const button = libinput_event_pointer_get_button(pointer);
160 auto const action = (libinput_event_pointer_get_button_state(pointer) == LIBINPUT_BUTTON_STATE_PRESSED)?
161 mir_pointer_action_button_down : mir_pointer_action_button_up;
162@@ -156,25 +162,25 @@
163 auto const hscroll_value = 0.0f;
164 auto const vscroll_value = 0.0f;
165
166- report->received_event_from_kernel(time.count(), EV_KEY, pointer_button, action);
167+ report->received_event_from_kernel(ns_offset(now), EV_KEY, pointer_button, action);
168
169 if (action == mir_pointer_action_button_down)
170 button_state = MirPointerButton(button_state | uint32_t(pointer_button));
171 else
172 button_state = MirPointerButton(button_state & ~uint32_t(pointer_button));
173
174- return builder->pointer_event(time, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
175+ return builder->pointer_event(now, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
176 hscroll_value, vscroll_value, relative_x_value, relative_y_value);
177 }
178
179 mir::EventUPtr mie::LibInputDevice::convert_motion_event(libinput_event_pointer* pointer)
180 {
181- std::chrono::nanoseconds const time = std::chrono::microseconds(libinput_event_pointer_get_time_usec(pointer));
182+ auto const now = clock->now();
183 auto const action = mir_pointer_action_motion;
184 auto const hscroll_value = 0.0f;
185 auto const vscroll_value = 0.0f;
186
187- report->received_event_from_kernel(time.count(), EV_REL, 0, 0);
188+ report->received_event_from_kernel(ns_offset(now), EV_REL, 0, 0);
189
190 mir::geometry::Displacement const movement{
191 libinput_event_pointer_get_dx(pointer),
192@@ -183,14 +189,14 @@
193
194 sink->confine_pointer(pointer_pos);
195
196- return builder->pointer_event(time, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
197+ return builder->pointer_event(now, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
198 hscroll_value, vscroll_value, movement.dx.as_float(), movement.dy.as_float());
199 }
200
201 mir::EventUPtr mie::LibInputDevice::convert_absolute_motion_event(libinput_event_pointer* pointer)
202 {
203+ auto const now = clock->now();
204 // a pointing device that emits absolute coordinates
205- std::chrono::nanoseconds const time = std::chrono::microseconds(libinput_event_pointer_get_time_usec(pointer));
206 auto const action = mir_pointer_action_motion;
207 auto const hscroll_value = 0.0f;
208 auto const vscroll_value = 0.0f;
209@@ -198,7 +204,7 @@
210 uint32_t const width = screen.size.width.as_int();
211 uint32_t const height = screen.size.height.as_int();
212
213- report->received_event_from_kernel(time.count(), EV_ABS, 0, 0);
214+ report->received_event_from_kernel(ns_offset(now), EV_ABS, 0, 0);
215 auto const old_pointer_pos = pointer_pos;
216 pointer_pos = mir::geometry::Point{
217 libinput_event_pointer_get_absolute_x_transformed(pointer, width),
218@@ -207,13 +213,13 @@
219
220 sink->confine_pointer(pointer_pos);
221
222- return builder->pointer_event(time, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
223+ return builder->pointer_event(now, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
224 hscroll_value, vscroll_value, movement.dx.as_float(), movement.dy.as_float());
225 }
226
227 mir::EventUPtr mie::LibInputDevice::convert_axis_event(libinput_event_pointer* pointer)
228 {
229- std::chrono::nanoseconds const time = std::chrono::microseconds(libinput_event_pointer_get_time_usec(pointer));
230+ auto const now = clock->now();
231 auto const action = mir_pointer_action_motion;
232 auto const relative_x_value = 0.0f;
233 auto const relative_y_value = 0.0f;
234@@ -226,17 +232,18 @@
235 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)
236 : 0.0f;
237
238- report->received_event_from_kernel(time.count(), EV_REL, 0, 0);
239- return builder->pointer_event(time, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
240+ report->received_event_from_kernel(ns_offset(now), EV_REL, 0, 0);
241+ return builder->pointer_event(now, action, button_state, pointer_pos.x.as_float(), pointer_pos.y.as_float(),
242 hscroll_value, vscroll_value, relative_x_value, relative_y_value);
243 }
244
245-MirEvent& mie::LibInputDevice::get_accumulated_touch_event(std::chrono::nanoseconds timestamp)
246+MirEvent& mie::LibInputDevice::get_accumulated_touch_event()
247 {
248 if (!accumulated_touch_event)
249 {
250- report->received_event_from_kernel(timestamp.count(), EV_SYN, 0, 0);
251- accumulated_touch_event = builder->touch_event(timestamp);
252+ auto const now = clock->now();
253+ report->received_event_from_kernel(ns_offset(now), EV_SYN, 0, 0);
254+ accumulated_touch_event = builder->touch_event(now);
255 }
256
257 return *accumulated_touch_event;
258@@ -244,8 +251,7 @@
259
260 void mie::LibInputDevice::add_touch_down_event(libinput_event_touch* touch)
261 {
262- std::chrono::nanoseconds const time = std::chrono::microseconds(libinput_event_touch_get_time_usec(touch));
263- auto& event = get_accumulated_touch_event(time);
264+ auto& event = get_accumulated_touch_event();
265
266 MirTouchId const id = libinput_event_touch_get_slot(touch);
267 auto const action = mir_touch_action_down;
268@@ -265,8 +271,7 @@
269
270 void mie::LibInputDevice::add_touch_up_event(libinput_event_touch* touch)
271 {
272- std::chrono::nanoseconds const time = std::chrono::microseconds(libinput_event_touch_get_time_usec(touch));
273- auto& event = get_accumulated_touch_event(time);
274+ auto& event = get_accumulated_touch_event();
275 MirTouchId const id = libinput_event_touch_get_slot(touch);
276 auto const action = mir_touch_action_up;
277 auto const tool = mir_touch_tooltype_finger; // TODO make libinput indicate tool type
278@@ -297,8 +302,7 @@
279
280 void mie::LibInputDevice::add_touch_motion_event(libinput_event_touch* touch)
281 {
282- std::chrono::nanoseconds const time = std::chrono::microseconds(libinput_event_touch_get_time_usec(touch));
283- auto& event = get_accumulated_touch_event(time);
284+ auto& event = get_accumulated_touch_event();
285
286 MirTouchId const id = libinput_event_touch_get_slot(touch);
287 auto const action = mir_touch_action_change;
288
289=== modified file 'src/platforms/evdev/libinput_device.h'
290--- src/platforms/evdev/libinput_device.h 2015-11-04 07:43:28 +0000
291+++ src/platforms/evdev/libinput_device.h 2015-11-12 20:43:41 +0000
292@@ -38,6 +38,10 @@
293
294 namespace mir
295 {
296+namespace time
297+{
298+class Clock;
299+}
300 namespace input
301 {
302 class InputReport;
303@@ -49,7 +53,8 @@
304 class LibInputDevice : public input::InputDevice
305 {
306 public:
307- LibInputDevice(std::shared_ptr<InputReport> const& report, char const* path, LibInputDevicePtr dev);
308+ LibInputDevice(std::shared_ptr<InputReport> const& report, std::shared_ptr<time::Clock> const& clock,
309+ char const* path, LibInputDevicePtr dev);
310 ~LibInputDevice();
311 void start(InputSink* sink, EventBuilder* builder) override;
312 void stop() override;
313@@ -73,10 +78,11 @@
314 void add_touch_down_event(libinput_event_touch* touch);
315 void add_touch_up_event(libinput_event_touch* touch);
316 void add_touch_motion_event(libinput_event_touch* touch);
317- MirEvent& get_accumulated_touch_event(std::chrono::nanoseconds timestamp);
318+ MirEvent& get_accumulated_touch_event();
319 void update_device_info();
320
321- std::shared_ptr<InputReport> report;
322+ std::shared_ptr<InputReport> const report;
323+ std::shared_ptr<time::Clock> const clock;
324 std::shared_ptr<::libinput> lib;
325 std::vector<std::string> paths;
326 std::vector<LibInputDevicePtr> devices;
327
328=== modified file 'src/platforms/evdev/platform.cpp'
329--- src/platforms/evdev/platform.cpp 2015-11-12 20:43:40 +0000
330+++ src/platforms/evdev/platform.cpp 2015-11-12 20:43:41 +0000
331@@ -45,23 +45,23 @@
332 namespace mie = mi::evdev;
333
334 mie::Platform::Platform(std::shared_ptr<InputDeviceRegistry> const& registry,
335- std::shared_ptr<InputReport> const& report,
336- std::unique_ptr<udev::Context>&& udev_context,
337- std::unique_ptr<udev::Monitor>&& monitor)
338- : report(report), udev_context(std::move(udev_context)), monitor(std::move(monitor)),
339- input_device_registry(registry),
340- platform_dispatchable{std::make_shared<md::MultiplexingDispatchable>()},
341- monitor_dispatchable{
342- std::make_shared<md::ReadableFd>(
343- Fd{IntOwnedFd{this->monitor->fd()}},
344- [this](){process_changes();}
345- )},
346+ std::shared_ptr<InputReport> const& report,
347+ std::unique_ptr<udev::Context>&& udev_context,
348+ std::unique_ptr<udev::Monitor>&& monitor,
349+ std::shared_ptr<time::Clock> const& clock)
350+ : report(report), udev_context(std::move(udev_context)), monitor(std::move(monitor)), clock(clock),
351+ input_device_registry(registry), platform_dispatchable{std::make_shared<md::MultiplexingDispatchable>()},
352+ monitor_dispatchable{std::make_shared<md::ReadableFd>(Fd{IntOwnedFd{this->monitor->fd()}},
353+ [this]()
354+ {
355+ process_changes();
356+ })},
357 lib{make_libinput()},
358- libinput_dispatchable{
359- std::make_shared<md::ReadableFd>(
360- Fd{IntOwnedFd{libinput_get_fd(lib.get())}},
361- [this](){process_input_events();}
362- )}
363+ libinput_dispatchable{std::make_shared<md::ReadableFd>(Fd{IntOwnedFd{libinput_get_fd(lib.get())}},
364+ [this]()
365+ {
366+ process_input_events();
367+ })}
368 {
369 this->monitor->filter_by_subsystem("input");
370 this->monitor->enable();
371@@ -171,7 +171,7 @@
372
373 try
374 {
375- devices.emplace_back(std::make_shared<mie::LibInputDevice>(report, dev.devnode(), move(device_ptr)));
376+ devices.emplace_back(std::make_shared<mie::LibInputDevice>(report, clock, dev.devnode(), move(device_ptr)));
377
378 input_device_registry->add_device(devices.back());
379
380
381=== modified file 'src/platforms/evdev/platform.h'
382--- src/platforms/evdev/platform.h 2015-08-27 13:47:31 +0000
383+++ src/platforms/evdev/platform.h 2015-11-12 20:43:41 +0000
384@@ -30,6 +30,10 @@
385
386 namespace mir
387 {
388+namespace time
389+{
390+class Clock;
391+}
392 namespace udev
393 {
394 class Device;
395@@ -56,7 +60,8 @@
396 Platform(std::shared_ptr<InputDeviceRegistry> const& registry,
397 std::shared_ptr<InputReport> const& report,
398 std::unique_ptr<udev::Context>&& udev_context,
399- std::unique_ptr<udev::Monitor>&& monitor);
400+ std::unique_ptr<udev::Monitor>&& monitor,
401+ std::shared_ptr<mir::time::Clock> const& clock);
402 std::shared_ptr<mir::dispatch::Dispatchable> dispatchable() override;
403 void start() override;
404 void stop() override;
405@@ -74,6 +79,7 @@
406 std::shared_ptr<InputReport> const report;
407 std::shared_ptr<udev::Context> const udev_context;
408 std::unique_ptr<udev::Monitor> const monitor;
409+ std::shared_ptr<mir::time::Clock> const clock;
410 std::shared_ptr<InputDeviceRegistry> const input_device_registry;
411 std::shared_ptr<dispatch::MultiplexingDispatchable> const platform_dispatchable;
412 std::shared_ptr<dispatch::ReadableFd> const monitor_dispatchable;
413
414=== modified file 'src/platforms/evdev/platform_factory.cpp'
415--- src/platforms/evdev/platform_factory.cpp 2015-11-12 20:43:40 +0000
416+++ src/platforms/evdev/platform_factory.cpp 2015-11-12 20:43:41 +0000
417@@ -17,6 +17,7 @@
418 */
419
420 #include "platform.h"
421+#include "mir/input/platform.h"
422 #include "mir/udev/wrapper.h"
423 #include "mir/fd.h"
424 #include "mir/assert_module_entry_point.h"
425@@ -27,7 +28,7 @@
426
427 #include <memory>
428 #include <string>
429-#include <iostream>
430+#include <type_traits>
431
432 namespace mo = mir::options;
433 namespace mi = mir::input;
434@@ -71,12 +72,13 @@
435 std::shared_ptr<mo::Option> const& /*options*/,
436 std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/,
437 std::shared_ptr<mi::InputDeviceRegistry> const& input_device_registry,
438- std::shared_ptr<mi::InputReport> const& report)
439+ std::shared_ptr<mi::InputReport> const& report,
440+ std::shared_ptr<mir::time::Clock> const& clock)
441 {
442 mir::assert_entry_point_signature<mi::CreatePlatform>(&create_input_platform);
443 auto ctx = std::make_unique<mu::Context>();
444 auto monitor = std::make_unique<mu::Monitor>(*ctx.get());
445- return mir::make_module_ptr<mie::Platform>(input_device_registry, report, std::move(ctx), std::move(monitor));
446+ return mir::make_module_ptr<mie::Platform>(input_device_registry, report, std::move(ctx), std::move(monitor), clock);
447 }
448
449 void add_input_platform_options(
450
451=== modified file 'src/platforms/mesa/server/x11/input/input.cpp'
452--- src/platforms/mesa/server/x11/input/input.cpp 2015-11-12 20:43:40 +0000
453+++ src/platforms/mesa/server/x11/input/input.cpp 2015-11-12 20:43:41 +0000
454@@ -32,7 +32,8 @@
455 std::shared_ptr<mo::Option> const& /*options*/,
456 std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/,
457 std::shared_ptr<mi::InputDeviceRegistry> const& input_device_registry,
458- std::shared_ptr<mi::InputReport> const& /*report*/)
459+ std::shared_ptr<mi::InputReport> const& /*report*/,
460+ std::shared_ptr<mir::time::Clock> const& /*clock*/)
461 {
462 mir::assert_entry_point_signature<mi::CreatePlatform>(&create_input_platform);
463 return mir::make_module_ptr<mix::XInputPlatform>(input_device_registry, x11_resources.get_conn());
464@@ -47,6 +48,8 @@
465 mi::PlatformPriority probe_input_platform(
466 mo::Option const& options)
467 {
468+ static_assert(std::is_same<decltype(&probe_input_platform), mir::input::ProbePlatform>::value,
469+ "Platform interface function does not match typedef");
470 mir::assert_entry_point_signature<mi::ProbePlatform>(&probe_input_platform);
471 if (options.is_set("host-socket"))
472 return mi::PlatformPriority::unsupported;
473
474=== modified file 'src/platforms/mesa/server/x11/input/input_platform.cpp'
475--- src/platforms/mesa/server/x11/input/input_platform.cpp 2015-11-04 07:43:28 +0000
476+++ src/platforms/mesa/server/x11/input/input_platform.cpp 2015-11-12 20:43:41 +0000
477@@ -140,7 +140,7 @@
478 #endif
479 core_keyboard->sink->handle_input(
480 *core_keyboard->builder->key_event(
481- event_time,
482+ mir::time::Timestamp{event_time},
483 xkev.type == KeyPress ?
484 mir_keyboard_action_down :
485 mir_keyboard_action_up,
486@@ -202,7 +202,7 @@
487 { // scroll event
488 core_pointer->sink->handle_input(
489 *core_pointer->builder->pointer_event(
490- event_time,
491+ mir::time::Timestamp{event_time},
492 mir_pointer_action_motion,
493 0,
494 xbev.x,
495@@ -218,7 +218,7 @@
496 {
497 core_pointer->sink->handle_input(
498 *core_pointer->builder->pointer_event(
499- event_time,
500+ mir::time::Timestamp{event_time},
501 xbev.type == ButtonPress ?
502 mir_pointer_action_button_down :
503 mir_pointer_action_button_up,
504@@ -272,7 +272,7 @@
505 #endif
506 core_pointer->sink->handle_input(
507 *core_pointer->builder->pointer_event(
508- event_time,
509+ mir::time::Timestamp{event_time},
510 mir_pointer_action_motion,
511 buttons_pressed,
512 xmev.x,
513
514=== modified file 'src/server/input/default_configuration.cpp'
515--- src/server/input/default_configuration.cpp 2015-10-13 17:42:07 +0000
516+++ src/server/input/default_configuration.cpp 2015-11-12 20:43:41 +0000
517@@ -50,6 +50,7 @@
518 #include "mir/shared_library.h"
519 #include "mir/glib_main_loop.h"
520 #include "mir/dispatch/action_queue.h"
521+#include "mir/time/clock.h"
522
523 #include "mir_toolkit/cursors.h"
524
525@@ -62,6 +63,27 @@
526 namespace mg = mir::graphics;
527 namespace msh = mir::shell;
528 namespace md = mir::dispatch;
529+namespace mt = mir::time;
530+
531+// Because of LP: #1515515 we cannot use steady_clock for input platforms
532+namespace
533+{
534+struct InputClock : mt::Clock
535+{
536+ mt::Timestamp now() const override
537+ {
538+ timespec t;
539+ clock_gettime(CLOCK_REALTIME, &t);
540+ return mt::Timestamp{std::chrono::nanoseconds{t.tv_sec*1000000000LL + t.tv_nsec}};
541+ }
542+
543+ mt::Duration min_wait_until(mt::Timestamp t) const override
544+ {
545+ return max(t - now(), mt::Duration{0});
546+ }
547+};
548+}
549+
550
551 std::shared_ptr<mi::InputRegion> mir::DefaultServerConfiguration::the_input_region()
552 {
553@@ -306,7 +328,7 @@
554 auto create = lib->load_function<mi::CreatePlatform>(
555 "create_input_platform",
556 MIR_SERVER_INPUT_PLATFORM_VERSION);
557- return create(the_options(), the_emergency_cleanup(), the_input_device_registry(), the_input_report());
558+ return create(the_options(), the_emergency_cleanup(), the_input_device_registry(), the_input_report(), std::make_shared<InputClock>());
559 });
560 }
561
562
563=== modified file 'src/server/input/default_event_builder.cpp'
564--- src/server/input/default_event_builder.cpp 2015-11-04 07:43:28 +0000
565+++ src/server/input/default_event_builder.cpp 2015-11-12 20:43:41 +0000
566@@ -25,6 +25,19 @@
567 namespace me = mir::events;
568 namespace mi = mir::input;
569
570+namespace
571+{
572+uint64_t for_cookie(mir::time::Timestamp const& ts)
573+{
574+ return ts.time_since_epoch().count();
575+}
576+std::chrono::nanoseconds to_ns(mir::time::Timestamp const& ts)
577+{
578+ return std::chrono::duration_cast<std::chrono::nanoseconds>(ts.time_since_epoch());
579+}
580+}
581+
582+
583 mi::DefaultEventBuilder::DefaultEventBuilder(MirInputDeviceId device_id,
584 std::shared_ptr<mir::cookie::CookieFactory> const& cookie_factory)
585 : device_id(device_id),
586@@ -35,13 +48,13 @@
587 mir::EventUPtr mi::DefaultEventBuilder::key_event(Timestamp timestamp, MirKeyboardAction action, xkb_keysym_t key_code,
588 int scan_code)
589 {
590- uint64_t mac = cookie_factory->timestamp_to_cookie(timestamp.count()).mac;
591- return me::make_event(device_id, timestamp, mac, action, key_code, scan_code, mir_input_event_modifier_none);
592+ uint64_t mac = cookie_factory->timestamp_to_cookie(for_cookie(timestamp)).mac;
593+ return me::make_event(device_id, to_ns(timestamp), mac, action, key_code, scan_code, mir_input_event_modifier_none);
594 }
595
596 mir::EventUPtr mi::DefaultEventBuilder::touch_event(Timestamp timestamp)
597 {
598- return me::make_event(device_id, timestamp, 0, mir_input_event_modifier_none);
599+ return me::make_event(device_id, to_ns(timestamp), 0, mir_input_event_modifier_none);
600 }
601
602 void mi::DefaultEventBuilder::add_touch(MirEvent& event, MirTouchId touch_id, MirTouchAction action,
603@@ -66,12 +79,12 @@
604 {
605 uint64_t mac = 0;
606 if (action == mir_pointer_action_button_up || action == mir_pointer_action_button_down)
607- mac = cookie_factory->timestamp_to_cookie(timestamp.count()).mac;
608- return me::make_event(device_id, timestamp, mac, mir_input_event_modifier_none, action, buttons_pressed, x_axis_value, y_axis_value,
609+ mac = cookie_factory->timestamp_to_cookie(for_cookie(timestamp)).mac;
610+ return me::make_event(device_id, to_ns(timestamp), mac, mir_input_event_modifier_none, action, buttons_pressed, x_axis_value, y_axis_value,
611 hscroll_value, vscroll_value, relative_x_value, relative_y_value);
612 }
613
614 mir::EventUPtr mi::DefaultEventBuilder::configuration_event(Timestamp timestamp, MirInputConfigurationAction action)
615 {
616- return me::make_event(action, device_id, timestamp);
617+ return me::make_event(action, device_id, to_ns(timestamp));
618 }
619
620=== modified file 'tests/mir_test_framework/fake_input_device_impl.cpp'
621--- tests/mir_test_framework/fake_input_device_impl.cpp 2015-11-04 07:43:28 +0000
622+++ tests/mir_test_framework/fake_input_device_impl.cpp 2015-11-12 20:43:41 +0000
623@@ -25,6 +25,7 @@
624 #include "mir/input/pointer_settings.h"
625 #include "mir/input/touchpad_settings.h"
626 #include "mir/input/event_builder.h"
627+#include "mir/time/clock.h"
628 #include "mir/dispatch/action_queue.h"
629 #include "mir/geometry/displacement.h"
630 #include "src/platforms/evdev/button_utils.h"
631@@ -92,17 +93,19 @@
632 {
633 }
634
635+void mtf::FakeInputDeviceImpl::InputDevice::set_clock(std::shared_ptr<mir::time::Clock> const& clock)
636+{
637+ this->clock = clock;
638+}
639+
640 void mtf::FakeInputDeviceImpl::InputDevice::synthesize_events(synthesis::KeyParameters const& key_params)
641 {
642 xkb_keysym_t key_code = 0;
643
644- auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(
645- std::chrono::system_clock::now().time_since_epoch());
646-
647 auto input_action =
648 (key_params.action == synthesis::EventAction::Down) ? mir_keyboard_action_down : mir_keyboard_action_up;
649
650- auto key_event = builder->key_event(event_time, input_action, key_code, key_params.scancode);
651+ auto key_event = builder->key_event(clock->now(), input_action, key_code, key_params.scancode);
652
653 if (!sink)
654 BOOST_THROW_EXCEPTION(std::runtime_error("Device is not started."));
655@@ -111,10 +114,8 @@
656
657 void mtf::FakeInputDeviceImpl::InputDevice::synthesize_events(synthesis::ButtonParameters const& button)
658 {
659- auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(
660- std::chrono::system_clock::now().time_since_epoch());
661 auto action = update_buttons(button.action, mie::to_pointer_button(button.button, settings.handedness));
662- auto button_event = builder->pointer_event(event_time,
663+ auto button_event = builder->pointer_event(clock->now(),
664 action,
665 buttons,
666 pos.x.as_float(),
667@@ -148,8 +149,6 @@
668 if (!sink)
669 BOOST_THROW_EXCEPTION(std::runtime_error("Device is not started."));
670
671- auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(
672- std::chrono::system_clock::now().time_since_epoch());
673 // constant scaling is used here to simplify checking for the
674 // expected results. Default settings of the device lead to no
675 // scaling at all.
676@@ -158,7 +157,7 @@
677 auto rel_y = pointer.rel_y * acceleration;
678
679 update_position(rel_x, rel_y);
680- auto pointer_event = builder->pointer_event(event_time,
681+ auto pointer_event = builder->pointer_event(clock->now(),
682 mir_pointer_action_motion,
683 buttons,
684 pos.x.as_float(),
685@@ -182,10 +181,7 @@
686 if (!sink)
687 BOOST_THROW_EXCEPTION(std::runtime_error("Device is not started."));
688
689- auto event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(
690- std::chrono::system_clock::now().time_since_epoch());
691-
692- auto touch_event = builder->touch_event(event_time);
693+ auto touch_event = builder->touch_event(clock->now());
694
695 auto touch_action = mir_touch_action_up;
696 if (touch.action == synthesis::TouchParameters::Action::Tap)
697
698=== modified file 'tests/mir_test_framework/fake_input_device_impl.h'
699--- tests/mir_test_framework/fake_input_device_impl.h 2015-11-04 07:43:28 +0000
700+++ tests/mir_test_framework/fake_input_device_impl.h 2015-11-12 20:43:41 +0000
701@@ -32,6 +32,10 @@
702 {
703 class ActionQueue;
704 }
705+namespace time
706+{
707+class Clock;
708+}
709 }
710
711 namespace mir_test_framework
712@@ -46,7 +50,6 @@
713 void emit_event(synthesis::MotionParameters const& motion) override;
714 void emit_event(synthesis::TouchParameters const& touch) override;
715
716-private:
717 class InputDevice : public mir::input::InputDevice
718 {
719 public:
720@@ -70,6 +73,8 @@
721 mir::optional_value<mir::input::TouchpadSettings> get_touchpad_settings() const override;
722 void apply_settings(mir::input::TouchpadSettings const& settings) override;
723
724+ void set_clock(std::shared_ptr<mir::time::Clock> const& clock);
725+
726 private:
727 MirPointerAction update_buttons(synthesis::EventAction action, MirPointerButton button);
728 void update_position(int rel_x, int rel_y);
729@@ -82,7 +87,9 @@
730 mir::geometry::Point pos, scroll;
731 MirPointerButtons buttons;
732 mir::input::PointerSettings settings;
733+ std::shared_ptr<mir::time::Clock> clock;
734 };
735+private:
736 std::shared_ptr<mir::dispatch::ActionQueue> queue;
737 std::shared_ptr<InputDevice> device;
738 };
739
740=== modified file 'tests/mir_test_framework/stub_input.cpp'
741--- tests/mir_test_framework/stub_input.cpp 2015-11-12 20:43:40 +0000
742+++ tests/mir_test_framework/stub_input.cpp 2015-11-12 20:43:41 +0000
743@@ -29,10 +29,11 @@
744 std::shared_ptr<mo::Option> const& /*options*/,
745 std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/,
746 std::shared_ptr<mi::InputDeviceRegistry> const& input_device_registry,
747- std::shared_ptr<mi::InputReport> const& /*report*/)
748+ std::shared_ptr<mi::InputReport> const& /*report*/,
749+ std::shared_ptr<mir::time::Clock> const& clock)
750 {
751 mir::assert_entry_point_signature<mi::CreatePlatform>(&create_input_platform);
752- return mir::make_module_ptr<mtf::StubInputPlatform>(input_device_registry);
753+ return mir::make_module_ptr<mtf::StubInputPlatform>(input_device_registry, clock);
754 }
755
756 void add_input_platform_options(
757
758=== modified file 'tests/mir_test_framework/stub_input_platform.cpp'
759--- tests/mir_test_framework/stub_input_platform.cpp 2015-10-12 08:08:58 +0000
760+++ tests/mir_test_framework/stub_input_platform.cpp 2015-11-12 20:43:41 +0000
761@@ -17,6 +17,7 @@
762 */
763
764 #include "stub_input_platform.h"
765+#include "fake_input_device_impl.h"
766
767 #include "mir/input/input_device_registry.h"
768 #include "mir/dispatch/action_queue.h"
769@@ -29,10 +30,10 @@
770 namespace mi = mir::input;
771
772 mtf::StubInputPlatform::StubInputPlatform(
773- std::shared_ptr<mi::InputDeviceRegistry> const& input_device_registry)
774+ std::shared_ptr<mi::InputDeviceRegistry> const& input_device_registry, std::shared_ptr<mir::time::Clock> const& clock)
775 : platform_dispatchable{std::make_shared<mir::dispatch::MultiplexingDispatchable>()},
776 platform_queue{std::make_shared<mir::dispatch::ActionQueue>()},
777- registry(input_device_registry)
778+ registry(input_device_registry), clock(clock)
779 {
780 stub_input_platform = this;
781 platform_dispatchable->add_watch(platform_queue);
782@@ -50,7 +51,13 @@
783 {
784 auto device = dev.lock();
785 if (device)
786+ {
787+ auto fake_dev = std::dynamic_pointer_cast<FakeInputDeviceImpl::InputDevice>(device);
788+ if (fake_dev)
789+ fake_dev->set_clock(clock);
790+
791 registry->add_device(device);
792+ }
793 }
794 }
795
796@@ -78,6 +85,10 @@
797 return;
798 }
799
800+ auto fake_dev = std::dynamic_pointer_cast<FakeInputDeviceImpl::InputDevice>(dev);
801+ if (fake_dev)
802+ fake_dev->set_clock(input_platform->clock);
803+
804 input_platform->platform_queue->enqueue(
805 [registry=input_platform->registry,dev]
806 {
807
808=== modified file 'tests/mir_test_framework/stub_input_platform.h'
809--- tests/mir_test_framework/stub_input_platform.h 2015-10-12 08:08:58 +0000
810+++ tests/mir_test_framework/stub_input_platform.h 2015-11-12 20:43:41 +0000
811@@ -41,7 +41,7 @@
812 class StubInputPlatform : public mir::input::Platform
813 {
814 public:
815- explicit StubInputPlatform(std::shared_ptr<mir::input::InputDeviceRegistry> const& input_device_registry);
816+ explicit StubInputPlatform(std::shared_ptr<mir::input::InputDeviceRegistry> const& input_device_registry, std::shared_ptr<mir::time::Clock> const& clock);
817 ~StubInputPlatform();
818
819 std::shared_ptr<mir::dispatch::Dispatchable> dispatchable() override;
820@@ -57,6 +57,7 @@
821 std::shared_ptr<mir::dispatch::MultiplexingDispatchable> const platform_dispatchable;
822 std::shared_ptr<mir::dispatch::ActionQueue> const platform_queue;
823 std::shared_ptr<mir::input::InputDeviceRegistry> const registry;
824+ std::shared_ptr<mir::time::Clock> const clock;
825 static std::atomic<StubInputPlatform*> stub_input_platform;
826 static std::vector<std::weak_ptr<mir::input::InputDevice>> device_store;
827 };
828
829=== modified file 'tests/unit-tests/input/evdev/test_evdev_input_platform.cpp'
830--- tests/unit-tests/input/evdev/test_evdev_input_platform.cpp 2015-10-05 02:18:18 +0000
831+++ tests/unit-tests/input/evdev/test_evdev_input_platform.cpp 2015-11-12 20:43:41 +0000
832@@ -26,6 +26,7 @@
833 #include "mir_test_framework/udev_environment.h"
834 #include "mir/test/fake_shared.h"
835 #include "mir/test/doubles/mock_libinput.h"
836+#include "mir/test/doubles/advanceable_clock.h"
837
838 #include <gtest/gtest.h>
839 #include <gmock/gmock.h>
840@@ -57,6 +58,7 @@
841 mir_test_framework::UdevEnvironment env;
842 testing::NiceMock<mtd::MockLibInput> mock_libinput;
843 testing::NiceMock<MockInputDeviceRegistry> mock_registry;
844+ mtd::AdvanceableClock fake_clock;
845 libinput *li_context{reinterpret_cast<libinput*>(0xFEBA)};
846
847 std::vector<std::pair<std::string, libinput_device*>> devices;
848@@ -142,7 +144,7 @@
849 auto ctx = std::make_unique<mu::Context>();
850 auto monitor = std::make_unique<mu::Monitor>(*ctx.get());
851 return std::make_unique<mie::Platform>(mt::fake_shared(mock_registry), mr::null_input_report(), std::move(ctx),
852- std::move(monitor));
853+ std::move(monitor), mt::fake_shared(fake_clock));
854 }
855
856 void remove_devices()
857
858=== modified file 'tests/unit-tests/input/evdev/test_libinput_device.cpp'
859--- tests/unit-tests/input/evdev/test_libinput_device.cpp 2015-11-05 13:13:10 +0000
860+++ tests/unit-tests/input/evdev/test_libinput_device.cpp 2015-11-12 20:43:41 +0000
861@@ -29,17 +29,21 @@
862 #include "mir/geometry/rectangle.h"
863 #include "mir/test/event_matchers.h"
864 #include "mir/test/doubles/mock_libinput.h"
865+#include "mir/test/doubles/advanceable_clock.h"
866 #include "mir/test/gmock_fixes.h"
867+#include "mir/test/fake_shared.h"
868 #include "mir/udev/wrapper.h"
869 #include "mir/cookie_factory.h"
870 #include "mir_test_framework/udev_environment.h"
871
872 #include <gmock/gmock.h>
873 #include <gtest/gtest.h>
874+#include <boost/throw_exception.hpp>
875 #include <linux/input.h>
876 #include <libinput.h>
877
878 #include <chrono>
879+#include <stdexcept>
880
881 namespace mi = mir::input;
882 namespace mie = mi::evdev;
883@@ -121,10 +125,36 @@
884 MOCK_METHOD2(configuration_event, mir::EventUPtr(Timestamp, MirInputConfigurationAction));
885 };
886
887+struct TimestampVector : public mir::time::Clock
888+{
889+ mir::time::Timestamp now() const override
890+ {
891+ if (time_stamps.empty())
892+ BOOST_THROW_EXCEPTION(std::logic_error("Test requires more time stamps"));
893+ auto now = time_stamps.front();
894+ time_stamps.erase(time_stamps.begin());
895+ return now;
896+ }
897+
898+ mir::time::Duration min_wait_until(mir::time::Timestamp) const override
899+ {
900+ return mir::time::Duration{0};
901+ }
902+
903+ void add_time_stamp(mir::time::Timestamp event_time_stamp)
904+ {
905+ time_stamps.push_back(event_time_stamp);
906+ }
907+
908+private:
909+ std::vector<mir::time::Timestamp> mutable time_stamps;
910+};
911+
912 struct LibInputDevice : public ::testing::Test
913 {
914 mtf::UdevEnvironment env;
915 ::testing::NiceMock<mir::test::doubles::MockLibInput> mock_libinput;
916+ TimestampVector fake_clock;
917 ::testing::NiceMock<MockInputSink> mock_sink;
918 ::testing::NiceMock<MockEventBuilder> mock_builder;
919 std::shared_ptr<libinput> lib;
920@@ -137,14 +167,10 @@
921 libinput_event* fake_event_4 = reinterpret_cast<libinput_event*>(0xF4C8);
922 libinput_device* second_fake_device = reinterpret_cast<libinput_device*>(0xF4C9);
923
924- const uint64_t event_time_1 = 1000;
925- const mi::EventBuilder::Timestamp time_stamp_1{std::chrono::microseconds{event_time_1}};
926- const uint64_t event_time_2 = 2000;
927- const mi::EventBuilder::Timestamp time_stamp_2{std::chrono::microseconds{event_time_2}};
928- const uint64_t event_time_3 = 3000;
929- const mi::EventBuilder::Timestamp time_stamp_3{std::chrono::microseconds{event_time_3}};
930- const uint64_t event_time_4 = 4000;
931- const mi::EventBuilder::Timestamp time_stamp_4{std::chrono::microseconds{event_time_4}};
932+ const mir::time::Timestamp time_stamp_1{std::chrono::microseconds{1000}};
933+ const mir::time::Timestamp time_stamp_2{std::chrono::microseconds{2000}};
934+ const mir::time::Timestamp time_stamp_3{std::chrono::microseconds{3000}};
935+ const mir::time::Timestamp time_stamp_4{std::chrono::microseconds{4000}};
936
937 char const* laptop_keyboard_device_path = "/dev/input/event4";
938 char const* trackpad_dev_path = "/dev/input/event13";
939@@ -261,80 +287,77 @@
940
941 }
942
943- void setup_key_event(libinput_event* event, uint64_t event_time, uint32_t key, libinput_key_state state)
944+ void setup_key_event(libinput_event* event, mir::time::Timestamp event_time, uint32_t key, libinput_key_state state)
945 {
946 auto key_event = reinterpret_cast<libinput_event_keyboard*>(event);
947+ fake_clock.add_time_stamp(event_time);
948
949 ON_CALL(mock_libinput, libinput_event_get_type(event))
950 .WillByDefault(Return(LIBINPUT_EVENT_KEYBOARD_KEY));
951 ON_CALL(mock_libinput, libinput_event_get_keyboard_event(event))
952 .WillByDefault(Return(key_event));
953- ON_CALL(mock_libinput, libinput_event_keyboard_get_time_usec(key_event))
954- .WillByDefault(Return(event_time));
955 ON_CALL(mock_libinput, libinput_event_keyboard_get_key(key_event))
956 .WillByDefault(Return(key));
957 ON_CALL(mock_libinput, libinput_event_keyboard_get_key_state(key_event))
958 .WillByDefault(Return(state));
959 }
960
961- void setup_pointer_event(libinput_event* event, uint64_t event_time, float relatve_x, float relatve_y)
962+ void setup_pointer_event(libinput_event* event, mir::time::Timestamp event_time, float relatve_x, float relatve_y)
963 {
964 auto pointer_event = reinterpret_cast<libinput_event_pointer*>(event);
965+ fake_clock.add_time_stamp(event_time);
966
967 ON_CALL(mock_libinput, libinput_event_get_type(event))
968 .WillByDefault(Return(LIBINPUT_EVENT_POINTER_MOTION));
969 ON_CALL(mock_libinput, libinput_event_get_pointer_event(event))
970 .WillByDefault(Return(pointer_event));
971- ON_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
972- .WillByDefault(Return(event_time));
973 ON_CALL(mock_libinput, libinput_event_pointer_get_dx(pointer_event))
974 .WillByDefault(Return(relatve_x));
975 ON_CALL(mock_libinput, libinput_event_pointer_get_dy(pointer_event))
976 .WillByDefault(Return(relatve_y));
977 }
978
979- void setup_absolute_pointer_event(libinput_event* event, uint64_t event_time, float x, float y)
980+ void setup_absolute_pointer_event(libinput_event * event, mir::time::Timestamp event_time, float x, float y)
981 {
982 auto pointer_event = reinterpret_cast<libinput_event_pointer*>(event);
983+ fake_clock.add_time_stamp(event_time);
984
985 ON_CALL(mock_libinput, libinput_event_get_type(event))
986 .WillByDefault(Return(LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE));
987 ON_CALL(mock_libinput, libinput_event_get_pointer_event(event))
988 .WillByDefault(Return(pointer_event));
989- ON_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
990- .WillByDefault(Return(event_time));
991 ON_CALL(mock_libinput, libinput_event_pointer_get_absolute_x_transformed(pointer_event, _))
992 .WillByDefault(Return(x));
993 ON_CALL(mock_libinput, libinput_event_pointer_get_absolute_y_transformed(pointer_event, _))
994 .WillByDefault(Return(y));
995 }
996
997- void setup_button_event(libinput_event* event, uint64_t event_time, int button, libinput_button_state state)
998+ void setup_button_event(libinput_event * event, mir::time::Timestamp event_time, int button,
999+ libinput_button_state state)
1000 {
1001 auto pointer_event = reinterpret_cast<libinput_event_pointer*>(event);
1002+ fake_clock.add_time_stamp(event_time);
1003
1004 ON_CALL(mock_libinput, libinput_event_get_type(event))
1005 .WillByDefault(Return(LIBINPUT_EVENT_POINTER_BUTTON));
1006 ON_CALL(mock_libinput, libinput_event_get_pointer_event(event))
1007 .WillByDefault(Return(pointer_event));
1008- ON_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
1009- .WillByDefault(Return(event_time));
1010 ON_CALL(mock_libinput, libinput_event_pointer_get_button(pointer_event))
1011 .WillByDefault(Return(button));
1012 ON_CALL(mock_libinput, libinput_event_pointer_get_button_state(pointer_event))
1013 .WillByDefault(Return(state));
1014 }
1015
1016- void setup_axis_event(libinput_event* event, uint64_t event_time, double horizontal, double vertical)
1017+ void setup_axis_event(libinput_event * event, mir::time::Timestamp event_time, double horizontal,
1018+ double vertical)
1019 {
1020 auto pointer_event = reinterpret_cast<libinput_event_pointer*>(event);
1021+ fake_clock.add_time_stamp(event_time);
1022
1023 ON_CALL(mock_libinput, libinput_event_get_type(event))
1024 .WillByDefault(Return(LIBINPUT_EVENT_POINTER_AXIS));
1025 ON_CALL(mock_libinput, libinput_event_get_pointer_event(event))
1026 .WillByDefault(Return(pointer_event));
1027- ON_CALL(mock_libinput, libinput_event_pointer_get_time_usec(pointer_event))
1028- .WillByDefault(Return(event_time));
1029 ON_CALL(mock_libinput, libinput_event_pointer_has_axis(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
1030 .WillByDefault(Return(horizontal!=0.0));
1031 ON_CALL(mock_libinput, libinput_event_pointer_has_axis(pointer_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
1032@@ -345,10 +368,11 @@
1033 .WillByDefault(Return(horizontal));
1034 }
1035
1036- void setup_touch_event(libinput_event* event, libinput_event_type type, uint64_t event_time, int slot, float x,
1037- float y, float major, float minor, float pressure)
1038+ void setup_touch_event(libinput_event * event, libinput_event_type type, mir::time::Timestamp event_time,
1039+ int slot, float x, float y, float major, float minor, float pressure)
1040 {
1041 auto touch_event = reinterpret_cast<libinput_event_touch*>(event);
1042+ fake_clock.add_time_stamp(event_time);
1043
1044 ON_CALL(mock_libinput, libinput_event_get_type(event))
1045 .WillByDefault(Return(type));
1046@@ -360,8 +384,6 @@
1047 .WillByDefault(Return(x));
1048 ON_CALL(mock_libinput, libinput_event_touch_get_y_transformed(touch_event, _))
1049 .WillByDefault(Return(y));
1050- ON_CALL(mock_libinput, libinput_event_touch_get_time_usec(touch_event))
1051- .WillByDefault(Return(event_time));
1052 ON_CALL(mock_libinput, libinput_event_touch_get_major_transformed(touch_event, _, _))
1053 .WillByDefault(Return(major));
1054 ON_CALL(mock_libinput, libinput_event_touch_get_minor_transformed(touch_event, _, _))
1055@@ -370,9 +392,10 @@
1056 .WillByDefault(Return(pressure));
1057 }
1058
1059- void setup_touch_up_event(libinput_event* event, uint64_t event_time, int slot)
1060+ void setup_touch_up_event(libinput_event* event, mir::time::Timestamp event_time, int slot)
1061 {
1062 auto touch_event = reinterpret_cast<libinput_event_touch*>(event);
1063+ fake_clock.add_time_stamp(event_time);
1064
1065 ON_CALL(mock_libinput, libinput_event_get_type(event))
1066 .WillByDefault(Return(LIBINPUT_EVENT_TOUCH_UP));
1067@@ -380,8 +403,6 @@
1068 .WillByDefault(Return(touch_event));
1069 ON_CALL(mock_libinput, libinput_event_touch_get_slot(touch_event))
1070 .WillByDefault(Return(slot));
1071- ON_CALL(mock_libinput, libinput_event_touch_get_time_usec(touch_event))
1072- .WillByDefault(Return(event_time));
1073 }
1074
1075 void setup_touch_frame(libinput_event* event)
1076@@ -394,39 +415,45 @@
1077 struct LibInputDeviceOnLaptopKeyboard : public LibInputDevice
1078 {
1079 char const* keyboard_path = setup_laptop_keyboard(fake_device);
1080- mie::LibInputDevice keyboard{mir::report::null_input_report(), keyboard_path, mie::make_libinput_device(lib.get(), keyboard_path)};
1081+ mie::LibInputDevice keyboard{mir::report::null_input_report(), mt::fake_shared(fake_clock), keyboard_path,
1082+ mie::make_libinput_device(lib.get(), keyboard_path)};
1083 };
1084
1085 struct LibInputDeviceOnMouse : public LibInputDevice
1086 {
1087 char const* mouse_path = setup_mouse(fake_device);
1088- mie::LibInputDevice mouse{mir::report::null_input_report(), mouse_path, mie::make_libinput_device(lib.get(), mouse_path)};
1089+ mie::LibInputDevice mouse{mir::report::null_input_report(), mt::fake_shared(fake_clock), mouse_path,
1090+ mie::make_libinput_device(lib.get(), mouse_path)};
1091 };
1092
1093 struct LibInputDeviceOnLaptopKeyboardAndMouse : public LibInputDevice
1094 {
1095 char const* mouse_path = setup_mouse(fake_device);
1096 char const* keyboard_path = setup_laptop_keyboard(fake_device);
1097- mie::LibInputDevice keyboard{mir::report::null_input_report(), keyboard_path, mie::make_libinput_device(lib.get(), keyboard_path)};
1098- mie::LibInputDevice mouse{mir::report::null_input_report(), mouse_path, mie::make_libinput_device(lib.get(), mouse_path)};
1099+ mie::LibInputDevice keyboard{mir::report::null_input_report(), mt::fake_shared(fake_clock), keyboard_path,
1100+ mie::make_libinput_device(lib.get(), keyboard_path)};
1101+ mie::LibInputDevice mouse{mir::report::null_input_report(), mt::fake_shared(fake_clock), mouse_path,
1102+ mie::make_libinput_device(lib.get(), mouse_path)};
1103 };
1104
1105 struct LibInputDeviceOnTouchScreen : public LibInputDevice
1106 {
1107 char const* touch_screen_path = setup_touch_screen(fake_device);
1108- mie::LibInputDevice touch_screen{mir::report::null_input_report(), touch_screen_path, mie::make_libinput_device(lib.get(), touch_screen_path)};
1109+ mie::LibInputDevice touch_screen{mir::report::null_input_report(), mt::fake_shared(fake_clock), touch_screen_path,
1110+ mie::make_libinput_device(lib.get(), touch_screen_path)};
1111 };
1112
1113 struct LibInputDeviceOnTouchpad : public LibInputDevice
1114 {
1115 char const* touchpad_path = setup_touchpad(fake_device);
1116- mie::LibInputDevice touchpad{mir::report::null_input_report(), touchpad_path, mie::make_libinput_device(lib.get(), touchpad_path)};
1117+ mie::LibInputDevice touchpad{mir::report::null_input_report(), mt::fake_shared(fake_clock), touchpad_path,
1118+ mie::make_libinput_device(lib.get(), touchpad_path)};
1119 };
1120 }
1121
1122 TEST_F(LibInputDevice, start_creates_and_unrefs_libinput_device_from_path)
1123 {
1124- char const * path = setup_laptop_keyboard(fake_device);
1125+ char const* path = setup_laptop_keyboard(fake_device);
1126
1127 EXPECT_CALL(mock_libinput, libinput_path_add_device(fake_input,StrEq(path)))
1128 .Times(1);
1129@@ -435,8 +462,7 @@
1130 EXPECT_CALL(mock_libinput, libinput_device_ref(fake_device))
1131 .Times(1);
1132
1133- mie::LibInputDevice dev(mir::report::null_input_report(),
1134- path,
1135+ mie::LibInputDevice dev(mir::report::null_input_report(), mt::fake_shared(fake_clock), path,
1136 std::move(mie::make_libinput_device(lib.get(), path)));
1137 dev.start(&mock_sink, &mock_builder);
1138 }
1139@@ -454,8 +480,7 @@
1140 EXPECT_CALL(mock_libinput, libinput_path_add_device(fake_input,StrEq(second_path))).Times(1);
1141 EXPECT_CALL(mock_libinput, libinput_device_ref(second_fake_device)).Times(1);
1142
1143- mie::LibInputDevice dev(mir::report::null_input_report(),
1144- first_path,
1145+ mie::LibInputDevice dev(mir::report::null_input_report(), mt::fake_shared(fake_clock), first_path,
1146 std::move(mie::make_libinput_device(lib.get(), first_path)));
1147 dev.add_device_of_group(second_path, mie::make_libinput_device(lib.get(), second_path));
1148 dev.start(&mock_sink, &mock_builder);
1149@@ -466,8 +491,7 @@
1150 char const* first_dev = setup_laptop_keyboard(fake_device);
1151 char const* second_dev = setup_trackpad(second_fake_device);
1152
1153- mie::LibInputDevice dev(mir::report::null_input_report(),
1154- first_dev,
1155+ mie::LibInputDevice dev(mir::report::null_input_report(), mt::fake_shared(fake_clock), first_dev,
1156 mie::make_libinput_device(lib.get(), first_dev));
1157 dev.add_device_of_group(second_dev, mie::make_libinput_device(lib.get(), second_dev));
1158 auto info = dev.get_device_info();
1159@@ -481,16 +505,16 @@
1160 {
1161 char const* path = setup_laptop_keyboard(fake_device);
1162
1163- EXPECT_CALL(mock_libinput, libinput_device_unref(fake_device))
1164- .Times(1);
1165+ EXPECT_CALL(mock_libinput, libinput_device_unref(fake_device)).Times(1);
1166
1167- mie::LibInputDevice dev(mir::report::null_input_report(), path, mie::make_libinput_device(lib.get(), path));
1168+ mie::LibInputDevice dev(mir::report::null_input_report(), mt::fake_shared(fake_clock), path,
1169+ mie::make_libinput_device(lib.get(), path));
1170 }
1171
1172 TEST_F(LibInputDeviceOnLaptopKeyboard, process_event_converts_key_event)
1173 {
1174- setup_key_event(fake_event_1, event_time_1, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
1175- setup_key_event(fake_event_2, event_time_2, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
1176+ setup_key_event(fake_event_1, time_stamp_1, KEY_A, LIBINPUT_KEY_STATE_PRESSED);
1177+ setup_key_event(fake_event_2, time_stamp_2, KEY_A, LIBINPUT_KEY_STATE_RELEASED);
1178
1179 EXPECT_CALL(mock_builder, key_event(time_stamp_1, mir_keyboard_action_down, _, KEY_A));
1180 EXPECT_CALL(mock_sink, handle_input(AllOf(mt::KeyOfScanCode(KEY_A),mt::KeyDownEvent())));
1181@@ -504,9 +528,9 @@
1182
1183 TEST_F(LibInputDeviceOnLaptopKeyboard, process_event_accumulates_key_state)
1184 {
1185- setup_key_event(fake_event_1, event_time_1, KEY_C, LIBINPUT_KEY_STATE_PRESSED);
1186- setup_key_event(fake_event_2, event_time_2, KEY_LEFTALT, LIBINPUT_KEY_STATE_PRESSED);
1187- setup_key_event(fake_event_3, event_time_3, KEY_C, LIBINPUT_KEY_STATE_RELEASED);
1188+ setup_key_event(fake_event_1, time_stamp_1, KEY_C, LIBINPUT_KEY_STATE_PRESSED);
1189+ setup_key_event(fake_event_2, time_stamp_2, KEY_LEFTALT, LIBINPUT_KEY_STATE_PRESSED);
1190+ setup_key_event(fake_event_3, time_stamp_3, KEY_C, LIBINPUT_KEY_STATE_RELEASED);
1191
1192 InSequence seq;
1193 EXPECT_CALL(mock_builder, key_event(time_stamp_1, mir_keyboard_action_down, _, KEY_C));
1194@@ -529,8 +553,8 @@
1195 float y_movement_1 = 17;
1196 float x_movement_2 = 20;
1197 float y_movement_2 = 40;
1198- setup_pointer_event(fake_event_1, event_time_1, x_movement_1, y_movement_1);
1199- setup_pointer_event(fake_event_2, event_time_2, x_movement_2, y_movement_2);
1200+ setup_pointer_event(fake_event_1, time_stamp_1, x_movement_1, y_movement_1);
1201+ setup_pointer_event(fake_event_2, time_stamp_2, x_movement_2, y_movement_2);
1202
1203 EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithDiff(x_movement_1,y_movement_1)));
1204 EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithDiff(x_movement_2,y_movement_2)));
1205@@ -546,8 +570,8 @@
1206 float y1 = 17;
1207 float x2 = 40;
1208 float y2 = 10;
1209- setup_absolute_pointer_event(fake_event_1, event_time_1, x1, y1);
1210- setup_absolute_pointer_event(fake_event_2, event_time_2, x2, y2);
1211+ setup_absolute_pointer_event(fake_event_1, time_stamp_1, x1, y1);
1212+ setup_absolute_pointer_event(fake_event_2, time_stamp_2, x2, y2);
1213
1214 EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithPosition(x1, y1)));
1215 EXPECT_CALL(mock_sink,
1216@@ -562,7 +586,7 @@
1217 {
1218 float x = -5;
1219 float y = 20;
1220- setup_pointer_event(fake_event_1, event_time_1, x, y);
1221+ setup_pointer_event(fake_event_1, time_stamp_1, x, y);
1222
1223 EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithDiff(x,y)));
1224
1225@@ -575,8 +599,8 @@
1226 float x1 = 15, x2 = 23;
1227 float y1 = 17, y2 = 21;
1228
1229- setup_pointer_event(fake_event_1, event_time_1, x1, y1);
1230- setup_pointer_event(fake_event_2, event_time_2, x2, y2);
1231+ setup_pointer_event(fake_event_1, time_stamp_1, x1, y1);
1232+ setup_pointer_event(fake_event_2, time_stamp_2, x2, y2);
1233
1234 EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithPosition(x1,y1)));
1235 EXPECT_CALL(mock_sink, handle_input(mt::PointerEventWithPosition(x1+x2,y1+y2)));
1236@@ -592,10 +616,10 @@
1237 float const y = 0;
1238 geom::Point const pos{x, y};
1239
1240- setup_button_event(fake_event_1, event_time_1, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
1241- setup_button_event(fake_event_2, event_time_2, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
1242- setup_button_event(fake_event_3, event_time_3, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
1243- setup_button_event(fake_event_4, event_time_4, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
1244+ setup_button_event(fake_event_1, time_stamp_1, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
1245+ setup_button_event(fake_event_2, time_stamp_2, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
1246+ setup_button_event(fake_event_3, time_stamp_3, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
1247+ setup_button_event(fake_event_4, time_stamp_4, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
1248
1249 InSequence seq;
1250 EXPECT_CALL(mock_sink, handle_input(mt::ButtonDownEventWithButton(pos, mir_pointer_button_primary)));
1251@@ -612,8 +636,8 @@
1252
1253 TEST_F(LibInputDeviceOnMouse, process_event_handles_scroll)
1254 {
1255- setup_axis_event(fake_event_1, event_time_1, 0.0, 20.0);
1256- setup_axis_event(fake_event_2, event_time_2, 5.0, 0.0);
1257+ setup_axis_event(fake_event_1, time_stamp_1, 0.0, 20.0);
1258+ setup_axis_event(fake_event_2, time_stamp_2, 5.0, 0.0);
1259
1260 InSequence seq;
1261 // expect two scroll events..
1262@@ -638,7 +662,7 @@
1263 float x = 100;
1264 float y = 7;
1265
1266- setup_touch_event(fake_event_1, LIBINPUT_EVENT_TOUCH_DOWN, event_time_1, slot, x, y, major, minor, pressure);
1267+ setup_touch_event(fake_event_1, LIBINPUT_EVENT_TOUCH_DOWN, time_stamp_1, slot, x, y, major, minor, pressure);
1268 setup_touch_frame(fake_event_2);
1269
1270 InSequence seq;
1271@@ -661,7 +685,7 @@
1272 float x = 100;
1273 float y = 7;
1274
1275- setup_touch_event(fake_event_1, LIBINPUT_EVENT_TOUCH_MOTION, event_time_1, slot, x, y, major, minor, pressure);
1276+ setup_touch_event(fake_event_1, LIBINPUT_EVENT_TOUCH_MOTION, time_stamp_1, slot, x, y, major, minor, pressure);
1277 setup_touch_frame(fake_event_2);
1278
1279 InSequence seq;
1280@@ -684,9 +708,9 @@
1281 float x = 30;
1282 float y = 20;
1283
1284- setup_touch_event(fake_event_1, LIBINPUT_EVENT_TOUCH_DOWN, event_time_1, slot, x, y, major, minor, pressure);
1285+ setup_touch_event(fake_event_1, LIBINPUT_EVENT_TOUCH_DOWN, time_stamp_1, slot, x, y, major, minor, pressure);
1286 setup_touch_frame(fake_event_2);
1287- setup_touch_up_event(fake_event_3, event_time_2, slot);
1288+ setup_touch_up_event(fake_event_3, time_stamp_2, slot);
1289 setup_touch_frame(fake_event_4);
1290
1291 InSequence seq;
1292@@ -763,8 +787,8 @@
1293
1294 TEST_F(LibInputDeviceOnMouse, scroll_speed_scales_scroll_events)
1295 {
1296- setup_axis_event(fake_event_1, event_time_1, 0.0, 3.0);
1297- setup_axis_event(fake_event_2, event_time_2, -2.0, 0.0);
1298+ setup_axis_event(fake_event_1, time_stamp_1, 0.0, 3.0);
1299+ setup_axis_event(fake_event_2, time_stamp_2, -2.0, 0.0);
1300
1301 // expect two scroll events..
1302 EXPECT_CALL(mock_sink, handle_input(mt::PointerAxisChange(mir_pointer_axis_vscroll, -3.0f)));
1303
1304=== modified file 'tests/unit-tests/input/test_default_input_device_hub.cpp'
1305--- tests/unit-tests/input/test_default_input_device_hub.cpp 2015-11-04 07:43:28 +0000
1306+++ tests/unit-tests/input/test_default_input_device_hub.cpp 2015-11-12 20:43:41 +0000
1307@@ -113,7 +113,7 @@
1308 Nice<MockInputDevice> another_device;
1309 Nice<MockInputDevice> third_device;
1310
1311- std::chrono::nanoseconds arbitrary_timestamp;
1312+ mir::time::Timestamp arbitrary_timestamp;
1313
1314 InputDeviceHubTest()
1315 {
1316@@ -384,7 +384,7 @@
1317 capture_input_sink(device, sink, builder);
1318 hub.add_device(mt::fake_shared(device));
1319
1320- auto event = builder->pointer_event(0ns, mir_pointer_action_motion, 0, x, y, 0.0f, 0.0f, 0.0f, 0.0f);
1321+ auto event = builder->pointer_event(arbitrary_timestamp, mir_pointer_action_motion, 0, x, y, 0.0f, 0.0f, 0.0f, 0.0f);
1322
1323 EXPECT_CALL(mock_cursor_listener, cursor_moved_to(x, y)).Times(1);
1324

Subscribers

People subscribed via source and target branches