Merge lp:~mir-team/mir/unify-pointer-button into lp:mir
- unify-pointer-button
- Merge into development-branch
Status: | Superseded |
---|---|
Proposed branch: | lp:~mir-team/mir/unify-pointer-button |
Merge into: | lp:mir |
Prerequisite: | lp:~mir-team/mir/remaining-nsec-removal |
Diff against target: |
2677 lines (+854/-963) 40 files modified
3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp (+11/-11) include/client/mir/events/event_builders.h (+1/-2) include/client/mir_toolkit/events/input/pointer_event.h (+15/-5) src/client/events/event_builders.cpp (+19/-30) src/client/input/android/android_input_lexicon.cpp (+1/-1) src/client/input/android/event_conversion_helpers.cpp (+34/-0) src/client/input/input_event.cpp (+11/-5) src/client/symbols.map (+3/-0) src/include/common/mir/events/event_private.h (+1/-9) src/include/common/mir/input/android/event_conversion_helpers.h (+3/-1) src/server/input/android/android_input_dispatcher.cpp (+1/-1) src/server/input/android/input_sender.cpp (+1/-1) src/server/input/android/input_translator.cpp (+1/-1) src/server/input/default_configuration.cpp (+2/-0) src/server/input/default_input_device_hub.cpp (+16/-1) src/server/input/default_input_device_hub.h (+4/-0) tests/acceptance-tests/test_client_input.cpp (+510/-69) tests/acceptance-tests/test_surface_modifications.cpp (+2/-4) tests/acceptance-tests/test_surface_placement.cpp (+1/-1) tests/acceptance-tests/throwback/CMakeLists.txt (+0/-1) tests/acceptance-tests/throwback/test_client_input.cpp (+0/-704) tests/acceptance-tests/throwback/test_custom_input_targeter.cpp (+0/-1) tests/include/mir_test/event_matchers.h (+28/-27) tests/include/mir_test_framework/input_testing_server_configuration.h (+0/-22) tests/include/mir_test_framework/placement_applying_shell.h (+59/-0) tests/integration-tests/input/CMakeLists.txt (+1/-4) tests/integration-tests/input/android/CMakeLists.txt (+0/-9) tests/integration-tests/input/test_cursor_listener.cpp (+17/-10) tests/mir_test_framework/CMakeLists.txt (+1/-0) tests/mir_test_framework/fake_input_device_impl.cpp (+3/-3) tests/mir_test_framework/fake_input_device_impl.h (+1/-3) tests/mir_test_framework/input_testing_server_options.cpp (+0/-17) tests/mir_test_framework/placement_applying_shell.cpp (+59/-0) tests/unit-tests/input/android/test_android_input_dispatcher.cpp (+5/-4) tests/unit-tests/input/android/test_android_input_lexicon.cpp (+2/-5) tests/unit-tests/input/android/test_input_translator.cpp (+2/-3) tests/unit-tests/input/test_default_input_device_hub.cpp (+28/-1) tests/unit-tests/input/test_event_builders.cpp (+2/-4) tests/unit-tests/input/test_input_event.cpp (+8/-2) tests/unit-tests/scene/test_abstract_shell.cpp (+1/-1) |
To merge this branch: | bzr merge lp:~mir-team/mir/unify-pointer-button |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alan Griffiths | Needs Fixing | ||
Alexandros Frantzis (community) | Approve | ||
Daniel van Vugt | Needs Fixing | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Andreas Pokorny (community) | Approve | ||
Kevin DuBois (community) | Needs Information | ||
Review via email: mp+258322@code.launchpad.net |
This proposal has been superseded by a proposal from 2015-05-14.
Commit message
Unify the pointer button enums. The new style event buttons are not using a mask so as to allow for extensibility so there is some churn in the change of the internal representation.
Description of the change
Unify the pointer button enums. The new style event buttons are not using a mask so as to allow for extensibility so there is some churn in the change of the internal representation.
This branch is part of the event cleaning pipeline:
Pluck-low-
Unify-event-
Unify-keyboard-
Remaining-
unify-pointer-
https:/
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2548
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alexandros Frantzis (afrantzis) wrote : | # |
> The new style event buttons are not using a mask so as to allow for extensibility so there
> is some churn in the change of the internal representation.
How is having a mask reduce extensibility? Do you mean running out of bits?
190+ bool button_
This will break if we add a new member to the enum (although we will probably catch the issue at compile time). In any case, it's best to introduce a mir_pointer_
Needs info/fixing
Robert Carr (robertcarr) wrote : | # |
Added mir_pointer_
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2549
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2550
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2551
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2553
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
Seems self-consistent.
But I'm a little concerned that other APIs treat buttons as bitmasks (e.g. "143+ android_state |= AMOTION_
Robert Carr (robertcarr) wrote : | # |
I've thought through my concerns that related to nto storing buttons as a flag. Primarly I was worried about exotic devices and allocating button indices for them and potentially running out of flag values. I suppose if anything though such devices would not be pointers and only available throuhg the raw input API so I'm not concerned. Updated branch to use flag...required more client ABI break :)
Kevin DuBois (kdub) wrote : | # |
nonblocking comment:
The bitmask seems okay for now, plenty of unused bits left.
needs-info
77+ mev.button_
Since this appears private now, could we have something more like:
mev.button_
It took a bit of reading of the struct to figure out what was going on in the present form.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2556
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Andreas Pokorny (andreas-pokorny) wrote : | # |
ok looks good apart from the merge conflict
Andreas Pokorny (andreas-pokorny) : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2558
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
(0) MirPointerButton: Definitely a client ABI break now, so we must remember to bump to libmirclient9 ASAP (Alan is working on it but blocked by CI annoyances).
(1) I guess this isn't well tested yet because there's a logic error (should be "&="):
365 - buttons.
366 + buttons |= ~button;
Alexandros Frantzis (afrantzis) wrote : | # |
Besides Daniel's "Needs Fixing", looks good.
Nit:
239-
Why remove the line?
Alan Griffiths (alan-griffiths) wrote : | # |
Agree with Daniel about test coverage and Alexandros about whitespace.
Preview Diff
1 | === modified file '3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp' |
2 | --- 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2015-05-01 08:54:27 +0000 |
3 | +++ 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2015-05-14 18:12:40 +0000 |
4 | @@ -20,30 +20,30 @@ |
5 | //#define LOG_NDEBUG 0 |
6 | |
7 | // Log detailed debug messages about each inbound event notification to the dispatcher. |
8 | -#define DEBUG_INBOUND_EVENT_DETAILS 0 |
9 | +#define DEBUG_INBOUND_EVENT_DETAILS 1 |
10 | |
11 | // Log detailed debug messages about each outbound event processed by the dispatcher. |
12 | -#define DEBUG_OUTBOUND_EVENT_DETAILS 0 |
13 | +#define DEBUG_OUTBOUND_EVENT_DETAILS 1 |
14 | |
15 | // Log debug messages about the dispatch cycle. |
16 | -#define DEBUG_DISPATCH_CYCLE 0 |
17 | +#define DEBUG_DISPATCH_CYCLE 1 |
18 | |
19 | // Log debug messages about registrations. |
20 | -#define DEBUG_REGISTRATION 0 |
21 | +#define DEBUG_REGISTRATION 1 |
22 | |
23 | -// Log debug messages about input event injection. |
24 | -#define DEBUG_INJECTION 0 |
25 | + // Log debug messages about input event injection. |
26 | +#define DEBUG_INJECTION 1 |
27 | |
28 | // Log debug messages about input focus tracking. |
29 | -#define DEBUG_FOCUS 0 |
30 | +#define DEBUG_FOCUS 1 |
31 | |
32 | // Log debug messages about the app switch latency optimization. |
33 | -#define DEBUG_APP_SWITCH 0 |
34 | +#define DEBUG_APP_SWITCH 1 |
35 | |
36 | // Log debug messages about hover events. |
37 | -#define DEBUG_HOVER 0 |
38 | +#define DEBUG_HOVER 1 |
39 | |
40 | -#define ENABLE_APP_SWITCH_OPTIMIZATION 0 |
41 | +#define ENABLE_APP_SWITCH_OPTIMIZATION 1 |
42 | |
43 | #include "InputDispatcher.h" |
44 | |
45 | @@ -3464,7 +3464,7 @@ |
46 | originalKeyCode, keyEntry->action, keyEntry->repeatCount, |
47 | keyEntry->policyFlags); |
48 | #endif |
49 | - return false; |
50 | + return false; |
51 | } |
52 | |
53 | // Dispatch the unhandled key to the policy. |
54 | |
55 | === modified file 'include/client/mir/events/event_builders.h' |
56 | --- include/client/mir/events/event_builders.h 2015-05-05 18:01:08 +0000 |
57 | +++ include/client/mir/events/event_builders.h 2015-05-14 18:12:40 +0000 |
58 | @@ -25,7 +25,6 @@ |
59 | #include "mir/frontend/surface_id.h" |
60 | |
61 | #include <memory> |
62 | -#include <vector> |
63 | #include <functional> |
64 | #include <chrono> |
65 | |
66 | @@ -63,7 +62,7 @@ |
67 | // Pointer event |
68 | EventUPtr make_event(MirInputDeviceId device_id, std::chrono::nanoseconds timestamp, |
69 | MirInputEventModifiers modifiers, MirPointerAction action, |
70 | - std::vector<MirPointerButton> const& buttons_pressed, |
71 | + MirPointerButtons buttons_pressed, |
72 | float x_axis_value, float y_axis_value, |
73 | float hscroll_value, float vscroll_value); |
74 | } |
75 | |
76 | === modified file 'include/client/mir_toolkit/events/input/pointer_event.h' |
77 | --- include/client/mir_toolkit/events/input/pointer_event.h 2015-03-31 02:35:42 +0000 |
78 | +++ include/client/mir_toolkit/events/input/pointer_event.h 2015-05-14 18:12:40 +0000 |
79 | @@ -68,12 +68,13 @@ |
80 | * Identifiers for pointer buttons |
81 | */ |
82 | typedef enum { |
83 | - mir_pointer_button_primary = 1, |
84 | - mir_pointer_button_secondary = 2, |
85 | - mir_pointer_button_tertiary = 3, |
86 | - mir_pointer_button_back = 4, |
87 | - mir_pointer_button_forward = 5 |
88 | + mir_pointer_button_primary = 1 << 0, |
89 | + mir_pointer_button_secondary = 1 << 1, |
90 | + mir_pointer_button_tertiary = 1 << 2, |
91 | + mir_pointer_button_back = 1 << 3, |
92 | + mir_pointer_button_forward = 1 << 4 |
93 | } MirPointerButton; |
94 | +typedef unsigned int MirPointerButtons; |
95 | |
96 | /** |
97 | * Retrieve the modifier keys pressed when the pointer action occured. |
98 | @@ -103,6 +104,15 @@ |
99 | MirPointerButton button); |
100 | |
101 | /** |
102 | + * Retreive the pointer button state as a masked set of values. |
103 | + * |
104 | + * \param [in] event The pointer event |
105 | + * |
106 | + * \return The button state |
107 | + */ |
108 | +MirPointerButtons mir_pointer_event_buttons(MirPointerEvent const* event); |
109 | + |
110 | +/** |
111 | * Retrieve the axis value reported by a given pointer event. |
112 | * |
113 | * \param [in] event The pointer event |
114 | |
115 | === modified file 'src/client/events/event_builders.cpp' |
116 | --- src/client/events/event_builders.cpp 2015-05-08 20:54:52 +0000 |
117 | +++ src/client/events/event_builders.cpp 2015-05-14 18:12:40 +0000 |
118 | @@ -231,29 +231,40 @@ |
119 | |
120 | namespace |
121 | { |
122 | -MirMotionAction old_action_from_pointer_action(MirPointerAction action, MirMotionButton button_state) |
123 | +MirMotionAction old_action_from_pointer_action(MirPointerAction action, int buttons_pressed) |
124 | { |
125 | switch (action) |
126 | { |
127 | case mir_pointer_action_button_up: |
128 | - return mir_motion_action_up; |
129 | + return buttons_pressed == 0 ? mir_motion_action_up : mir_motion_action_pointer_up; |
130 | case mir_pointer_action_button_down: |
131 | - return mir_motion_action_down; |
132 | + return buttons_pressed == 1 ? mir_motion_action_down : mir_motion_action_pointer_down; |
133 | case mir_pointer_action_enter: |
134 | return mir_motion_action_hover_enter; |
135 | case mir_pointer_action_leave: |
136 | return mir_motion_action_hover_exit; |
137 | case mir_pointer_action_motion: |
138 | - return button_state ? mir_motion_action_move : mir_motion_action_hover_move; |
139 | + return buttons_pressed ? mir_motion_action_move : mir_motion_action_hover_move; |
140 | default: |
141 | BOOST_THROW_EXCEPTION(std::logic_error("Invalid pointer action")); |
142 | } |
143 | } |
144 | +int count_buttons(MirPointerButtons buttons) |
145 | +{ |
146 | + int ret = 0; |
147 | + if (buttons & mir_pointer_button_primary) ret++; |
148 | + if (buttons & mir_pointer_button_secondary) ret++; |
149 | + if (buttons & mir_pointer_button_tertiary) ret++; |
150 | + if (buttons & mir_pointer_button_forward) ret++; |
151 | + if (buttons & mir_pointer_button_back) ret++; |
152 | + |
153 | + return ret; |
154 | +} |
155 | } |
156 | |
157 | mir::EventUPtr mev::make_event(MirInputDeviceId device_id, std::chrono::nanoseconds timestamp, |
158 | MirInputEventModifiers modifiers, MirPointerAction action, |
159 | - std::vector<MirPointerButton> const& buttons_pressed, |
160 | + MirPointerButtons buttons_pressed, |
161 | float x_axis_value, float y_axis_value, |
162 | float hscroll_value, float vscroll_value) |
163 | { |
164 | @@ -266,31 +277,9 @@ |
165 | mev.event_time = timestamp; |
166 | mev.modifiers = modifiers; |
167 | mev.source_id = AINPUT_SOURCE_MOUSE; |
168 | - |
169 | - int button_state = 0; |
170 | - for (auto button : buttons_pressed) |
171 | - { |
172 | - switch (button) |
173 | - { |
174 | - case mir_pointer_button_primary: |
175 | - button_state |= mir_motion_button_primary; |
176 | - break; |
177 | - case mir_pointer_button_secondary: |
178 | - button_state |= mir_motion_button_secondary; |
179 | - break; |
180 | - case mir_pointer_button_tertiary: |
181 | - button_state |= mir_motion_button_tertiary; |
182 | - break; |
183 | - case mir_pointer_button_back: |
184 | - button_state |= mir_motion_button_back; |
185 | - break; |
186 | - case mir_pointer_button_forward: |
187 | - button_state |= mir_motion_button_forward; |
188 | - break; |
189 | - } |
190 | - } |
191 | - mev.button_state = static_cast<MirMotionButton>(button_state); |
192 | - mev.action = old_action_from_pointer_action(action, mev.button_state); |
193 | + mev.buttons = buttons_pressed; |
194 | + |
195 | + mev.action = old_action_from_pointer_action(action, count_buttons(buttons_pressed)); |
196 | |
197 | mev.pointer_count = 1; |
198 | auto& pc = mev.pointer_coordinates[0]; |
199 | |
200 | === modified file 'src/client/input/android/android_input_lexicon.cpp' |
201 | --- src/client/input/android/android_input_lexicon.cpp 2015-05-05 18:01:08 +0000 |
202 | +++ src/client/input/android/android_input_lexicon.cpp 2015-05-14 18:12:40 +0000 |
203 | @@ -50,7 +50,7 @@ |
204 | mir_event.motion.source_id = android_event->getSource(); |
205 | mir_event.motion.action = mev->getAction(); |
206 | mir_event.motion.modifiers = mia::mir_modifiers_from_android(mev->getMetaState()); |
207 | - mir_event.motion.button_state = static_cast<MirMotionButton>(mev->getButtonState()); |
208 | + mir_event.motion.buttons = mia::mir_pointer_buttons_from_android(mev->getButtonState()); |
209 | mir_event.motion.event_time = mev->getEventTime(); |
210 | mir_event.motion.pointer_count = mev->getPointerCount(); |
211 | for(unsigned int i = 0; i < mev->getPointerCount(); i++) |
212 | |
213 | === modified file 'src/client/input/android/event_conversion_helpers.cpp' |
214 | --- src/client/input/android/event_conversion_helpers.cpp 2015-05-08 20:44:56 +0000 |
215 | +++ src/client/input/android/event_conversion_helpers.cpp 2015-05-14 18:12:40 +0000 |
216 | @@ -100,3 +100,37 @@ |
217 | return AKEY_EVENT_ACTION_UP; |
218 | } |
219 | } |
220 | + |
221 | +MirPointerButtons mia::mir_pointer_buttons_from_android(int32_t android_state) |
222 | +{ |
223 | + MirPointerButtons buttons = 0; |
224 | + |
225 | + if (android_state & AMOTION_EVENT_BUTTON_PRIMARY) |
226 | + buttons |= mir_pointer_button_primary; |
227 | + if (android_state & AMOTION_EVENT_BUTTON_SECONDARY) |
228 | + buttons |= mir_pointer_button_secondary; |
229 | + if (android_state & AMOTION_EVENT_BUTTON_TERTIARY) |
230 | + buttons |= mir_pointer_button_tertiary; |
231 | + if (android_state & AMOTION_EVENT_BUTTON_BACK) |
232 | + buttons |= mir_pointer_button_back; |
233 | + if (android_state & AMOTION_EVENT_BUTTON_FORWARD) |
234 | + buttons |= mir_pointer_button_forward; |
235 | + |
236 | + return buttons; |
237 | +} |
238 | + |
239 | +int32_t mia::android_pointer_buttons_from_mir(MirPointerButtons buttons) |
240 | +{ |
241 | + int32_t android_state = 0; |
242 | + if (buttons & mir_pointer_button_primary) |
243 | + android_state |= AMOTION_EVENT_BUTTON_PRIMARY; |
244 | + if (buttons & mir_pointer_button_secondary) |
245 | + android_state |= AMOTION_EVENT_BUTTON_SECONDARY; |
246 | + if (buttons & mir_pointer_button_tertiary) |
247 | + android_state |= AMOTION_EVENT_BUTTON_TERTIARY; |
248 | + if (buttons & mir_pointer_button_back) |
249 | + android_state |= AMOTION_EVENT_BUTTON_BACK; |
250 | + if (buttons & mir_pointer_button_forward) |
251 | + android_state |= AMOTION_EVENT_BUTTON_FORWARD; |
252 | + return android_state; |
253 | +} |
254 | |
255 | === modified file 'src/client/input/input_event.cpp' |
256 | --- src/client/input/input_event.cpp 2015-05-05 18:01:08 +0000 |
257 | +++ src/client/input/input_event.cpp 2015-05-14 18:12:40 +0000 |
258 | @@ -424,20 +424,26 @@ |
259 | switch (button) |
260 | { |
261 | case mir_pointer_button_primary: |
262 | - return old_mev.button_state & mir_motion_button_primary; |
263 | + return old_mev.buttons & mir_pointer_button_primary; |
264 | case mir_pointer_button_secondary: |
265 | - return old_mev.button_state & mir_motion_button_secondary; |
266 | + return old_mev.buttons & mir_pointer_button_secondary; |
267 | case mir_pointer_button_tertiary: |
268 | - return old_mev.button_state & mir_motion_button_tertiary; |
269 | + return old_mev.buttons & mir_pointer_button_tertiary; |
270 | case mir_pointer_button_back: |
271 | - return old_mev.button_state & mir_motion_button_back; |
272 | + return old_mev.buttons & mir_pointer_button_back; |
273 | case mir_pointer_button_forward: |
274 | - return old_mev.button_state & mir_motion_button_forward; |
275 | + return old_mev.buttons & mir_pointer_button_forward; |
276 | default: |
277 | return false; |
278 | } |
279 | } |
280 | |
281 | +MirPointerButtons mir_pointer_event_buttons(MirPointerEvent const* pev) |
282 | +{ |
283 | + auto const& old_mev = old_mev_from_new(pev); |
284 | + return old_mev.buttons; |
285 | +} |
286 | + |
287 | float mir_pointer_event_axis_value(MirPointerEvent const* pev, MirPointerAxis axis) |
288 | { |
289 | auto const& old_mev = old_mev_from_new(pev); |
290 | |
291 | === modified file 'src/client/symbols.map' |
292 | --- src/client/symbols.map 2015-05-07 19:41:08 +0000 |
293 | +++ src/client/symbols.map 2015-05-14 18:12:40 +0000 |
294 | @@ -196,6 +196,7 @@ |
295 | mir_buffer_stream_release; |
296 | mir_buffer_stream_release_sync; |
297 | mir_buffer_stream_is_valid; |
298 | + mir_pointer_event_buttons; # Move to 8.5 |
299 | } MIR_CLIENT_8.3; |
300 | |
301 | MIR_CLIENT_DETAIL_8 { |
302 | @@ -208,6 +209,8 @@ |
303 | mir::input::android::mir_modifiers_from_android*; |
304 | mir::input::android::mir_keyboard_action_from_android*; |
305 | mir::input::android::android_keyboard_action_from_mir*; |
306 | + mir::input::android::mir_pointer_buttons_from_android*; |
307 | + mir::input::android::android_pointer_buttons_from_mir*; |
308 | mir::client::DefaultConnectionConfiguration::DefaultConnectionConfiguration*; |
309 | mir::client::DefaultConnectionConfiguration::the_surface_map*; |
310 | mir::client::DefaultConnectionConfiguration::the_rpc_channel*; |
311 | |
312 | === modified file 'src/include/common/mir/events/event_private.h' |
313 | --- src/include/common/mir/events/event_private.h 2015-05-07 19:43:49 +0000 |
314 | +++ src/include/common/mir/events/event_private.h 2015-05-14 18:12:40 +0000 |
315 | @@ -60,14 +60,6 @@ |
316 | } MirMotionAction; |
317 | |
318 | typedef enum { |
319 | - mir_motion_button_primary = 1 << 0, |
320 | - mir_motion_button_secondary = 1 << 1, |
321 | - mir_motion_button_tertiary = 1 << 2, |
322 | - mir_motion_button_back = 1 << 3, |
323 | - mir_motion_button_forward = 1 << 4 |
324 | -} MirMotionButton; |
325 | - |
326 | -typedef enum { |
327 | mir_motion_tool_type_unknown = 0, |
328 | mir_motion_tool_type_finger = 1, |
329 | mir_motion_tool_type_stylus = 2, |
330 | @@ -125,7 +117,7 @@ |
331 | int action; |
332 | MirInputEventModifiers modifiers; |
333 | |
334 | - MirMotionButton button_state; |
335 | + MirPointerButtons buttons; |
336 | std::chrono::nanoseconds event_time; |
337 | |
338 | size_t pointer_count; |
339 | |
340 | === modified file 'src/include/common/mir/input/android/event_conversion_helpers.h' |
341 | --- src/include/common/mir/input/android/event_conversion_helpers.h 2015-05-08 20:44:56 +0000 |
342 | +++ src/include/common/mir/input/android/event_conversion_helpers.h 2015-05-14 18:12:40 +0000 |
343 | @@ -31,13 +31,15 @@ |
344 | int32_t android_modifiers_from_mir(MirInputEventModifiers modifiers); |
345 | |
346 | MirKeyboardAction mir_keyboard_action_from_android(int32_t android_action, int32_t repeat_count); |
347 | - |
348 | // Mir differentiates between mir_keyboard_action_down |
349 | // and mir_keyboard_action_repeat whereas android encodes |
350 | // keyrepeats as AKEY_EVENT_ACTION_DOWN and a repeatCount of > 0 |
351 | // Thus when converting from MirKeyboardAction to an android |
352 | // action we must also fetch a repeat count for the android event. |
353 | int32_t android_keyboard_action_from_mir(int32_t& repeat_count_out, MirKeyboardAction action); |
354 | + |
355 | +MirPointerButtons mir_pointer_buttons_from_android(int32_t android_state); |
356 | +int32_t android_pointer_buttons_from_mir(MirPointerButtons buttons); |
357 | } |
358 | } |
359 | } |
360 | |
361 | === modified file 'src/server/input/android/android_input_dispatcher.cpp' |
362 | --- src/server/input/android/android_input_dispatcher.cpp 2015-05-08 20:54:52 +0000 |
363 | +++ src/server/input/android/android_input_dispatcher.cpp 2015-05-14 18:12:40 +0000 |
364 | @@ -102,7 +102,7 @@ |
365 | event.motion.action, |
366 | 0, /* flags */ |
367 | mia::android_modifiers_from_mir(event.motion.modifiers), |
368 | - event.motion.button_state, |
369 | + mia::android_pointer_buttons_from_mir(event.motion.buttons), |
370 | 0, /* edge_flags */ |
371 | event.motion.pointer_count, |
372 | pointer_properties.data(), |
373 | |
374 | === modified file 'src/server/input/android/input_sender.cpp' |
375 | --- src/server/input/android/input_sender.cpp 2015-05-08 20:54:52 +0000 |
376 | +++ src/server/input/android/input_sender.cpp 2015-05-14 18:12:40 +0000 |
377 | @@ -288,7 +288,7 @@ |
378 | 0, /* flags */ |
379 | 0, /* edge flags */ |
380 | mia::android_modifiers_from_mir(event.modifiers), |
381 | - static_cast<int32_t>(event.button_state), |
382 | + mia::android_pointer_buttons_from_mir(event.buttons), |
383 | 0.0f, // event.x_offset, |
384 | 0.0f, // event.y_offset, |
385 | 0, 0, /* unused x/y precision */ |
386 | |
387 | === modified file 'src/server/input/android/input_translator.cpp' |
388 | --- src/server/input/android/input_translator.cpp 2015-05-07 19:43:49 +0000 |
389 | +++ src/server/input/android/input_translator.cpp 2015-05-14 18:12:40 +0000 |
390 | @@ -147,7 +147,7 @@ |
391 | mir_event.motion.source_id = args->source; |
392 | mir_event.motion.action = args->action; |
393 | mir_event.motion.modifiers = mia::mir_modifiers_from_android(args->metaState); |
394 | - mir_event.motion.button_state = static_cast<MirMotionButton>(args->buttonState); |
395 | + mir_event.motion.buttons = mia::mir_pointer_buttons_from_android(args->buttonState); |
396 | mir_event.motion.event_time = args->eventTime; |
397 | mir_event.motion.pointer_count = args->pointerCount; |
398 | for(unsigned int i = 0; i < args->pointerCount; i++) |
399 | |
400 | === modified file 'src/server/input/default_configuration.cpp' |
401 | --- src/server/input/default_configuration.cpp 2015-05-04 10:45:05 +0000 |
402 | +++ src/server/input/default_configuration.cpp 2015-05-14 18:12:40 +0000 |
403 | @@ -426,6 +426,7 @@ |
404 | the_input_reading_multiplexer(), |
405 | the_main_loop(), |
406 | the_touch_visualizer(), |
407 | + the_cursor_listener(), |
408 | the_input_region()); |
409 | }); |
410 | } |
411 | @@ -439,6 +440,7 @@ |
412 | the_input_reading_multiplexer(), |
413 | the_main_loop(), |
414 | the_touch_visualizer(), |
415 | + the_cursor_listener(), |
416 | the_input_region()); |
417 | }); |
418 | } |
419 | |
420 | === modified file 'src/server/input/default_input_device_hub.cpp' |
421 | --- src/server/input/default_input_device_hub.cpp 2015-04-14 11:08:21 +0000 |
422 | +++ src/server/input/default_input_device_hub.cpp 2015-05-14 18:12:40 +0000 |
423 | @@ -23,6 +23,7 @@ |
424 | #include "mir/input/input_dispatcher.h" |
425 | #include "mir/input/input_device.h" |
426 | #include "mir/input/input_device_observer.h" |
427 | +#include "mir/input/cursor_listener.h" |
428 | #include "mir/input/input_region.h" |
429 | #include "mir/events/event_private.h" |
430 | #include "mir/dispatch/multiplexing_dispatchable.h" |
431 | @@ -42,9 +43,10 @@ |
432 | std::shared_ptr<dispatch::MultiplexingDispatchable> const& input_multiplexer, |
433 | std::shared_ptr<mir::ServerActionQueue> const& observer_queue, |
434 | std::shared_ptr<TouchVisualizer> const& touch_visualizer, |
435 | + std::shared_ptr<CursorListener> const& cursor_listener, |
436 | std::shared_ptr<InputRegion> const& input_region) |
437 | : input_dispatcher(input_dispatcher), input_dispatchable{input_multiplexer}, observer_queue(observer_queue), |
438 | - touch_visualizer(touch_visualizer), input_region(input_region) |
439 | + touch_visualizer(touch_visualizer), cursor_listener(cursor_listener), input_region(input_region) |
440 | { |
441 | } |
442 | |
443 | @@ -163,9 +165,22 @@ |
444 | BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid input event receivd from device")); |
445 | |
446 | update_spots(mir_event_get_input_event(&event)); |
447 | + notify_cursor_listener(mir_event_get_input_event(&event)); |
448 | dispatcher->dispatch(event); |
449 | } |
450 | |
451 | +void mi::DefaultInputDeviceHub::RegisteredDevice::notify_cursor_listener(MirInputEvent const* event) |
452 | +{ |
453 | + if (mir_input_event_get_type(event) != mir_input_event_type_pointer) |
454 | + return; |
455 | + |
456 | + auto pointer_ev = mir_input_event_get_pointer_event(event); |
457 | + hub->cursor_listener->cursor_moved_to( |
458 | + mir_pointer_event_axis_value(pointer_ev, mir_pointer_axis_x), |
459 | + mir_pointer_event_axis_value(pointer_ev, mir_pointer_axis_y) |
460 | + ); |
461 | +} |
462 | + |
463 | void mi::DefaultInputDeviceHub::RegisteredDevice::update_spots(MirInputEvent const* event) |
464 | { |
465 | if (mir_input_event_get_type(event) != mir_input_event_type_touch) |
466 | |
467 | === modified file 'src/server/input/default_input_device_hub.h' |
468 | --- src/server/input/default_input_device_hub.h 2015-04-14 11:08:21 +0000 |
469 | +++ src/server/input/default_input_device_hub.h 2015-05-14 18:12:40 +0000 |
470 | @@ -46,6 +46,7 @@ |
471 | class InputDeviceObserver; |
472 | class TouchVisualizer; |
473 | class InputRegion; |
474 | +class CursorListener; |
475 | |
476 | class DefaultInputDeviceHub : public InputDeviceRegistry, public InputDeviceHub |
477 | { |
478 | @@ -54,6 +55,7 @@ |
479 | std::shared_ptr<dispatch::MultiplexingDispatchable> const& input_multiplexer, |
480 | std::shared_ptr<ServerActionQueue> const& observer_queue, |
481 | std::shared_ptr<TouchVisualizer> const& touch_visualizer, |
482 | + std::shared_ptr<CursorListener> const& cursor_listener, |
483 | std::shared_ptr<InputRegion> const& input_region); |
484 | |
485 | // InputDeviceRegistry - calls from mi::Platform |
486 | @@ -72,6 +74,7 @@ |
487 | std::shared_ptr<dispatch::MultiplexingDispatchable> const input_dispatchable; |
488 | std::shared_ptr<ServerActionQueue> const observer_queue; |
489 | std::shared_ptr<TouchVisualizer> const touch_visualizer; |
490 | + std::shared_ptr<CursorListener> const cursor_listener; |
491 | std::shared_ptr<InputRegion> const input_region; |
492 | |
493 | struct RegisteredDevice : public InputSink |
494 | @@ -89,6 +92,7 @@ |
495 | std::vector<TouchVisualizer::Spot> const& spots() const; |
496 | private: |
497 | void update_spots(MirInputEvent const* event); |
498 | + void notify_cursor_listener(MirInputEvent const* event); |
499 | static int32_t create_new_device_id(); |
500 | int32_t device_id; |
501 | std::shared_ptr<InputDevice> const device; |
502 | |
503 | === modified file 'tests/acceptance-tests/test_client_input.cpp' |
504 | --- tests/acceptance-tests/test_client_input.cpp 2015-05-04 17:33:07 +0000 |
505 | +++ tests/acceptance-tests/test_client_input.cpp 2015-05-14 18:12:40 +0000 |
506 | @@ -16,20 +16,22 @@ |
507 | * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
508 | */ |
509 | |
510 | -#define MIR_INCLUDE_DEPRECATED_EVENT_HEADER |
511 | - |
512 | #include "mir/input/input_device_info.h" |
513 | #include "mir/input/event_filter.h" |
514 | #include "mir/input/composite_event_filter.h" |
515 | |
516 | -#include "mir_test_framework/connected_client_with_a_surface.h" |
517 | +#include "mir_test_framework/headless_in_process_server.h" |
518 | #include "mir_test_framework/fake_input_device.h" |
519 | +#include "mir_test_framework/placement_applying_shell.h" |
520 | #include "mir_test_framework/stub_server_platform_factory.h" |
521 | #include "mir_test/wait_condition.h" |
522 | #include "mir_test/spin_wait.h" |
523 | #include "mir_test/event_matchers.h" |
524 | #include "mir_test/event_factory.h" |
525 | |
526 | +#include "mir_toolkit/mir_client_library.h" |
527 | +#include "mir/events/event_builders.h" |
528 | + |
529 | #include <gtest/gtest.h> |
530 | #include <gmock/gmock.h> |
531 | |
532 | @@ -41,17 +43,14 @@ |
533 | |
534 | namespace mi = mir::input; |
535 | namespace mt = mir::test; |
536 | +namespace ms = mir::scene; |
537 | namespace mis = mir::input::synthesis; |
538 | namespace mtf = mir_test_framework; |
539 | +namespace geom = mir::geometry; |
540 | |
541 | namespace |
542 | { |
543 | |
544 | -struct MockInputHandler |
545 | -{ |
546 | - MOCK_METHOD1(handle_input, void(MirEvent const*)); |
547 | -}; |
548 | - |
549 | struct MockEventFilter : public mi::EventFilter |
550 | { |
551 | // Work around GMock wanting to know how to construct MirEvent |
552 | @@ -63,71 +62,127 @@ |
553 | } |
554 | }; |
555 | |
556 | -struct TestClientInputNew : mtf::ConnectedClientWithASurface |
557 | +const int surface_width = 100; |
558 | +const int surface_height = 100; |
559 | + |
560 | +struct Client |
561 | { |
562 | - void SetUp() override |
563 | + MirSurface* surface{nullptr}; |
564 | + |
565 | + MOCK_METHOD1(handle_input, void(MirEvent const*)); |
566 | + MOCK_METHOD1(handle_keymap, void(MirEvent const*)); |
567 | + |
568 | + Client(std::string const& con, std::string const& name) |
569 | { |
570 | - ConnectedClientWithASurface::SetUp(); |
571 | - |
572 | - mir_surface_set_event_handler(surface, handle_input, this); |
573 | + connection = mir_connect_sync(con.c_str(), name.c_str()); |
574 | + |
575 | + if (!mir_connection_is_valid(connection)) |
576 | + { |
577 | + BOOST_THROW_EXCEPTION( |
578 | + std::runtime_error{std::string{"Failed to connect to test server: "} + |
579 | + mir_connection_get_error_message(connection)}); |
580 | + } |
581 | + auto spec = mir_connection_create_spec_for_normal_surface(connection, surface_width, |
582 | + surface_height, mir_pixel_format_abgr_8888); |
583 | + mir_surface_spec_set_name(spec, name.c_str()); |
584 | + surface = mir_surface_create_sync(spec); |
585 | + mir_surface_spec_release(spec); |
586 | + if (!mir_surface_is_valid(surface)) |
587 | + BOOST_THROW_EXCEPTION(std::runtime_error{std::string{"Failed creating a surface: "}+ |
588 | + mir_surface_get_error_message(surface)}); |
589 | + |
590 | + mir_surface_set_event_handler(surface, handle_event, this); |
591 | mir_buffer_stream_swap_buffers_sync( |
592 | mir_surface_get_buffer_stream(surface)); |
593 | |
594 | - wait_for_surface_to_become_focused_and_exposed(); |
595 | - ready_to_accept_events.wake_up_everyone(); |
596 | + ready_to_accept_events.wait_for_at_most_seconds(4); |
597 | + if (!ready_to_accept_events.woken()) |
598 | + BOOST_THROW_EXCEPTION(std::runtime_error("Timeout waiting for surface to become focused and exposed")); |
599 | } |
600 | |
601 | - static void handle_input(MirSurface*, MirEvent const* ev, void* context) |
602 | + static void handle_event(MirSurface*, MirEvent const* ev, void* context) |
603 | { |
604 | - auto const client = static_cast<TestClientInputNew*>(context); |
605 | + auto const client = static_cast<Client*>(context); |
606 | auto type = mir_event_get_type(ev); |
607 | + if (type == mir_event_type_surface) |
608 | + { |
609 | + auto surface_event = mir_event_get_surface_event(ev); |
610 | + |
611 | + if (mir_surface_attrib_focus == mir_surface_event_get_attribute(surface_event) && |
612 | + 1 == mir_surface_event_get_attribute_value(surface_event)) |
613 | + client->ready_to_accept_events.wake_up_everyone(); |
614 | + } |
615 | if (type == mir_event_type_input) |
616 | - client->handler.handle_input(ev); |
617 | - } |
618 | - |
619 | - void wait_for_surface_to_become_focused_and_exposed() |
620 | - { |
621 | - bool success = mt::spin_wait_for_condition_or_timeout( |
622 | - [&] |
623 | + client->handle_input(ev); |
624 | + if (type == mir_event_type_keymap) |
625 | + client->handle_keymap(ev); |
626 | + } |
627 | + ~Client() |
628 | + { |
629 | + mir_surface_release_sync(surface); |
630 | + mir_connection_release(connection); |
631 | + } |
632 | + MirConnection * connection; |
633 | + mir::test::WaitCondition ready_to_accept_events; |
634 | + mir::test::WaitCondition all_events_received; |
635 | +}; |
636 | + |
637 | +struct TestClientInput : mtf::HeadlessInProcessServer |
638 | +{ |
639 | + void SetUp() override |
640 | + { |
641 | + initial_display_layout({screen_geometry}); |
642 | + |
643 | + server.wrap_shell( |
644 | + [this](std::shared_ptr<mir::shell::Shell> const& wrapped) |
645 | { |
646 | - return mir_surface_get_visibility(surface) == mir_surface_visibility_exposed && |
647 | - mir_surface_get_focus(surface) == mir_surface_focused; |
648 | - }, |
649 | - std::chrono::seconds{5}); |
650 | - |
651 | - if (!success) |
652 | - throw std::runtime_error("Timeout waiting for surface to become focused and exposed"); |
653 | + return std::make_shared<mtf::PlacementApplyingShell>( |
654 | + wrapped, |
655 | + input_regions, positions, depths); |
656 | + }); |
657 | + |
658 | + HeadlessInProcessServer::SetUp(); |
659 | + |
660 | + depths[first] = ms::DepthId{0}; |
661 | + positions[first] = geom::Rectangle{{0,0}, {surface_width, surface_height}}; |
662 | } |
663 | |
664 | std::unique_ptr<mtf::FakeInputDevice> fake_keyboard{ |
665 | mtf::add_fake_input_device(mi::InputDeviceInfo{ 0, "keyboard", "keyboard-uid" , mi::DeviceCapability::keyboard}) |
666 | }; |
667 | - ::testing::NiceMock<MockInputHandler> handler; |
668 | - mir::test::WaitCondition all_events_received; |
669 | - mir::test::WaitCondition ready_to_accept_events; |
670 | + std::unique_ptr<mtf::FakeInputDevice> fake_mouse{ |
671 | + mtf::add_fake_input_device(mi::InputDeviceInfo{ 0, "mouse", "mouse-uid" , mi::DeviceCapability::pointer}) |
672 | + }; |
673 | + std::unique_ptr<mtf::FakeInputDevice> fake_touch_screen{mtf::add_fake_input_device(mi::InputDeviceInfo{ |
674 | + 0, "touch screen", "touch-screen-uid", mi::DeviceCapability::touchscreen | mi::DeviceCapability::multitouch})}; |
675 | |
676 | + std::string first{"first"}; |
677 | + std::string second{"second"}; |
678 | + mtf::ClientInputRegions input_regions; |
679 | + mtf::ClientPositions positions; |
680 | + mtf::ClientDepths depths; |
681 | + geom::Rectangle screen_geometry{{0,0}, {1000,800}}; |
682 | std::shared_ptr<MockEventFilter> mock_event_filter = std::make_shared<MockEventFilter>(); |
683 | }; |
684 | |
685 | } |
686 | |
687 | +using namespace ::testing; |
688 | |
689 | -TEST_F(TestClientInputNew, clients_receive_keys) |
690 | +TEST_F(TestClientInput, clients_receive_keys) |
691 | { |
692 | - using namespace testing; |
693 | + Client first_client(new_connection(), first); |
694 | |
695 | InSequence seq; |
696 | - EXPECT_CALL(handler, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_Shift_R)))); |
697 | - EXPECT_CALL(handler, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_M)))); |
698 | - EXPECT_CALL(handler, handle_input(AllOf(mt::KeyUpEvent(), mt::KeyOfSymbol(XKB_KEY_M)))); |
699 | - EXPECT_CALL(handler, handle_input(AllOf(mt::KeyUpEvent(), mt::KeyOfSymbol(XKB_KEY_Shift_R)))); |
700 | - EXPECT_CALL(handler, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_i)))); |
701 | - EXPECT_CALL(handler, handle_input(AllOf(mt::KeyUpEvent(), mt::KeyOfSymbol(XKB_KEY_i)))); |
702 | - EXPECT_CALL(handler, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_r)))); |
703 | - EXPECT_CALL(handler, handle_input(AllOf(mt::KeyUpEvent(), mt::KeyOfSymbol(XKB_KEY_r)))).WillOnce( |
704 | - mt::WakeUp(&all_events_received)); |
705 | - |
706 | - ready_to_accept_events.wait_for_at_most_seconds(5); |
707 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_Shift_R)))); |
708 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_M)))); |
709 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyUpEvent(), mt::KeyOfSymbol(XKB_KEY_M)))); |
710 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyUpEvent(), mt::KeyOfSymbol(XKB_KEY_Shift_R)))); |
711 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_i)))); |
712 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyUpEvent(), mt::KeyOfSymbol(XKB_KEY_i)))); |
713 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_r)))); |
714 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyUpEvent(), mt::KeyOfSymbol(XKB_KEY_r)))).WillOnce( |
715 | + mt::WakeUp(&first_client.all_events_received)); |
716 | |
717 | fake_keyboard->emit_event(mis::a_key_down_event().of_scancode(KEY_RIGHTSHIFT)); |
718 | fake_keyboard->emit_event(mis::a_key_down_event().of_scancode(KEY_M)); |
719 | @@ -138,38 +193,424 @@ |
720 | fake_keyboard->emit_event(mis::a_key_down_event().of_scancode(KEY_R)); |
721 | fake_keyboard->emit_event(mis::a_key_up_event().of_scancode(KEY_R)); |
722 | |
723 | - all_events_received.wait_for_at_most_seconds(10); |
724 | -} |
725 | - |
726 | -namespace |
727 | -{ |
728 | -struct TestClientInputNewEventFilter : public TestClientInputNew |
729 | -{ |
730 | - void SetUp() override |
731 | - { |
732 | - TestClientInputNew::SetUp(); |
733 | - server.the_composite_event_filter()->append(mock_event_filter); |
734 | - } |
735 | + first_client.all_events_received.wait_for_at_most_seconds(10); |
736 | +} |
737 | + |
738 | +TEST_F(TestClientInput, clients_receive_us_english_mapped_keys) |
739 | +{ |
740 | + Client first_client(new_connection(), first); |
741 | + |
742 | + InSequence seq; |
743 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_Shift_L)))); |
744 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_dollar)))) |
745 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
746 | + |
747 | + fake_keyboard->emit_event(mis::a_key_down_event().of_scancode(KEY_LEFTSHIFT)); |
748 | + fake_keyboard->emit_event(mis::a_key_down_event().of_scancode(KEY_4)); |
749 | + first_client.all_events_received.wait_for_at_most_seconds(10); |
750 | +} |
751 | + |
752 | +TEST_F(TestClientInput, clients_receive_pointer_inside_window_and_crossing_events) |
753 | +{ |
754 | + positions[first] = geom::Rectangle{{0,0}, {surface_width, surface_height}}; |
755 | + Client first_client(new_connection(), first); |
756 | + |
757 | + // We should see the cursor enter |
758 | + InSequence seq; |
759 | + EXPECT_CALL(first_client, handle_input(mt::PointerEnterEvent())); |
760 | + EXPECT_CALL(first_client, handle_input(mt::PointerEventWithPosition(surface_width - 1, surface_height - 1))); |
761 | + EXPECT_CALL(first_client, handle_input(mt::PointerLeaveEvent())) |
762 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
763 | + // But we should not receive an event for the second movement outside of our surface! |
764 | + |
765 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(surface_width - 1, surface_height - 1)); |
766 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(2, 2)); |
767 | + |
768 | + first_client.all_events_received.wait_for_at_most_seconds(120); |
769 | +} |
770 | + |
771 | +TEST_F(TestClientInput, clients_receive_button_events_inside_window) |
772 | +{ |
773 | + Client first_client(new_connection(), first); |
774 | + // The cursor starts at (0, 0). |
775 | + EXPECT_CALL(first_client, handle_input(mt::ButtonDownEvent(0, 0))) |
776 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
777 | + |
778 | + fake_mouse->emit_event(mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down)); |
779 | + |
780 | + first_client.all_events_received.wait_for_at_most_seconds(10); |
781 | +} |
782 | + |
783 | +TEST_F(TestClientInput, clients_receive_many_button_events_inside_window) |
784 | +{ |
785 | + Client first_client(new_connection(), first); |
786 | + // The cursor starts at (0, 0). |
787 | + |
788 | + InSequence seq; |
789 | + auto expect_buttons = [&](MirPointerButtons b) { |
790 | + EXPECT_CALL(first_client, handle_input(mt::ButtonsDown(0, 0, b))); |
791 | + }; |
792 | + |
793 | + MirPointerButtons buttons = mir_pointer_button_primary; |
794 | + expect_buttons(buttons); |
795 | + expect_buttons(buttons |= mir_pointer_button_secondary); |
796 | + expect_buttons(buttons |= mir_pointer_button_tertiary); |
797 | + expect_buttons(buttons |= mir_pointer_button_forward); |
798 | + expect_buttons(buttons |= mir_pointer_button_back); |
799 | + expect_buttons(buttons &= ~mir_pointer_button_back); |
800 | + expect_buttons(buttons &= ~mir_pointer_button_forward); |
801 | + expect_buttons(buttons &= ~mir_pointer_button_tertiary); |
802 | + expect_buttons(buttons &= ~mir_pointer_button_secondary); |
803 | + EXPECT_CALL(first_client, handle_input(mt::ButtonsDown(0, 0, 0))).WillOnce( |
804 | + mt::WakeUp(&first_client.all_events_received)); |
805 | + |
806 | + auto press_button = [&](int button) { |
807 | + fake_mouse->emit_event(mis::a_button_down_event().of_button(button).with_action(mis::EventAction::Down)); |
808 | + }; |
809 | + auto release_button = [&](int button) { |
810 | + fake_mouse->emit_event(mis::a_button_up_event().of_button(button).with_action(mis::EventAction::Up)); |
811 | + }; |
812 | + press_button(BTN_LEFT); |
813 | + press_button(BTN_RIGHT); |
814 | + press_button(BTN_MIDDLE); |
815 | + press_button(BTN_FORWARD); |
816 | + press_button(BTN_BACK); |
817 | + release_button(BTN_BACK); |
818 | + release_button(BTN_FORWARD); |
819 | + release_button(BTN_MIDDLE); |
820 | + release_button(BTN_RIGHT); |
821 | + release_button(BTN_LEFT); |
822 | + |
823 | + first_client.all_events_received.wait_for_at_most_seconds(10); |
824 | +} |
825 | + |
826 | +TEST_F(TestClientInput, multiple_clients_receive_pointer_inside_windows) |
827 | +{ |
828 | + int const screen_width = screen_geometry.size.width.as_int(); |
829 | + int const screen_height = screen_geometry.size.height.as_int(); |
830 | + int const client_height = screen_height / 2; |
831 | + int const client_width = screen_width / 2; |
832 | + |
833 | + positions[first] = {{0, 0}, {client_width, client_height}}; |
834 | + positions[second] = {{client_width, client_height}, {client_width, client_height}}; |
835 | + |
836 | + Client first_client(new_connection(), first); |
837 | + Client second_client(new_connection(), second); |
838 | + |
839 | + { |
840 | + InSequence seq; |
841 | + EXPECT_CALL(first_client, handle_input(mt::PointerEnterEvent())); |
842 | + EXPECT_CALL(first_client, handle_input(mt::PointerEventWithPosition(client_width - 1, client_height - 1))); |
843 | + EXPECT_CALL(first_client, handle_input(mt::PointerLeaveEvent())) |
844 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
845 | + } |
846 | + |
847 | + { |
848 | + InSequence seq; |
849 | + EXPECT_CALL(second_client, handle_input(mt::PointerEnterEvent())); |
850 | + EXPECT_CALL(second_client, handle_input(mt::PointerEventWithPosition(client_width - 1, client_height - 1))) |
851 | + .WillOnce(mt::WakeUp(&second_client.all_events_received)); |
852 | + } |
853 | + |
854 | + // In the bounds of the first surface |
855 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(client_width - 1, client_height - 1)); |
856 | + // In the bounds of the second surface |
857 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(client_width, client_height)); |
858 | + |
859 | + first_client.all_events_received.wait_for_at_most_seconds(2); |
860 | + second_client.all_events_received.wait_for_at_most_seconds(2); |
861 | +} |
862 | + |
863 | +TEST_F(TestClientInput, clients_do_not_receive_pointer_outside_input_region) |
864 | +{ |
865 | + int const client_height = surface_height; |
866 | + int const client_width = surface_width; |
867 | + |
868 | + input_regions[first] = {{{0, 0}, {client_width - 80, client_height}}, |
869 | + {{client_width - 20, 0}, {client_width - 80, client_height}}}; |
870 | + |
871 | + Client first_client(new_connection(), first); |
872 | + |
873 | + EXPECT_CALL(first_client, handle_input(mt::PointerEnterEvent())).Times(AnyNumber()); |
874 | + EXPECT_CALL(first_client, handle_input(mt::PointerLeaveEvent())).Times(AnyNumber()); |
875 | + EXPECT_CALL(first_client, handle_input(mt::PointerMovementEvent())).Times(AnyNumber()); |
876 | + |
877 | + { |
878 | + // We should see two of the three button pairs. |
879 | + InSequence seq; |
880 | + EXPECT_CALL(first_client, handle_input(mt::ButtonDownEvent(1, 1))); |
881 | + EXPECT_CALL(first_client, handle_input(mt::ButtonUpEvent(1, 1))); |
882 | + EXPECT_CALL(first_client, handle_input(mt::ButtonDownEvent(99, 99))); |
883 | + EXPECT_CALL(first_client, handle_input(mt::ButtonUpEvent(99, 99))) |
884 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
885 | + } |
886 | + |
887 | + // First we will move the cursor in to the input region on the left side of |
888 | + // the window. We should see a click here. |
889 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(1, 1)); |
890 | + fake_mouse->emit_event(mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down)); |
891 | + fake_mouse->emit_event(mis::a_button_up_event().of_button(BTN_LEFT)); |
892 | + |
893 | + // Now in to the dead zone in the center of the window. We should not see |
894 | + // a click here. |
895 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(49, 49)); |
896 | + fake_mouse->emit_event(mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down)); |
897 | + fake_mouse->emit_event(mis::a_button_up_event().of_button(BTN_LEFT)); |
898 | + |
899 | + // Now in to the right edge of the window, in the right input region. |
900 | + // Again we should see a click. |
901 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(49, 49)); |
902 | + fake_mouse->emit_event(mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down)); |
903 | + fake_mouse->emit_event(mis::a_button_up_event().of_button(BTN_LEFT)); |
904 | + |
905 | + first_client.all_events_received.wait_for_at_most_seconds(5); |
906 | +} |
907 | + |
908 | +TEST_F(TestClientInput, scene_obscure_motion_events_by_stacking) |
909 | +{ |
910 | + auto smaller_geometry = screen_geometry; |
911 | + smaller_geometry.size.width = |
912 | + geom::Width{screen_geometry.size.width.as_uint32_t() / 2}; |
913 | + |
914 | + positions[first] = screen_geometry; |
915 | + positions[second] = smaller_geometry; |
916 | + depths[second] = ms::DepthId{1}; |
917 | + |
918 | + Client first_client(new_connection(), first); |
919 | + Client second_client(new_connection(), second); |
920 | + |
921 | + EXPECT_CALL(first_client, handle_input(mt::PointerEnterEvent())).Times(AnyNumber()); |
922 | + EXPECT_CALL(first_client, handle_input(mt::PointerLeaveEvent())).Times(AnyNumber()); |
923 | + EXPECT_CALL(first_client, handle_input(mt::PointerMovementEvent())).Times(AnyNumber()); |
924 | + { |
925 | + // We should only see one button event sequence. |
926 | + InSequence seq; |
927 | + EXPECT_CALL(first_client, handle_input(mt::ButtonDownEvent(501, 1))); |
928 | + EXPECT_CALL(first_client, handle_input(mt::ButtonUpEvent(501, 1))) |
929 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
930 | + } |
931 | + |
932 | + EXPECT_CALL(second_client, handle_input(mt::PointerEnterEvent())).Times(AnyNumber()); |
933 | + EXPECT_CALL(second_client, handle_input(mt::PointerLeaveEvent())).Times(AnyNumber()); |
934 | + EXPECT_CALL(second_client, handle_input(mt::PointerMovementEvent())).Times(AnyNumber()); |
935 | + { |
936 | + // Likewise we should only see one button sequence. |
937 | + InSequence seq; |
938 | + EXPECT_CALL(second_client, handle_input(mt::ButtonDownEvent(1, 1))); |
939 | + EXPECT_CALL(second_client, handle_input(mt::ButtonUpEvent(1, 1))) |
940 | + .WillOnce(mt::WakeUp(&second_client.all_events_received)); |
941 | + } |
942 | + |
943 | + // First we will move the cursor in to the region where client 2 obscures client 1 |
944 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(1, 1)); |
945 | + fake_mouse->emit_event( |
946 | + mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down)); |
947 | + fake_mouse->emit_event(mis::a_button_up_event().of_button(BTN_LEFT)); |
948 | + // Now we move to the unobscured region of client 1 |
949 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(500, 0)); |
950 | + fake_mouse->emit_event(mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down)); |
951 | + fake_mouse->emit_event(mis::a_button_up_event().of_button(BTN_LEFT)); |
952 | + |
953 | + first_client.all_events_received.wait_for_at_most_seconds(5); |
954 | + second_client.all_events_received.wait_for_at_most_seconds(5); |
955 | +} |
956 | + |
957 | +TEST_F(TestClientInput, hidden_clients_do_not_receive_pointer_events) |
958 | +{ |
959 | + depths[second] = ms::DepthId{1}; |
960 | + positions[second] = {{0,0}, {surface_width, surface_height}}; |
961 | + |
962 | + Client first_client(new_connection(), first); |
963 | + Client second_client(new_connection(), second); |
964 | + |
965 | + EXPECT_CALL(second_client, handle_input(mt::PointerEnterEvent())).Times(AnyNumber()); |
966 | + EXPECT_CALL(second_client, handle_input(mt::PointerLeaveEvent())).Times(AnyNumber()); |
967 | + EXPECT_CALL(second_client, handle_input(mt::PointerEventWithPosition(1, 1))) |
968 | + .WillOnce(mt::WakeUp(&second_client.all_events_received)); |
969 | + |
970 | + EXPECT_CALL(first_client, handle_input(mt::PointerEnterEvent())).Times(AnyNumber()); |
971 | + EXPECT_CALL(first_client, handle_input(mt::PointerLeaveEvent())).Times(AnyNumber()); |
972 | + EXPECT_CALL(first_client, handle_input(mt::PointerEventWithPosition(2, 2))) |
973 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
974 | + |
975 | + // We send one event and then hide the surface on top before sending the next. |
976 | + // So we expect each of the two surfaces to receive one event |
977 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(1,1)); |
978 | + |
979 | + second_client.all_events_received.wait_for_at_most_seconds(2); |
980 | + |
981 | + server.the_shell()->focused_session()->hide(); |
982 | + |
983 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(1,1)); |
984 | + first_client.all_events_received.wait_for_at_most_seconds(2); |
985 | +} |
986 | + |
987 | +TEST_F(TestClientInput, clients_receive_pointer_within_coordinate_system_of_window) |
988 | +{ |
989 | + int const screen_width = screen_geometry.size.width.as_int(); |
990 | + int const screen_height = screen_geometry.size.height.as_int(); |
991 | + int const client_height = screen_height / 2; |
992 | + int const client_width = screen_width / 2; |
993 | + |
994 | + positions[first] = {{screen_width / 2, screen_height / 2}, {client_width, client_height}}; |
995 | + |
996 | + Client first_client(new_connection(), first); |
997 | + |
998 | + InSequence seq; |
999 | + EXPECT_CALL(first_client, handle_input(mt::PointerEnterEvent())); |
1000 | + EXPECT_CALL(first_client, handle_input(mt::PointerEventWithPosition(80, 170))) |
1001 | + .Times(AnyNumber()) |
1002 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
1003 | + |
1004 | + server.the_shell()->focused_surface()->move_to(geom::Point{screen_width / 2 - 40, screen_height / 2 - 80}); |
1005 | + |
1006 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(screen_width / 2 + 40, screen_height / 2 + 90)); |
1007 | + |
1008 | + first_client.all_events_received.wait_for_at_most_seconds(2); |
1009 | +} |
1010 | + |
1011 | +// TODO: Consider tests for more input devices with custom mapping (i.e. joysticks...) |
1012 | +TEST_F(TestClientInput, usb_direct_input_devices_work) |
1013 | +{ |
1014 | + float const minimum_touch = mtf::FakeInputDevice::minimum_touch_axis_value; |
1015 | + float const maximum_touch = mtf::FakeInputDevice::maximum_touch_axis_value; |
1016 | + auto const display_width = screen_geometry.size.width.as_float(); |
1017 | + auto const display_height = screen_geometry.size.height.as_float(); |
1018 | + |
1019 | + // We place a click 10% in to the touchscreens space in both axis, |
1020 | + // and a second at 0,0. Thus we expect to see a click at |
1021 | + // .1*screen_width/height and a second at zero zero. |
1022 | + float const abs_touch_x_1 = minimum_touch + (maximum_touch - minimum_touch) * 0.1f; |
1023 | + float const abs_touch_y_1 = minimum_touch + (maximum_touch - minimum_touch) * 0.1f; |
1024 | + float const abs_touch_x_2 = 0; |
1025 | + float const abs_touch_y_2 = 0; |
1026 | + |
1027 | + float const expected_scale_x = display_width / (maximum_touch - minimum_touch + 1.0f); |
1028 | + float const expected_scale_y = display_height / (maximum_touch - minimum_touch + 1.0f); |
1029 | + |
1030 | + float const expected_motion_x_1 = expected_scale_x * abs_touch_x_1; |
1031 | + float const expected_motion_y_1 = expected_scale_y * abs_touch_y_1; |
1032 | + float const expected_motion_x_2 = expected_scale_x * abs_touch_x_2; |
1033 | + float const expected_motion_y_2 = expected_scale_y * abs_touch_y_2; |
1034 | + |
1035 | + positions[first] = screen_geometry; |
1036 | + |
1037 | + Client first_client(new_connection(), first); |
1038 | + |
1039 | + InSequence seq; |
1040 | + EXPECT_CALL(first_client, handle_input( |
1041 | + mt::TouchEvent(expected_motion_x_1, expected_motion_y_1))); |
1042 | + EXPECT_CALL(first_client, handle_input( |
1043 | + mt::TouchEventInDirection(expected_motion_x_1, |
1044 | + expected_motion_y_1, |
1045 | + expected_motion_x_2, |
1046 | + expected_motion_y_2))) |
1047 | + .Times(AnyNumber()) |
1048 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
1049 | + |
1050 | + fake_touch_screen->emit_event(mis::a_touch_event() |
1051 | + .at_position({abs_touch_x_1, abs_touch_y_1})); |
1052 | + // Sleep here to trigger more failures (simulate slow machine) |
1053 | + // TODO why would that cause failures?b |
1054 | + std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
1055 | + fake_touch_screen->emit_event(mis::a_touch_event() |
1056 | + .with_action(mis::TouchParameters::Action::Move) |
1057 | + .at_position({abs_touch_x_2, abs_touch_y_2})); |
1058 | + |
1059 | + first_client.all_events_received.wait_for_at_most_seconds(2); |
1060 | +} |
1061 | + |
1062 | +TEST_F(TestClientInput, send_mir_input_events_through_surface) |
1063 | +{ |
1064 | + Client first_client(new_connection(), first); |
1065 | + |
1066 | + EXPECT_CALL(first_client, handle_input(mt::KeyDownEvent())) |
1067 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
1068 | + |
1069 | + auto key_event = mir::events::make_event(MirInputDeviceId{0}, std::chrono::nanoseconds(0), mir_keyboard_action_down, 0, KEY_M, |
1070 | + mir_input_event_modifier_none); |
1071 | + |
1072 | + server.the_shell()->focused_surface()->consume(*key_event); |
1073 | + |
1074 | + first_client.all_events_received.wait_for_at_most_seconds(2); |
1075 | +} |
1076 | + |
1077 | +TEST_F(TestClientInput, clients_receive_keymap_change_events) |
1078 | +{ |
1079 | + Client first_client(new_connection(), first); |
1080 | + |
1081 | + xkb_rule_names names; |
1082 | + names.rules = "evdev"; |
1083 | + names.model = "pc105"; |
1084 | + names.layout = "dvorak"; |
1085 | + names.variant = ""; |
1086 | + names.options = ""; |
1087 | + |
1088 | + EXPECT_CALL(first_client, handle_keymap(mt::KeymapEventWithRules(names))) |
1089 | + .Times(1) |
1090 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
1091 | + |
1092 | + server.the_shell()->focused_surface()->set_keymap(names); |
1093 | + first_client.all_events_received.wait_for_at_most_seconds(2); |
1094 | +} |
1095 | + |
1096 | +TEST_F(TestClientInput, keymap_changes_change_keycode_received) |
1097 | +{ |
1098 | + Client first_client(new_connection(), first); |
1099 | + |
1100 | + xkb_rule_names names; |
1101 | + names.rules = "evdev"; |
1102 | + names.model = "pc105"; |
1103 | + names.layout = "us"; |
1104 | + names.variant = "dvorak"; |
1105 | + names.options = ""; |
1106 | + |
1107 | + mt::WaitCondition first_event_received, |
1108 | + client_sees_keymap_change; |
1109 | + |
1110 | + InSequence seq; |
1111 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_n)))); |
1112 | + EXPECT_CALL(first_client, handle_input(mt::KeyUpEvent())) |
1113 | + .WillOnce(mt::WakeUp(&first_event_received)); |
1114 | + EXPECT_CALL(first_client, handle_keymap(mt::KeymapEventWithRules(names))) |
1115 | + .WillOnce(mt::WakeUp(&client_sees_keymap_change)); |
1116 | + |
1117 | + EXPECT_CALL(first_client, handle_input(AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_b)))); |
1118 | + EXPECT_CALL(first_client, handle_input(mt::KeyUpEvent())) |
1119 | + .WillOnce(mt::WakeUp(&first_client.all_events_received)); |
1120 | + |
1121 | + fake_keyboard->emit_event(mis::a_key_down_event().of_scancode(KEY_N)); |
1122 | + fake_keyboard->emit_event(mis::a_key_up_event().of_scancode(KEY_N)); |
1123 | + |
1124 | + first_event_received.wait_for_at_most_seconds(60); |
1125 | + |
1126 | + server.the_shell()->focused_surface()->set_keymap(names); |
1127 | + |
1128 | + client_sees_keymap_change.wait_for_at_most_seconds(60); |
1129 | + |
1130 | + fake_keyboard->emit_event(mis::a_key_down_event().of_scancode(KEY_N)); |
1131 | + fake_keyboard->emit_event(mis::a_key_up_event().of_scancode(KEY_N)); |
1132 | + |
1133 | + first_client.all_events_received.wait_for_at_most_seconds(5); |
1134 | +} |
1135 | + |
1136 | +TEST_F(TestClientInput, event_filter_may_consume_events) |
1137 | +{ |
1138 | std::shared_ptr<MockEventFilter> mock_event_filter = std::make_shared<MockEventFilter>(); |
1139 | -}; |
1140 | -} |
1141 | + server.the_composite_event_filter()->append(mock_event_filter); |
1142 | |
1143 | -TEST_F(TestClientInputNewEventFilter, event_filter_may_consume_events) |
1144 | -{ |
1145 | - using namespace ::testing; |
1146 | + Client first_client(new_connection(), first); |
1147 | |
1148 | InSequence seq; |
1149 | EXPECT_CALL(*mock_event_filter, handle(_)).WillOnce(Return(true)); |
1150 | EXPECT_CALL(*mock_event_filter, handle(_)).WillOnce( |
1151 | - DoAll(mt::WakeUp(&all_events_received), Return(true))); |
1152 | + DoAll(mt::WakeUp(&first_client.all_events_received), Return(true))); |
1153 | |
1154 | // Since we handle the events in the filter the client should not receive them. |
1155 | - EXPECT_CALL(handler, handle_input(_)).Times(0); |
1156 | - |
1157 | - ready_to_accept_events.wait_for_at_most_seconds(5); |
1158 | + EXPECT_CALL(first_client, handle_input(_)).Times(0); |
1159 | |
1160 | fake_keyboard->emit_event(mis::a_key_down_event().of_scancode(KEY_M)); |
1161 | fake_keyboard->emit_event(mis::a_key_up_event().of_scancode(KEY_M)); |
1162 | |
1163 | - all_events_received.wait_for_at_most_seconds(10); |
1164 | + first_client.all_events_received.wait_for_at_most_seconds(10); |
1165 | } |
1166 | |
1167 | === modified file 'tests/acceptance-tests/test_surface_modifications.cpp' |
1168 | --- tests/acceptance-tests/test_surface_modifications.cpp 2015-05-05 18:01:08 +0000 |
1169 | +++ tests/acceptance-tests/test_surface_modifications.cpp 2015-05-14 18:12:40 +0000 |
1170 | @@ -93,7 +93,6 @@ |
1171 | void generate_alt_click_at(Point const& click_position) |
1172 | { |
1173 | auto const modifiers = mir_input_event_modifier_alt; |
1174 | - std::vector<MirPointerButton> depressed_buttons{mir_pointer_button_tertiary}; |
1175 | |
1176 | auto const x_axis_value = click_position.x.as_float(); |
1177 | auto const y_axis_value = click_position.y.as_float(); |
1178 | @@ -102,7 +101,7 @@ |
1179 | auto const action = mir_pointer_action_button_down; |
1180 | |
1181 | auto const click_event = mev::make_event(device_id, timestamp, modifiers, |
1182 | - action, depressed_buttons, x_axis_value, y_axis_value, hscroll_value, vscroll_value); |
1183 | + action, mir_pointer_button_tertiary, x_axis_value, y_axis_value, hscroll_value, vscroll_value); |
1184 | |
1185 | server.the_shell()->handle(*click_event); |
1186 | } |
1187 | @@ -110,7 +109,6 @@ |
1188 | void generate_alt_move_to(Point const& drag_position) |
1189 | { |
1190 | auto const modifiers = mir_input_event_modifier_alt; |
1191 | - std::vector<MirPointerButton> depressed_buttons{mir_pointer_button_tertiary}; |
1192 | |
1193 | auto const x_axis_value = drag_position.x.as_float(); |
1194 | auto const y_axis_value = drag_position.y.as_float(); |
1195 | @@ -119,7 +117,7 @@ |
1196 | auto const action = mir_pointer_action_motion; |
1197 | |
1198 | auto const drag_event = mev::make_event(device_id, timestamp, modifiers, |
1199 | - action, depressed_buttons, x_axis_value, y_axis_value, hscroll_value, vscroll_value); |
1200 | + action, mir_pointer_button_tertiary, x_axis_value, y_axis_value, hscroll_value, vscroll_value); |
1201 | |
1202 | server.the_shell()->handle(*drag_event); |
1203 | } |
1204 | |
1205 | === modified file 'tests/acceptance-tests/test_surface_placement.cpp' |
1206 | --- tests/acceptance-tests/test_surface_placement.cpp 2015-05-05 18:01:08 +0000 |
1207 | +++ tests/acceptance-tests/test_surface_placement.cpp 2015-05-14 18:12:40 +0000 |
1208 | @@ -121,7 +121,7 @@ |
1209 | MirInputDeviceId const device_id{7}; |
1210 | |
1211 | auto const modifiers = mir_input_event_modifier_none; |
1212 | - std::vector<MirPointerButton> depressed_buttons{mir_pointer_button_primary}; |
1213 | + auto const depressed_buttons = mir_pointer_button_primary; |
1214 | |
1215 | auto const x_axis_value = click_position.x.as_float(); |
1216 | auto const y_axis_value = click_position.y.as_float(); |
1217 | |
1218 | === modified file 'tests/acceptance-tests/throwback/CMakeLists.txt' |
1219 | --- tests/acceptance-tests/throwback/CMakeLists.txt 2015-04-13 14:53:35 +0000 |
1220 | +++ tests/acceptance-tests/throwback/CMakeLists.txt 2015-05-14 18:12:40 +0000 |
1221 | @@ -9,7 +9,6 @@ |
1222 | |
1223 | clients.cpp |
1224 | test_client_cursor_api.cpp |
1225 | - test_client_input.cpp |
1226 | test_custom_input_targeter.cpp |
1227 | test_focus_selection.cpp |
1228 | test_touchspot_visualization.cpp |
1229 | |
1230 | === removed file 'tests/acceptance-tests/throwback/test_client_input.cpp' |
1231 | --- tests/acceptance-tests/throwback/test_client_input.cpp 2015-05-05 17:11:45 +0000 |
1232 | +++ tests/acceptance-tests/throwback/test_client_input.cpp 1970-01-01 00:00:00 +0000 |
1233 | @@ -1,704 +0,0 @@ |
1234 | -/* |
1235 | - * Copyright © 2013-2015 Canonical Ltd. |
1236 | - * |
1237 | - * This program is free software: you can redistribute it and/or modify |
1238 | - * it under the terms of the GNU General Public License version 3 as |
1239 | - * published by the Free Software Foundation. |
1240 | - * |
1241 | - * This program is distributed in the hope that it will be useful, |
1242 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1243 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1244 | - * GNU General Public License for more details. |
1245 | - * |
1246 | - * You should have received a copy of the GNU General Public License |
1247 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1248 | - * |
1249 | - * Authored by: Robert Carr <robert.carr@canonical.com> |
1250 | - * Andreas Pokorny <andreas.pokorny@canonical.com> |
1251 | - * Alexandros Frantzis <alexandros.frantzis@canonical.com> |
1252 | - */ |
1253 | - |
1254 | -#include "mir/events/event_private.h" |
1255 | -#include "mir/shell/shell_wrapper.h" |
1256 | -#include "mir/scene/surface_creation_parameters.h" |
1257 | -#include "mir/scene/surface.h" |
1258 | -#include "mir/scene/session.h" |
1259 | -#include "src/server/scene/session_container.h" |
1260 | - |
1261 | -#include "mir_test_framework/in_process_server.h" |
1262 | -#include "mir_test_framework/using_stub_client_platform.h" |
1263 | -#include "mir_test_framework/fake_event_hub_server_configuration.h" |
1264 | -#include "mir_test_framework/declarative_placement_strategy.h" |
1265 | -#include "mir_test/wait_condition.h" |
1266 | -#include "mir_test/fake_event_hub.h" |
1267 | -#include "mir_test/event_matchers.h" |
1268 | -#include "mir_test/spin_wait.h" |
1269 | - |
1270 | -#include "mir_toolkit/mir_client_library.h" |
1271 | - |
1272 | -#include <linux/input.h> |
1273 | - |
1274 | -#include <gtest/gtest.h> |
1275 | -#include <gmock/gmock.h> |
1276 | -#include <cstring> |
1277 | - |
1278 | -namespace mf = mir::frontend; |
1279 | -namespace mt = mir::test; |
1280 | -namespace mtf = mir_test_framework; |
1281 | -namespace mis = mir::input::synthesis; |
1282 | -namespace mia = mir::input::android; |
1283 | -namespace msh = mir::shell; |
1284 | -namespace ms = mir::scene; |
1285 | -namespace geom = mir::geometry; |
1286 | - |
1287 | -namespace |
1288 | -{ |
1289 | - |
1290 | -struct MockInputHandler |
1291 | -{ |
1292 | - MOCK_METHOD1(handle_input, void(MirEvent const*)); |
1293 | -}; |
1294 | - |
1295 | -struct InputClient |
1296 | -{ |
1297 | - InputClient(std::string const& connect_string, std::string const& client_name) |
1298 | - : connect_string{connect_string}, client_name{client_name} |
1299 | - { |
1300 | - } |
1301 | - |
1302 | - |
1303 | - ~InputClient() |
1304 | - { |
1305 | - if (client_thread.joinable()) |
1306 | - client_thread.join(); |
1307 | - } |
1308 | - |
1309 | - void start() |
1310 | - { |
1311 | - client_thread = std::thread{[this] { run(); }}; |
1312 | - ready_to_accept_events.wait_for_at_most_seconds(5); |
1313 | - } |
1314 | - |
1315 | - void run() |
1316 | - { |
1317 | - auto const connection = |
1318 | - mir_connect_sync(connect_string.c_str(), client_name.c_str()); |
1319 | - |
1320 | - auto spec = mir_connection_create_spec_for_normal_surface(connection, surface_width, |
1321 | - surface_height, mir_pixel_format_bgr_888); |
1322 | - mir_surface_spec_set_name(spec, client_name.c_str()); |
1323 | - surface = mir_surface_create_sync(spec); |
1324 | - mir_surface_spec_release(spec); |
1325 | - |
1326 | - mir_surface_set_event_handler(surface, handle_input, this); |
1327 | - mir_buffer_stream_swap_buffers_sync( |
1328 | - mir_surface_get_buffer_stream(surface)); |
1329 | - |
1330 | - wait_for_surface_to_become_focused_and_exposed(); |
1331 | - |
1332 | - ready_to_accept_events.wake_up_everyone(); |
1333 | - all_events_received.wait_for_at_most_seconds(10); |
1334 | - |
1335 | - mir_surface_release_sync(surface); |
1336 | - mir_connection_release(connection); |
1337 | - } |
1338 | - |
1339 | - static void handle_input(MirSurface*, MirEvent const* ev, void* context) |
1340 | - { |
1341 | - auto const client = static_cast<InputClient*>(context); |
1342 | - |
1343 | - if (mir_event_get_type(ev) == mir_event_type_surface) |
1344 | - return; |
1345 | - |
1346 | - client->handler.handle_input(ev); |
1347 | - } |
1348 | - |
1349 | - void wait_for_surface_to_become_focused_and_exposed() |
1350 | - { |
1351 | - bool success = mt::spin_wait_for_condition_or_timeout( |
1352 | - [&] |
1353 | - { |
1354 | - return mir_surface_get_visibility(surface) == mir_surface_visibility_exposed && |
1355 | - mir_surface_get_focus(surface) == mir_surface_focused; |
1356 | - }, |
1357 | - std::chrono::seconds{5}); |
1358 | - |
1359 | - if (!success) |
1360 | - throw std::runtime_error("Timeout waiting for surface to become focused and exposed"); |
1361 | - } |
1362 | - |
1363 | - static int const surface_width = 100; |
1364 | - static int const surface_height = 100; |
1365 | - |
1366 | - std::string const connect_string; |
1367 | - std::string const client_name; |
1368 | - |
1369 | - std::thread client_thread; |
1370 | - MockInputHandler handler; |
1371 | - mir::test::WaitCondition all_events_received; |
1372 | - mir::test::WaitCondition ready_to_accept_events; |
1373 | - |
1374 | - MirSurface* surface; |
1375 | -}; |
1376 | - |
1377 | -using ClientInputRegions = std::map<std::string, std::vector<geom::Rectangle>>; |
1378 | - |
1379 | -struct RegionApplyingShell : msh::ShellWrapper |
1380 | -{ |
1381 | - RegionApplyingShell( |
1382 | - std::shared_ptr<msh::Shell> wrapped_coordinator, |
1383 | - ClientInputRegions const& client_input_regions) |
1384 | - : msh::ShellWrapper(wrapped_coordinator), |
1385 | - client_input_regions(client_input_regions) |
1386 | - { |
1387 | - } |
1388 | - |
1389 | - mf::SurfaceId create_surface( |
1390 | - std::shared_ptr<ms::Session> const& session, |
1391 | - ms::SurfaceCreationParameters const& params) override |
1392 | - { |
1393 | - auto const id = wrapped->create_surface(session, params); |
1394 | - |
1395 | - auto const surface = session->surface(id); |
1396 | - |
1397 | - if (client_input_regions.find(params.name) != client_input_regions.end()) |
1398 | - surface->set_input_region(client_input_regions.at(params.name)); |
1399 | - |
1400 | - return id; |
1401 | - } |
1402 | - |
1403 | - ClientInputRegions const& client_input_regions; |
1404 | -}; |
1405 | - |
1406 | -struct TestServerConfiguration : mtf::FakeEventHubServerConfiguration |
1407 | -{ |
1408 | - TestServerConfiguration(geom::Rectangle const& screen_geometry) |
1409 | - : mtf::FakeEventHubServerConfiguration( |
1410 | - std::vector<geom::Rectangle>{screen_geometry}) |
1411 | - { |
1412 | - } |
1413 | - |
1414 | - std::shared_ptr<mir::scene::PlacementStrategy> the_placement_strategy() override |
1415 | - { |
1416 | - return std::make_shared<mtf::DeclarativePlacementStrategy>( |
1417 | - FakeEventHubServerConfiguration::the_placement_strategy(), |
1418 | - client_geometries, client_depths); |
1419 | - } |
1420 | - |
1421 | - std::shared_ptr<msh::Shell> |
1422 | - wrap_shell(std::shared_ptr<msh::Shell> const& wrapped) override |
1423 | - { |
1424 | - return std::make_shared<RegionApplyingShell>( |
1425 | - wrapped, |
1426 | - client_input_regions); |
1427 | - } |
1428 | - |
1429 | - mtf::SurfaceGeometries client_geometries; |
1430 | - mtf::SurfaceDepths client_depths; |
1431 | - ClientInputRegions client_input_regions; |
1432 | -}; |
1433 | - |
1434 | -struct TestClientInput : mtf::InProcessServer |
1435 | -{ |
1436 | - mir::DefaultServerConfiguration& server_config() override |
1437 | - { |
1438 | - return server_configuration_; |
1439 | - } |
1440 | - |
1441 | - TestServerConfiguration& test_server_config() |
1442 | - { |
1443 | - return server_configuration_; |
1444 | - } |
1445 | - |
1446 | - std::shared_ptr<mir::input::android::FakeEventHub> fake_event_hub() |
1447 | - { |
1448 | - return server_configuration_.fake_event_hub; |
1449 | - } |
1450 | - |
1451 | - std::string const test_client_name_1{"client1"}; |
1452 | - std::string const test_client_name_2{"client2"}; |
1453 | - geom::Rectangle const screen_geometry{{0, 0}, {1000, 800}}; |
1454 | - TestServerConfiguration server_configuration_{screen_geometry}; |
1455 | - mtf::UsingStubClientPlatform using_stub_client_platform; |
1456 | -}; |
1457 | - |
1458 | -} |
1459 | - |
1460 | -TEST_F(TestClientInput, clients_receive_key_input) |
1461 | -{ |
1462 | - using namespace testing; |
1463 | - |
1464 | - InputClient client{new_connection(), test_client_name_1}; |
1465 | - |
1466 | - InSequence seq; |
1467 | - EXPECT_CALL(client.handler, handle_input(mt::KeyDownEvent())).Times(1); |
1468 | - EXPECT_CALL(client.handler, handle_input(mt::KeyRepeatEvent())).Times(1); |
1469 | - EXPECT_CALL(client.handler, handle_input(mt::KeyRepeatEvent())) |
1470 | - .WillOnce(mt::WakeUp(&client.all_events_received)); |
1471 | - |
1472 | - int const num_events_produced = 3; |
1473 | - |
1474 | - client.start(); |
1475 | - |
1476 | - for (int i = 0; i < num_events_produced; i++) |
1477 | - fake_event_hub()->synthesize_event( |
1478 | - mis::a_key_down_event().of_scancode(KEY_ENTER)); |
1479 | -} |
1480 | - |
1481 | -TEST_F(TestClientInput, clients_receive_us_english_mapped_keys) |
1482 | -{ |
1483 | - using namespace testing; |
1484 | - |
1485 | - InputClient client{new_connection(), test_client_name_1}; |
1486 | - |
1487 | - InSequence seq; |
1488 | - |
1489 | - EXPECT_CALL(client.handler, |
1490 | - handle_input( |
1491 | - AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_Shift_L)))); |
1492 | - EXPECT_CALL(client.handler, |
1493 | - handle_input( |
1494 | - AllOf(mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_dollar)))) |
1495 | - .WillOnce(mt::WakeUp(&client.all_events_received)); |
1496 | - |
1497 | - client.start(); |
1498 | - |
1499 | - fake_event_hub()->synthesize_event( |
1500 | - mis::a_key_down_event().of_scancode(KEY_LEFTSHIFT)); |
1501 | - fake_event_hub()->synthesize_event( |
1502 | - mis::a_key_down_event().of_scancode(KEY_4)); |
1503 | -} |
1504 | - |
1505 | -TEST_F(TestClientInput, clients_receive_pointer_inside_window_and_crossing_events) |
1506 | -{ |
1507 | - using namespace testing; |
1508 | - |
1509 | - InputClient client{new_connection(), test_client_name_1}; |
1510 | - |
1511 | - InSequence seq; |
1512 | - |
1513 | - // We should see the cursor enter |
1514 | - EXPECT_CALL(client.handler, handle_input(mt::PointerEnterEvent())); |
1515 | - EXPECT_CALL(client.handler, |
1516 | - handle_input( |
1517 | - mt::PointerEventWithPosition( |
1518 | - InputClient::surface_width - 1, |
1519 | - InputClient::surface_height - 1))); |
1520 | - EXPECT_CALL(client.handler, handle_input(mt::PointerLeaveEvent())) |
1521 | - .WillOnce(mt::WakeUp(&client.all_events_received)); |
1522 | - // But we should not receive an event for the second movement outside of our surface! |
1523 | - |
1524 | - client.start(); |
1525 | - |
1526 | - fake_event_hub()->synthesize_event( |
1527 | - mis::a_pointer_event().with_movement( |
1528 | - InputClient::surface_width - 1, |
1529 | - InputClient::surface_height - 1)); |
1530 | - fake_event_hub()->synthesize_event(mis::a_pointer_event().with_movement(2,2)); |
1531 | -} |
1532 | - |
1533 | -TEST_F(TestClientInput, clients_receive_button_events_inside_window) |
1534 | -{ |
1535 | - using namespace testing; |
1536 | - |
1537 | - InputClient client{new_connection(), test_client_name_1}; |
1538 | - |
1539 | - // The cursor starts at (0, 0). |
1540 | - EXPECT_CALL(client.handler, handle_input(mt::ButtonDownEvent(0, 0))) |
1541 | - .WillOnce(mt::WakeUp(&client.all_events_received)); |
1542 | - |
1543 | - client.start(); |
1544 | - |
1545 | - fake_event_hub()->synthesize_event( |
1546 | - mis::a_button_down_event() |
1547 | - .of_button(BTN_LEFT) |
1548 | - .with_action(mis::EventAction::Down)); |
1549 | -} |
1550 | - |
1551 | -TEST_F(TestClientInput, multiple_clients_receive_pointer_inside_windows) |
1552 | -{ |
1553 | - using namespace testing; |
1554 | - |
1555 | - int const screen_width = screen_geometry.size.width.as_int(); |
1556 | - int const screen_height = screen_geometry.size.height.as_int(); |
1557 | - int const client_height = screen_height / 2; |
1558 | - int const client_width = screen_width / 2; |
1559 | - |
1560 | - test_server_config().client_geometries[test_client_name_1] = |
1561 | - {{0, 0}, {client_width, client_height}}; |
1562 | - test_server_config().client_geometries[test_client_name_2] = |
1563 | - {{screen_width / 2, screen_height / 2}, {client_width, client_height}}; |
1564 | - |
1565 | - InputClient client1{new_connection(), test_client_name_1}; |
1566 | - InputClient client2{new_connection(), test_client_name_2}; |
1567 | - |
1568 | - { |
1569 | - InSequence seq; |
1570 | - EXPECT_CALL(client1.handler, handle_input(mt::PointerEnterEvent())); |
1571 | - EXPECT_CALL(client1.handler, |
1572 | - handle_input( |
1573 | - mt::PointerEventWithPosition(client_width - 1, client_height - 1))); |
1574 | - EXPECT_CALL(client1.handler, handle_input(mt::PointerLeaveEvent())) |
1575 | - .WillOnce(mt::WakeUp(&client1.all_events_received)); |
1576 | - } |
1577 | - |
1578 | - { |
1579 | - InSequence seq; |
1580 | - EXPECT_CALL(client2.handler, handle_input(mt::PointerEnterEvent())); |
1581 | - EXPECT_CALL(client2.handler, |
1582 | - handle_input( |
1583 | - mt::PointerEventWithPosition(client_width - 1, client_height - 1))) |
1584 | - .WillOnce(mt::WakeUp(&client2.all_events_received)); |
1585 | - } |
1586 | - |
1587 | - client1.start(); |
1588 | - client2.start(); |
1589 | - |
1590 | - // In the bounds of the first surface |
1591 | - fake_event_hub()->synthesize_event( |
1592 | - mis::a_pointer_event().with_movement(screen_width / 2 - 1, screen_height / 2 - 1)); |
1593 | - // In the bounds of the second surface |
1594 | - fake_event_hub()->synthesize_event( |
1595 | - mis::a_pointer_event().with_movement(screen_width / 2, screen_height / 2)); |
1596 | -} |
1597 | - |
1598 | -TEST_F(TestClientInput, clients_do_not_receive_pointer_outside_input_region) |
1599 | -{ |
1600 | - using namespace testing; |
1601 | - |
1602 | - int const client_height = InputClient::surface_height; |
1603 | - int const client_width = InputClient::surface_width; |
1604 | - |
1605 | - test_server_config().client_input_regions[test_client_name_1] = { |
1606 | - {{0, 0}, {client_width - 80, client_height}}, |
1607 | - {{client_width - 20, 0}, {client_width - 80, client_height}}}; |
1608 | - |
1609 | - InputClient client{new_connection(), test_client_name_1}; |
1610 | - |
1611 | - EXPECT_CALL(client.handler, handle_input(mt::PointerEnterEvent())).Times(AnyNumber()); |
1612 | - EXPECT_CALL(client.handler, handle_input(mt::PointerLeaveEvent())).Times(AnyNumber()); |
1613 | - EXPECT_CALL(client.handler, handle_input(mt::PointerMovementEvent())).Times(AnyNumber()); |
1614 | - |
1615 | - { |
1616 | - // We should see two of the three button pairs. |
1617 | - InSequence seq; |
1618 | - EXPECT_CALL(client.handler, handle_input(mt::ButtonDownEvent(1, 1))); |
1619 | - EXPECT_CALL(client.handler, handle_input(mt::ButtonUpEvent(1, 1))); |
1620 | - EXPECT_CALL(client.handler, handle_input(mt::ButtonDownEvent(99, 99))); |
1621 | - EXPECT_CALL(client.handler, handle_input(mt::ButtonUpEvent(99, 99))) |
1622 | - .WillOnce(mt::WakeUp(&client.all_events_received)); |
1623 | - } |
1624 | - |
1625 | - client.start(); |
1626 | - |
1627 | - // First we will move the cursor in to the input region on the left side of |
1628 | - // the window. We should see a click here. |
1629 | - fake_event_hub()->synthesize_event(mis::a_pointer_event().with_movement(1, 1)); |
1630 | - fake_event_hub()->synthesize_event( |
1631 | - mis::a_button_down_event() |
1632 | - .of_button(BTN_LEFT) |
1633 | - .with_action(mis::EventAction::Down)); |
1634 | - fake_event_hub()->synthesize_event(mis::a_button_up_event().of_button(BTN_LEFT)); |
1635 | - // Now in to the dead zone in the center of the window. We should not see |
1636 | - // a click here. |
1637 | - fake_event_hub()->synthesize_event(mis::a_pointer_event().with_movement(49, 49)); |
1638 | - fake_event_hub()->synthesize_event( |
1639 | - mis::a_button_down_event() |
1640 | - .of_button(BTN_LEFT) |
1641 | - .with_action(mis::EventAction::Down)); |
1642 | - fake_event_hub()->synthesize_event(mis::a_button_up_event().of_button(BTN_LEFT)); |
1643 | - // Now in to the right edge of the window, in the right input region. |
1644 | - // Again we should see a click. |
1645 | - fake_event_hub()->synthesize_event(mis::a_pointer_event().with_movement(49, 49)); |
1646 | - fake_event_hub()->synthesize_event( |
1647 | - mis::a_button_down_event() |
1648 | - .of_button(BTN_LEFT) |
1649 | - .with_action(mis::EventAction::Down)); |
1650 | - fake_event_hub()->synthesize_event(mis::a_button_up_event().of_button(BTN_LEFT)); |
1651 | -} |
1652 | - |
1653 | -TEST_F(TestClientInput, scene_obscure_motion_events_by_stacking) |
1654 | -{ |
1655 | - using namespace testing; |
1656 | - |
1657 | - auto smaller_geometry = screen_geometry; |
1658 | - smaller_geometry.size.width = |
1659 | - geom::Width{screen_geometry.size.width.as_uint32_t() / 2}; |
1660 | - |
1661 | - test_server_config().client_geometries[test_client_name_1] = screen_geometry; |
1662 | - test_server_config().client_geometries[test_client_name_2] = smaller_geometry; |
1663 | - test_server_config().client_depths[test_client_name_1] = ms::DepthId{0}; |
1664 | - test_server_config().client_depths[test_client_name_2] = ms::DepthId{1}; |
1665 | - |
1666 | - InputClient client1{new_connection(), test_client_name_1}; |
1667 | - InputClient client2{new_connection(), test_client_name_2}; |
1668 | - |
1669 | - EXPECT_CALL(client1.handler, handle_input(mt::PointerEnterEvent())).Times(AnyNumber()); |
1670 | - EXPECT_CALL(client1.handler, handle_input(mt::PointerLeaveEvent())).Times(AnyNumber()); |
1671 | - EXPECT_CALL(client1.handler, handle_input(mt::PointerMovementEvent())).Times(AnyNumber()); |
1672 | - { |
1673 | - // We should only see one button event sequence. |
1674 | - InSequence seq; |
1675 | - EXPECT_CALL(client1.handler, handle_input(mt::ButtonDownEvent(501, 1))); |
1676 | - EXPECT_CALL(client1.handler, handle_input(mt::ButtonUpEvent(501, 1))) |
1677 | - .WillOnce(mt::WakeUp(&client1.all_events_received)); |
1678 | - } |
1679 | - |
1680 | - EXPECT_CALL(client2.handler, handle_input(mt::PointerEnterEvent())).Times(AnyNumber()); |
1681 | - EXPECT_CALL(client2.handler, handle_input(mt::PointerLeaveEvent())).Times(AnyNumber()); |
1682 | - EXPECT_CALL(client2.handler, handle_input(mt::PointerMovementEvent())).Times(AnyNumber()); |
1683 | - { |
1684 | - // Likewise we should only see one button sequence. |
1685 | - InSequence seq; |
1686 | - EXPECT_CALL(client2.handler, handle_input(mt::ButtonDownEvent(1, 1))); |
1687 | - EXPECT_CALL(client2.handler, handle_input(mt::ButtonUpEvent(1, 1))) |
1688 | - .WillOnce(mt::WakeUp(&client2.all_events_received)); |
1689 | - } |
1690 | - |
1691 | - client1.start(); |
1692 | - client2.start(); |
1693 | - |
1694 | - // First we will move the cursor in to the region where client 2 obscures client 1 |
1695 | - fake_event_hub()->synthesize_event(mis::a_pointer_event().with_movement(1, 1)); |
1696 | - fake_event_hub()->synthesize_event( |
1697 | - mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down)); |
1698 | - fake_event_hub()->synthesize_event(mis::a_button_up_event().of_button(BTN_LEFT)); |
1699 | - // Now we move to the unobscured region of client 1 |
1700 | - fake_event_hub()->synthesize_event(mis::a_pointer_event().with_movement(500, 0)); |
1701 | - fake_event_hub()->synthesize_event( |
1702 | - mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down)); |
1703 | - fake_event_hub()->synthesize_event(mis::a_button_up_event().of_button(BTN_LEFT)); |
1704 | -} |
1705 | - |
1706 | -TEST_F(TestClientInput, hidden_clients_do_not_receive_pointer_events) |
1707 | -{ |
1708 | - using namespace testing; |
1709 | - |
1710 | - mt::WaitCondition second_client_done; |
1711 | - |
1712 | - test_server_config().client_depths[test_client_name_1] = ms::DepthId{0}; |
1713 | - test_server_config().client_depths[test_client_name_2] = ms::DepthId{1}; |
1714 | - |
1715 | - InputClient client1{new_connection(), test_client_name_1}; |
1716 | - InputClient client2{new_connection(), test_client_name_2}; |
1717 | - |
1718 | - EXPECT_CALL(client1.handler, handle_input(mt::PointerEnterEvent())).Times(AnyNumber()); |
1719 | - EXPECT_CALL(client1.handler, handle_input(mt::PointerLeaveEvent())).Times(AnyNumber()); |
1720 | - EXPECT_CALL(client1.handler, handle_input(mt::PointerEventWithPosition(2, 2))) |
1721 | - .WillOnce(mt::WakeUp(&client1.all_events_received)); |
1722 | - |
1723 | - EXPECT_CALL(client2.handler, handle_input(mt::PointerEnterEvent())).Times(AnyNumber()); |
1724 | - EXPECT_CALL(client2.handler, handle_input(mt::PointerLeaveEvent())).Times(AnyNumber()); |
1725 | - EXPECT_CALL(client2.handler, handle_input(mt::PointerEventWithPosition(1, 1))) |
1726 | - .WillOnce(DoAll(mt::WakeUp(&second_client_done), |
1727 | - mt::WakeUp(&client2.all_events_received))); |
1728 | - |
1729 | - client1.start(); |
1730 | - client2.start(); |
1731 | - |
1732 | - // We send one event and then hide the surface on top before sending the next. |
1733 | - // So we expect each of the two surfaces to receive one even |
1734 | - fake_event_hub()->synthesize_event(mis::a_pointer_event().with_movement(1,1)); |
1735 | - // We use a fence to ensure we do not hide the client |
1736 | - // before event dispatch occurs |
1737 | - second_client_done.wait_for_at_most_seconds(60); |
1738 | - |
1739 | - server_config().the_session_container()->for_each( |
1740 | - [&](std::shared_ptr<ms::Session> const& session) -> void |
1741 | - { |
1742 | - if (session->name() == test_client_name_2) |
1743 | - session->hide(); |
1744 | - }); |
1745 | - // As the surface will not be unocludded immediately when the other surface is |
1746 | - // hidden (due to the compositor feedback approach used) |
1747 | - // See bug: https://bugs.launchpad.net/mir/+bug/1408168 |
1748 | - client1.wait_for_surface_to_become_focused_and_exposed(); |
1749 | - |
1750 | - fake_event_hub()->synthesize_event(mis::a_pointer_event().with_movement(1,1)); |
1751 | -} |
1752 | - |
1753 | -TEST_F(TestClientInput, clients_receive_pointer_within_coordinate_system_of_window) |
1754 | -{ |
1755 | - using namespace testing; |
1756 | - |
1757 | - int const screen_width = screen_geometry.size.width.as_int(); |
1758 | - int const screen_height = screen_geometry.size.height.as_int(); |
1759 | - int const client_height = screen_height / 2; |
1760 | - int const client_width = screen_width / 2; |
1761 | - |
1762 | - test_server_config().client_geometries[test_client_name_1] = |
1763 | - {{screen_width / 2, screen_height / 2}, {client_width, client_height}}; |
1764 | - |
1765 | - InputClient client1{new_connection(), test_client_name_1}; |
1766 | - |
1767 | - InSequence seq; |
1768 | - EXPECT_CALL(client1.handler, handle_input(mt::PointerEnterEvent())); |
1769 | - EXPECT_CALL(client1.handler, handle_input(mt::PointerEventWithPosition(80, 170))) |
1770 | - .Times(AnyNumber()) |
1771 | - .WillOnce(mt::WakeUp(&client1.all_events_received)); |
1772 | - |
1773 | - client1.start(); |
1774 | - |
1775 | - server_config().the_session_container()->for_each( |
1776 | - [&](std::shared_ptr<ms::Session> const& session) -> void |
1777 | - { |
1778 | - session->default_surface()->move_to( |
1779 | - geom::Point{screen_width / 2 - 40, screen_height / 2 - 80}); |
1780 | - }); |
1781 | - |
1782 | - fake_event_hub()->synthesize_event( |
1783 | - mis::a_pointer_event().with_movement(screen_width / 2 + 40, screen_height / 2 + 90)); |
1784 | -} |
1785 | - |
1786 | -// TODO: Consider tests for more input devices with custom mapping (i.e. joysticks...) |
1787 | -TEST_F(TestClientInput, usb_direct_input_devices_work) |
1788 | -{ |
1789 | - using namespace ::testing; |
1790 | - |
1791 | - auto const minimum_touch = mia::FakeEventHub::TouchScreenMinAxisValue; |
1792 | - auto const maximum_touch = mia::FakeEventHub::TouchScreenMaxAxisValue; |
1793 | - auto const display_width = screen_geometry.size.width.as_uint32_t(); |
1794 | - auto const display_height = screen_geometry.size.height.as_uint32_t(); |
1795 | - |
1796 | - // We place a click 10% in to the touchscreens space in both axis, |
1797 | - // and a second at 0,0. Thus we expect to see a click at |
1798 | - // .1*screen_width/height and a second at zero zero. |
1799 | - static int const abs_touch_x_1 = minimum_touch + (maximum_touch - minimum_touch) * 0.1; |
1800 | - static int const abs_touch_y_1 = minimum_touch + (maximum_touch - minimum_touch) * 0.1; |
1801 | - static int const abs_touch_x_2 = 0; |
1802 | - static int const abs_touch_y_2 = 0; |
1803 | - |
1804 | - static float const expected_scale_x = |
1805 | - float(display_width) / (maximum_touch - minimum_touch + 1); |
1806 | - static float const expected_scale_y = |
1807 | - float(display_height) / (maximum_touch - minimum_touch + 1); |
1808 | - |
1809 | - static float const expected_motion_x_1 = expected_scale_x * abs_touch_x_1; |
1810 | - static float const expected_motion_y_1 = expected_scale_y * abs_touch_y_1; |
1811 | - static float const expected_motion_x_2 = expected_scale_x * abs_touch_x_2; |
1812 | - static float const expected_motion_y_2 = expected_scale_y * abs_touch_y_2; |
1813 | - |
1814 | - test_server_config().client_geometries[test_client_name_1] = screen_geometry; |
1815 | - |
1816 | - InputClient client1{new_connection(), test_client_name_1}; |
1817 | - |
1818 | - InSequence seq; |
1819 | - EXPECT_CALL(client1.handler, handle_input( |
1820 | - mt::TouchEvent(expected_motion_x_1, expected_motion_y_1))); |
1821 | - EXPECT_CALL(client1.handler, handle_input( |
1822 | - mt::TouchEventInDirection(expected_motion_x_1, |
1823 | - expected_motion_y_1, |
1824 | - expected_motion_x_2, |
1825 | - expected_motion_y_2))) |
1826 | - .WillOnce(mt::WakeUp(&client1.all_events_received)); |
1827 | - |
1828 | - client1.start(); |
1829 | - |
1830 | - fake_event_hub()->synthesize_event( |
1831 | - mis::a_touch_event().at_position({abs_touch_x_1, abs_touch_y_1})); |
1832 | - // Sleep here to trigger more failures (simulate slow machine) |
1833 | - std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
1834 | - fake_event_hub()->synthesize_event( |
1835 | - mis::a_touch_event().at_position({abs_touch_x_2, abs_touch_y_2})); |
1836 | -} |
1837 | - |
1838 | -TEST_F(TestClientInput, send_mir_input_events_through_surface) |
1839 | -{ |
1840 | - InputClient client1{new_connection(), test_client_name_1}; |
1841 | - |
1842 | - EXPECT_CALL(client1.handler, handle_input(mt::KeyDownEvent())) |
1843 | - .WillOnce(mt::WakeUp(&client1.all_events_received)); |
1844 | - |
1845 | - client1.start(); |
1846 | - |
1847 | - server_config().the_session_container()->for_each( |
1848 | - [] (std::shared_ptr<ms::Session> const& session) -> void |
1849 | - { |
1850 | - MirEvent key_event; |
1851 | - std::memset(&key_event, 0, sizeof key_event); |
1852 | - key_event.type = mir_event_type_key; |
1853 | - key_event.key.action = mir_keyboard_action_down; |
1854 | - |
1855 | - session->default_surface()->consume(key_event); |
1856 | - }); |
1857 | -} |
1858 | - |
1859 | -TEST_F(TestClientInput, clients_receive_keymap_change_events) |
1860 | -{ |
1861 | - using namespace testing; |
1862 | - |
1863 | - mt::WaitCondition first_event_received; |
1864 | - InputClient client{new_connection(), test_client_name_1}; |
1865 | - |
1866 | - xkb_rule_names names; |
1867 | - names.rules = "evdev"; |
1868 | - names.model = "pc105"; |
1869 | - names.layout = "dvorak"; |
1870 | - names.variant = ""; |
1871 | - names.options = ""; |
1872 | - |
1873 | - InSequence seq; |
1874 | - EXPECT_CALL(client.handler, handle_input( |
1875 | - mt::KeymapEventWithRules(names))) |
1876 | - .Times(1).WillOnce(mt::WakeUp(&client.all_events_received)); |
1877 | - |
1878 | - client.start(); |
1879 | - |
1880 | - server_config().the_session_container()->for_each( |
1881 | - [names] (std::shared_ptr<ms::Session> const& session) -> void |
1882 | - { |
1883 | - session->default_surface()->set_keymap(names); |
1884 | - }); |
1885 | -} |
1886 | - |
1887 | - |
1888 | -TEST_F(TestClientInput, keymap_changes_change_keycode_received) |
1889 | -{ |
1890 | - using namespace testing; |
1891 | - |
1892 | - xkb_rule_names names; |
1893 | - names.rules = "evdev"; |
1894 | - names.model = "pc105"; |
1895 | - names.layout = "us"; |
1896 | - names.variant = "dvorak"; |
1897 | - names.options = ""; |
1898 | - |
1899 | - mt::WaitCondition first_event_received, |
1900 | - client_sees_keymap_change; |
1901 | - InputClient client{new_connection(), test_client_name_1}; |
1902 | - |
1903 | - InSequence seq; |
1904 | - EXPECT_CALL(client.handler, handle_input(AllOf( |
1905 | - mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_n)))).Times(1); |
1906 | - EXPECT_CALL(client.handler, handle_input(mt::KeyUpEvent())) |
1907 | - .Times(1).WillOnce(mt::WakeUp(&first_event_received)); |
1908 | - EXPECT_CALL(client.handler, handle_input( |
1909 | - mt::KeymapEventWithRules(names))) |
1910 | - .Times(1).WillOnce(mt::WakeUp(&client_sees_keymap_change)); |
1911 | - EXPECT_CALL(client.handler, handle_input(AllOf( |
1912 | - mt::KeyDownEvent(), mt::KeyOfSymbol(XKB_KEY_b)))).Times(1); |
1913 | - EXPECT_CALL(client.handler, handle_input(mt::KeyUpEvent())) |
1914 | - .Times(1).WillOnce(mt::WakeUp(&client.all_events_received)); |
1915 | - |
1916 | - client.start(); |
1917 | - |
1918 | - fake_event_hub()->synthesize_event( |
1919 | - mis::a_key_down_event().of_scancode(KEY_N)); |
1920 | - fake_event_hub()->synthesize_event( |
1921 | - mis::a_key_up_event().of_scancode(KEY_N)); |
1922 | - |
1923 | - first_event_received.wait_for_at_most_seconds(60); |
1924 | - |
1925 | - server_config().the_session_container()->for_each( |
1926 | - [&names] (std::shared_ptr<ms::Session> const& session) -> void |
1927 | - { |
1928 | - session->default_surface()->set_keymap(names); |
1929 | - }); |
1930 | - |
1931 | - client_sees_keymap_change.wait_for_at_most_seconds(60); |
1932 | - |
1933 | - fake_event_hub()->synthesize_event( |
1934 | - mis::a_key_down_event().of_scancode(KEY_N)); |
1935 | - fake_event_hub()->synthesize_event( |
1936 | - mis::a_key_up_event().of_scancode(KEY_N)); |
1937 | -} |
1938 | |
1939 | === modified file 'tests/acceptance-tests/throwback/test_custom_input_targeter.cpp' |
1940 | --- tests/acceptance-tests/throwback/test_custom_input_targeter.cpp 2015-05-07 07:07:20 +0000 |
1941 | +++ tests/acceptance-tests/throwback/test_custom_input_targeter.cpp 2015-05-14 18:12:40 +0000 |
1942 | @@ -40,7 +40,6 @@ |
1943 | namespace ms = mir::scene; |
1944 | namespace mi = mir::input; |
1945 | namespace mt = mir::test; |
1946 | -namespace mtd = mt::doubles; |
1947 | namespace mt = mir::test; |
1948 | namespace mc = mir::compositor; |
1949 | namespace mtf = mir_test_framework; |
1950 | |
1951 | === modified file 'tests/include/mir_test/event_matchers.h' |
1952 | --- tests/include/mir_test/event_matchers.h 2015-05-07 07:07:20 +0000 |
1953 | +++ tests/include/mir_test/event_matchers.h 2015-05-14 18:12:40 +0000 |
1954 | @@ -135,10 +135,9 @@ |
1955 | return false; |
1956 | |
1957 | if(mir_keyboard_event_modifiers(kev) != modifiers) |
1958 | - { |
1959 | - printf("modifiers: %d vs expected %d \n", mir_keyboard_event_modifiers(kev), modifiers); |
1960 | + { |
1961 | return false; |
1962 | - } |
1963 | + } |
1964 | |
1965 | return true; |
1966 | } |
1967 | @@ -229,36 +228,38 @@ |
1968 | return false; |
1969 | } |
1970 | |
1971 | +inline bool button_event_matches(MirPointerEvent const* pev, float x, float y, MirPointerAction action, MirPointerButtons button_state, |
1972 | + bool check_action = true) |
1973 | +{ |
1974 | + if (pev == nullptr) |
1975 | + return false; |
1976 | + if (check_action && mir_pointer_event_action(pev) != action) |
1977 | + return false; |
1978 | + if (mir_pointer_event_buttons(pev) != button_state) |
1979 | + return false; |
1980 | + if (mir_pointer_event_axis_value(pev, mir_pointer_axis_x) != x) |
1981 | + return false; |
1982 | + if (mir_pointer_event_axis_value(pev, mir_pointer_axis_y) != y) |
1983 | + return false; |
1984 | + return true; |
1985 | +} |
1986 | + |
1987 | MATCHER_P2(ButtonDownEvent, x, y, "") |
1988 | { |
1989 | auto pev = maybe_pointer_event(to_address(arg)); |
1990 | - if (pev == nullptr) |
1991 | - return false; |
1992 | - if (mir_pointer_event_action(pev) != mir_pointer_action_button_down) |
1993 | - return false; |
1994 | - if (mir_pointer_event_button_state(pev, mir_pointer_button_primary) == false) |
1995 | - return false; |
1996 | - if (mir_pointer_event_axis_value(pev, mir_pointer_axis_x) != x) |
1997 | - return false; |
1998 | - if (mir_pointer_event_axis_value(pev, mir_pointer_axis_y) != y) |
1999 | - return false; |
2000 | - return true; |
2001 | + return button_event_matches(pev, x, y, mir_pointer_action_button_down, mir_pointer_button_primary); |
2002 | } |
2003 | |
2004 | MATCHER_P2(ButtonUpEvent, x, y, "") |
2005 | { |
2006 | auto pev = maybe_pointer_event(to_address(arg)); |
2007 | - if (pev == nullptr) |
2008 | - return false; |
2009 | - if (mir_pointer_event_action(pev) != mir_pointer_action_button_up) |
2010 | - return false; |
2011 | - if (mir_pointer_event_button_state(pev, mir_pointer_button_primary) == true) |
2012 | - return false; |
2013 | - if (mir_pointer_event_axis_value(pev, mir_pointer_axis_x) != x) |
2014 | - return false; |
2015 | - if (mir_pointer_event_axis_value(pev, mir_pointer_axis_y) != y) |
2016 | - return false; |
2017 | - return true; |
2018 | + return button_event_matches(pev, x, y, mir_pointer_action_button_up, 0); |
2019 | +} |
2020 | + |
2021 | +MATCHER_P3(ButtonsDown, x, y, buttons, "") |
2022 | +{ |
2023 | + auto pev = maybe_pointer_event(to_address(arg)); |
2024 | + return button_event_matches(pev, x, y, mir_pointer_action_button_down, buttons, false); |
2025 | } |
2026 | |
2027 | MATCHER_P2(TouchEvent, x, y, "") |
2028 | @@ -269,9 +270,9 @@ |
2029 | |
2030 | if (mir_touch_event_action(tev, 0) != mir_touch_action_down) |
2031 | return false; |
2032 | - if (mir_touch_event_axis_value(tev, 0, mir_touch_axis_x) != x) |
2033 | + if (std::abs(mir_touch_event_axis_value(tev, 0, mir_touch_axis_x) - x) > 0.5f) |
2034 | return false; |
2035 | - if (mir_touch_event_axis_value(tev, 0, mir_touch_axis_y) != y) |
2036 | + if (std::abs(mir_touch_event_axis_value(tev, 0, mir_touch_axis_y) - y) > 0.5f) |
2037 | return false; |
2038 | |
2039 | return true; |
2040 | |
2041 | === modified file 'tests/include/mir_test_framework/input_testing_server_configuration.h' |
2042 | --- tests/include/mir_test_framework/input_testing_server_configuration.h 2015-03-31 09:10:52 +0000 |
2043 | +++ tests/include/mir_test_framework/input_testing_server_configuration.h 2015-05-14 18:12:40 +0000 |
2044 | @@ -31,24 +31,6 @@ |
2045 | #include <atomic> |
2046 | #include <thread> |
2047 | |
2048 | -namespace mir |
2049 | -{ |
2050 | -namespace input |
2051 | -{ |
2052 | -namespace android |
2053 | -{ |
2054 | -class FakeEventHub; |
2055 | -} |
2056 | -} |
2057 | -namespace test |
2058 | -{ |
2059 | -namespace doubles |
2060 | -{ |
2061 | -class FakeEventHubInputConfiguration; |
2062 | -} |
2063 | -} |
2064 | -} |
2065 | - |
2066 | namespace mir_test_framework |
2067 | { |
2068 | |
2069 | @@ -61,20 +43,16 @@ |
2070 | void on_start() override; |
2071 | void on_exit() override; |
2072 | |
2073 | - std::shared_ptr<droidinput::EventHubInterface> the_event_hub() override; |
2074 | std::shared_ptr<mir::input::InputManager> the_input_manager() override; |
2075 | std::shared_ptr<mir::input::InputDispatcher> the_input_dispatcher() override; |
2076 | std::shared_ptr<mir::shell::InputTargeter> the_input_targeter() override; |
2077 | std::shared_ptr<mir::input::InputSender> the_input_sender() override; |
2078 | |
2079 | - |
2080 | protected: |
2081 | virtual void inject_input() = 0; |
2082 | |
2083 | void wait_until_client_appears(std::string const& surface_name); |
2084 | |
2085 | -private: |
2086 | - std::shared_ptr<mir::input::android::FakeEventHub> fake_event_hub; |
2087 | std::thread input_injection_thread; |
2088 | }; |
2089 | |
2090 | |
2091 | === added file 'tests/include/mir_test_framework/placement_applying_shell.h' |
2092 | --- tests/include/mir_test_framework/placement_applying_shell.h 1970-01-01 00:00:00 +0000 |
2093 | +++ tests/include/mir_test_framework/placement_applying_shell.h 2015-05-14 18:12:40 +0000 |
2094 | @@ -0,0 +1,59 @@ |
2095 | +/* |
2096 | + * Copyright © 2015 Canonical Ltd. |
2097 | + * |
2098 | + * This program is free software: you can redistribute it and/or modify it |
2099 | + * under the terms of the GNU General Public License version 3, |
2100 | + * as published by the Free Software Foundation. |
2101 | + * |
2102 | + * This program is distributed in the hope that it will be useful, |
2103 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2104 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2105 | + * GNU General Public License for more details. |
2106 | + * |
2107 | + * You should have received a copy of the GNU General Public License |
2108 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2109 | + * |
2110 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
2111 | + */ |
2112 | + |
2113 | +#ifndef MIR_TEST_FRAMEWORK_PLACEMENT_APPLYING_SHELL_H_ |
2114 | +#define MIR_TEST_FRAMEWORK_PLACEMENT_APPLYING_SHELL_H_ |
2115 | + |
2116 | +#include "mir/shell/shell_wrapper.h" |
2117 | +#include "mir/geometry/rectangle.h" |
2118 | +#include "mir/scene/depth_id.h" |
2119 | + |
2120 | +#include "mir/scene/session.h" |
2121 | +#include "mir/scene/surface.h" |
2122 | +#include "mir/scene/surface_creation_parameters.h" |
2123 | + |
2124 | +#include <vector> |
2125 | +#include <string> |
2126 | +#include <map> |
2127 | + |
2128 | +namespace mir_test_framework |
2129 | +{ |
2130 | +using ClientInputRegions = std::map<std::string, std::vector<mir::geometry::Rectangle>>; |
2131 | +using ClientPositions = std::map<std::string, mir::geometry::Rectangle>; |
2132 | +using ClientDepths = std::map<std::string, mir::scene::DepthId>; |
2133 | + |
2134 | +struct PlacementApplyingShell : mir::shell::ShellWrapper |
2135 | +{ |
2136 | + PlacementApplyingShell( |
2137 | + std::shared_ptr<mir::shell::Shell> wrapped_coordinator, |
2138 | + ClientInputRegions const& client_input_regions, |
2139 | + ClientPositions const& client_positions, |
2140 | + ClientDepths const& client_depths); |
2141 | + |
2142 | + mir::frontend::SurfaceId create_surface( |
2143 | + std::shared_ptr<mir::scene::Session> const& session, |
2144 | + mir::scene::SurfaceCreationParameters const& params) override; |
2145 | +private: |
2146 | + ClientInputRegions const& client_input_regions; |
2147 | + ClientPositions const& client_positions; |
2148 | + ClientDepths const& client_depths; |
2149 | +}; |
2150 | + |
2151 | +} |
2152 | + |
2153 | +#endif |
2154 | |
2155 | === modified file 'tests/integration-tests/input/CMakeLists.txt' |
2156 | --- tests/integration-tests/input/CMakeLists.txt 2015-04-16 22:11:07 +0000 |
2157 | +++ tests/integration-tests/input/CMakeLists.txt 2015-05-14 18:12:40 +0000 |
2158 | @@ -1,12 +1,9 @@ |
2159 | list( |
2160 | APPEND INTEGRATION_TESTS_SRCS |
2161 | ${CMAKE_CURRENT_SOURCE_DIR}/test_configuring_input_manager.cpp |
2162 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_cursor_listener.cpp |
2163 | ) |
2164 | |
2165 | -if(NOT MIR_TEST_PLATFORM STREQUAL "android") |
2166 | - add_subdirectory(android) |
2167 | -endif() |
2168 | - |
2169 | set( |
2170 | INTEGRATION_TESTS_SRCS |
2171 | ${INTEGRATION_TESTS_SRCS} |
2172 | |
2173 | === removed directory 'tests/integration-tests/input/android' |
2174 | === removed file 'tests/integration-tests/input/android/CMakeLists.txt' |
2175 | --- tests/integration-tests/input/android/CMakeLists.txt 2015-05-06 12:57:11 +0000 |
2176 | +++ tests/integration-tests/input/android/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
2177 | @@ -1,9 +0,0 @@ |
2178 | -list( |
2179 | - APPEND INTEGRATION_TESTS_SRCS |
2180 | - ${CMAKE_CURRENT_SOURCE_DIR}/test_android_cursor_listener.cpp |
2181 | -) |
2182 | - |
2183 | -set( |
2184 | - INTEGRATION_TESTS_SRCS |
2185 | - ${INTEGRATION_TESTS_SRCS} |
2186 | - PARENT_SCOPE) |
2187 | |
2188 | === renamed file 'tests/integration-tests/input/android/test_android_cursor_listener.cpp' => 'tests/integration-tests/input/test_cursor_listener.cpp' |
2189 | --- tests/integration-tests/input/android/test_android_cursor_listener.cpp 2015-04-20 20:07:52 +0000 |
2190 | +++ tests/integration-tests/input/test_cursor_listener.cpp 2015-05-14 18:12:40 +0000 |
2191 | @@ -20,8 +20,10 @@ |
2192 | #include "mir/events/event_private.h" |
2193 | |
2194 | #include "mir_test/fake_shared.h" |
2195 | -#include "mir_test/fake_event_hub.h" |
2196 | -#include "mir_test_framework/fake_event_hub_server_configuration.h" |
2197 | +#include "mir_test_framework/fake_input_device.h" |
2198 | +#include "mir_test_framework/stubbed_server_configuration.h" |
2199 | +#include "mir_test_framework/stub_server_platform_factory.h" |
2200 | +#include "mir_test_framework/temporary_environment_value.h" |
2201 | #include "mir_test_doubles/stub_input_enumerator.h" |
2202 | #include "mir_test_doubles/stub_touch_visualizer.h" |
2203 | #include "mir_test/wait_condition.h" |
2204 | @@ -30,17 +32,18 @@ |
2205 | #include "mir/input/cursor_listener.h" |
2206 | #include "mir/input/input_dispatcher.h" |
2207 | #include "mir/input/input_manager.h" |
2208 | +#include "mir/input/input_device_info.h" |
2209 | +#include "mir_test_framework/executable_path.h" |
2210 | |
2211 | #include <gmock/gmock.h> |
2212 | #include <gtest/gtest.h> |
2213 | |
2214 | #include <thread> |
2215 | +#include <cstdlib> |
2216 | |
2217 | namespace mi = mir::input; |
2218 | -namespace mia = mir::input::android; |
2219 | namespace mis = mir::input::synthesis; |
2220 | namespace mt = mir::test; |
2221 | -namespace mtd = mir::test::doubles; |
2222 | namespace mtf = mir_test_framework; |
2223 | |
2224 | namespace |
2225 | @@ -54,8 +57,11 @@ |
2226 | ~MockCursorListener() noexcept {} |
2227 | }; |
2228 | |
2229 | -struct AndroidCursorListenerIntegrationTest : testing::Test, mtf::FakeEventHubServerConfiguration |
2230 | +struct CursorListenerIntegrationTest : testing::Test, mtf::StubbedServerConfiguration |
2231 | { |
2232 | + mtf::TemporaryEnvironmentValue input_lib{"MIR_SERVER_PLATFORM_INPUT_LIB", mtf::server_platform("input-stub.so").c_str()}; |
2233 | + mtf::TemporaryEnvironmentValue real_input{"MIR_SERVER_TESTS_USE_REAL_INPUT", "1"}; |
2234 | + |
2235 | bool is_key_repeat_enabled() const override |
2236 | { |
2237 | return false; |
2238 | @@ -83,11 +89,15 @@ |
2239 | MockCursorListener cursor_listener; |
2240 | std::shared_ptr<mi::InputManager> input_manager; |
2241 | std::shared_ptr<mi::InputDispatcher> input_dispatcher; |
2242 | + |
2243 | + std::unique_ptr<mtf::FakeInputDevice> fake_mouse{ |
2244 | + mtf::add_fake_input_device(mi::InputDeviceInfo{ 0, "mouse", "mouse-uid" , mi::DeviceCapability::pointer}) |
2245 | + }; |
2246 | }; |
2247 | |
2248 | } |
2249 | |
2250 | -TEST_F(AndroidCursorListenerIntegrationTest, cursor_listener_receives_motion) |
2251 | +TEST_F(CursorListenerIntegrationTest, cursor_listener_receives_motion) |
2252 | { |
2253 | using namespace ::testing; |
2254 | |
2255 | @@ -98,10 +108,7 @@ |
2256 | |
2257 | EXPECT_CALL(cursor_listener, cursor_moved_to(x, y)).Times(1).WillOnce(mt::WakeUp(wait_condition)); |
2258 | |
2259 | - fake_event_hub->synthesize_builtin_cursor_added(); |
2260 | - fake_event_hub->synthesize_device_scan_complete(); |
2261 | - |
2262 | - fake_event_hub->synthesize_event(mis::a_pointer_event().with_movement(x, y)); |
2263 | + fake_mouse->emit_event(mis::a_pointer_event().with_movement(x, y)); |
2264 | |
2265 | wait_condition->wait_for_at_most_seconds(10); |
2266 | } |
2267 | |
2268 | === modified file 'tests/mir_test_framework/CMakeLists.txt' |
2269 | --- tests/mir_test_framework/CMakeLists.txt 2015-04-30 11:36:36 +0000 |
2270 | +++ tests/mir_test_framework/CMakeLists.txt 2015-05-14 18:12:40 +0000 |
2271 | @@ -46,6 +46,7 @@ |
2272 | fake_event_hub_server_configuration.cpp |
2273 | any_surface.cpp |
2274 | headless_nested_server_runner.cpp |
2275 | + placement_applying_shell.cpp |
2276 | ) |
2277 | |
2278 | list(APPEND TEST_FRAMEWORK_SRCS |
2279 | |
2280 | === modified file 'tests/mir_test_framework/fake_input_device_impl.cpp' |
2281 | --- tests/mir_test_framework/fake_input_device_impl.cpp 2015-05-07 20:41:25 +0000 |
2282 | +++ tests/mir_test_framework/fake_input_device_impl.cpp 2015-05-14 18:12:40 +0000 |
2283 | @@ -144,7 +144,7 @@ |
2284 | |
2285 | mtf::FakeInputDeviceImpl::InputDevice::InputDevice(mi::InputDeviceInfo const& info, |
2286 | std::shared_ptr<mir::dispatch::Dispatchable> const& dispatchable) |
2287 | - : info(info), queue{dispatchable} |
2288 | + : info(info), queue{dispatchable}, buttons{0} |
2289 | { |
2290 | } |
2291 | |
2292 | @@ -197,12 +197,12 @@ |
2293 | { |
2294 | if (action == synthesis::EventAction::Down) |
2295 | { |
2296 | - buttons.push_back(button); |
2297 | + buttons |= button; |
2298 | return mir_pointer_action_button_down; |
2299 | } |
2300 | else |
2301 | { |
2302 | - buttons.erase(remove(begin(buttons), end(buttons), button)); |
2303 | + buttons &= ~button; |
2304 | return mir_pointer_action_button_up; |
2305 | } |
2306 | } |
2307 | |
2308 | === modified file 'tests/mir_test_framework/fake_input_device_impl.h' |
2309 | --- tests/mir_test_framework/fake_input_device_impl.h 2015-05-04 07:28:06 +0000 |
2310 | +++ tests/mir_test_framework/fake_input_device_impl.h 2015-05-14 18:12:40 +0000 |
2311 | @@ -25,8 +25,6 @@ |
2312 | #include "mir/input/input_device_info.h" |
2313 | #include "mir/geometry/point.h" |
2314 | |
2315 | -#include <vector> |
2316 | - |
2317 | namespace mir |
2318 | { |
2319 | namespace dispatch |
2320 | @@ -76,7 +74,7 @@ |
2321 | std::shared_ptr<mir::dispatch::Dispatchable> const queue; |
2322 | uint32_t modifiers{0}; |
2323 | mir::geometry::Point pos, scroll; |
2324 | - std::vector<MirPointerButton> buttons; |
2325 | + MirPointerButtons buttons; |
2326 | }; |
2327 | std::shared_ptr<mir::dispatch::ActionQueue> queue; |
2328 | std::shared_ptr<InputDevice> device; |
2329 | |
2330 | === modified file 'tests/mir_test_framework/input_testing_server_options.cpp' |
2331 | --- tests/mir_test_framework/input_testing_server_options.cpp 2015-03-31 02:35:42 +0000 |
2332 | +++ tests/mir_test_framework/input_testing_server_options.cpp 2015-05-14 18:12:40 +0000 |
2333 | @@ -24,7 +24,6 @@ |
2334 | #include "mir/frontend/session.h" |
2335 | #include "mir/input/composite_event_filter.h" |
2336 | |
2337 | -#include "mir_test/fake_event_hub.h" |
2338 | #include "mir_test/wait_condition.h" |
2339 | |
2340 | #include <boost/throw_exception.hpp> |
2341 | @@ -41,7 +40,6 @@ |
2342 | namespace ms = mir::shell; |
2343 | namespace mia = mi::android; |
2344 | namespace geom = mir::geometry; |
2345 | -namespace mtd = mir::test::doubles; |
2346 | |
2347 | mtf::InputTestingServerConfiguration::InputTestingServerConfiguration() |
2348 | { |
2349 | @@ -96,18 +94,3 @@ |
2350 | { |
2351 | return DefaultServerConfiguration::the_input_sender(); |
2352 | } |
2353 | - |
2354 | -std::shared_ptr<droidinput::EventHubInterface> mtf::InputTestingServerConfiguration::the_event_hub() |
2355 | -{ |
2356 | - if (!fake_event_hub) |
2357 | - { |
2358 | - fake_event_hub = std::make_shared<mia::FakeEventHub>(); |
2359 | - |
2360 | - fake_event_hub->synthesize_builtin_keyboard_added(); |
2361 | - fake_event_hub->synthesize_builtin_cursor_added(); |
2362 | - fake_event_hub->synthesize_usb_touchscreen_added(); |
2363 | - fake_event_hub->synthesize_device_scan_complete(); |
2364 | - } |
2365 | - |
2366 | - return fake_event_hub; |
2367 | -} |
2368 | |
2369 | === added file 'tests/mir_test_framework/placement_applying_shell.cpp' |
2370 | --- tests/mir_test_framework/placement_applying_shell.cpp 1970-01-01 00:00:00 +0000 |
2371 | +++ tests/mir_test_framework/placement_applying_shell.cpp 2015-05-14 18:12:40 +0000 |
2372 | @@ -0,0 +1,59 @@ |
2373 | +/* |
2374 | + * Copyright © 2015 Canonical Ltd. |
2375 | + * |
2376 | + * This program is free software: you can redistribute it and/or modify it |
2377 | + * under the terms of the GNU General Public License version 3, |
2378 | + * as published by the Free Software Foundation. |
2379 | + * |
2380 | + * This program is distributed in the hope that it will be useful, |
2381 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2382 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2383 | + * GNU General Public License for more details. |
2384 | + * |
2385 | + * You should have received a copy of the GNU General Public License |
2386 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2387 | + * |
2388 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
2389 | + */ |
2390 | + |
2391 | +#include "mir_test_framework/placement_applying_shell.h" |
2392 | + |
2393 | +namespace mtf = mir_test_framework; |
2394 | + |
2395 | +mtf::PlacementApplyingShell::PlacementApplyingShell(std::shared_ptr<mir::shell::Shell> wrapped_coordinator, |
2396 | + ClientInputRegions const& client_input_regions, |
2397 | + ClientPositions const& client_positions, |
2398 | + ClientDepths const& client_depths) : |
2399 | + mir::shell::ShellWrapper(wrapped_coordinator), |
2400 | + client_input_regions(client_input_regions), |
2401 | + client_positions(client_positions), |
2402 | + client_depths(client_depths) |
2403 | +{ |
2404 | +} |
2405 | + |
2406 | +mir::frontend::SurfaceId mtf::PlacementApplyingShell::create_surface( |
2407 | + std::shared_ptr<mir::scene::Session> const& session, |
2408 | + mir::scene::SurfaceCreationParameters const& params) |
2409 | +{ |
2410 | + auto creation_parameters = params; |
2411 | + |
2412 | + auto depth = client_depths.find(params.name); |
2413 | + if (depth != client_depths.end()) |
2414 | + creation_parameters.depth = depth->second; |
2415 | + |
2416 | + auto const id = wrapped->create_surface(session, creation_parameters); |
2417 | + auto const surface = session->surface(id); |
2418 | + |
2419 | + auto position= client_positions.find(params.name); |
2420 | + if (position != client_positions.end()) |
2421 | + { |
2422 | + surface->move_to(position->second.top_left); |
2423 | + surface->resize(position->second.size); |
2424 | + } |
2425 | + |
2426 | + auto regions = client_input_regions.find(params.name); |
2427 | + if (regions != client_input_regions.end()) |
2428 | + surface->set_input_region(regions->second); |
2429 | + |
2430 | + return id; |
2431 | +} |
2432 | |
2433 | === modified file 'tests/unit-tests/input/android/test_android_input_dispatcher.cpp' |
2434 | --- tests/unit-tests/input/android/test_android_input_dispatcher.cpp 2015-05-05 18:01:08 +0000 |
2435 | +++ tests/unit-tests/input/android/test_android_input_dispatcher.cpp 2015-05-14 18:12:40 +0000 |
2436 | @@ -173,15 +173,16 @@ |
2437 | std::memset(expected_coords, 0, sizeof(expected_coords)); |
2438 | std::memset(expected_properties, 0, sizeof(expected_properties)); |
2439 | MirEvent event; |
2440 | + std::memset(&event, 0, sizeof(event)); |
2441 | + |
2442 | event.type = mir_event_type_motion; |
2443 | event.motion.pointer_count = 1; |
2444 | event.motion.event_time = std::chrono::nanoseconds(2); |
2445 | event.motion.device_id = 3; |
2446 | event.motion.source_id = 4; |
2447 | event.motion.action = mir_motion_action_scroll; |
2448 | - event.motion.modifiers = mir_input_event_modifier_shift, |
2449 | - event.motion.button_state = |
2450 | - static_cast<MirMotionButton>(mir_motion_button_forward | mir_motion_button_secondary); |
2451 | + event.motion.modifiers = mir_input_event_modifier_shift; |
2452 | + event.motion.buttons = mir_pointer_button_forward | mir_pointer_button_secondary; |
2453 | |
2454 | auto & pointer = event.motion.pointer_coordinates[0]; |
2455 | pointer.id = 1; |
2456 | @@ -215,7 +216,7 @@ |
2457 | event.motion.action, |
2458 | 0, /* flags */ |
2459 | AMETA_SHIFT_ON, |
2460 | - event.motion.button_state, |
2461 | + AMOTION_EVENT_BUTTON_FORWARD | AMOTION_EVENT_BUTTON_SECONDARY, |
2462 | 0, /* edge_flags */ |
2463 | event.motion.pointer_count, |
2464 | expected_properties, |
2465 | |
2466 | === modified file 'tests/unit-tests/input/android/test_android_input_lexicon.cpp' |
2467 | --- tests/unit-tests/input/android/test_android_input_lexicon.cpp 2015-05-05 18:01:08 +0000 |
2468 | +++ tests/unit-tests/input/android/test_android_input_lexicon.cpp 2015-05-14 18:12:40 +0000 |
2469 | @@ -78,7 +78,7 @@ |
2470 | const int32_t flags = 4; |
2471 | const int32_t edge_flags = 5; |
2472 | const int32_t meta_state = 6; |
2473 | - const int32_t button_state = 7; |
2474 | + const int32_t button_state = 0; |
2475 | const float x_offset = 8; |
2476 | const float y_offset = 9; |
2477 | const float x_precision = 10; |
2478 | @@ -134,7 +134,6 @@ |
2479 | |
2480 | auto mir_motion_ev = &mir_ev.motion; |
2481 | |
2482 | - EXPECT_EQ(mir_motion_ev->button_state, button_state); |
2483 | EXPECT_EQ(mir_motion_ev->event_time, event_time); |
2484 | |
2485 | EXPECT_EQ(mir_motion_ev->pointer_count, pointer_count); |
2486 | @@ -170,7 +169,6 @@ |
2487 | const int32_t flags = 4; |
2488 | const int32_t edge_flags = 5; |
2489 | const int32_t meta_state = 6; |
2490 | - const int32_t button_state = 7; |
2491 | const float x_offset = 8; |
2492 | const float y_offset = 9; |
2493 | const float x_precision = 10; |
2494 | @@ -223,7 +221,7 @@ |
2495 | } |
2496 | |
2497 | android_motion_ev->initialize(device_id, source_id, action, flags, |
2498 | - edge_flags, meta_state, button_state, |
2499 | + edge_flags, meta_state, 0, |
2500 | x_offset, y_offset, x_precision, y_precision, |
2501 | down_time, event_time, pointer_count, |
2502 | pointer_properties, pointer_coords); |
2503 | @@ -241,7 +239,6 @@ |
2504 | |
2505 | auto mir_motion_ev = &mir_ev.motion; |
2506 | |
2507 | - EXPECT_EQ(mir_motion_ev->button_state, button_state); |
2508 | EXPECT_EQ(mir_motion_ev->event_time, event_time); |
2509 | EXPECT_EQ(mir_motion_ev->pointer_count, pointer_count); |
2510 | |
2511 | |
2512 | === modified file 'tests/unit-tests/input/android/test_input_translator.cpp' |
2513 | --- tests/unit-tests/input/android/test_input_translator.cpp 2015-05-07 19:43:49 +0000 |
2514 | +++ tests/unit-tests/input/android/test_input_translator.cpp 2015-05-14 18:12:40 +0000 |
2515 | @@ -266,8 +266,7 @@ |
2516 | expected.motion.source_id = 4; |
2517 | expected.motion.action = mir_motion_action_scroll; |
2518 | expected.motion.modifiers = 6; |
2519 | - expected.motion.button_state = |
2520 | - static_cast<MirMotionButton>(mir_motion_button_forward | mir_motion_button_secondary); |
2521 | + expected.motion.buttons = mir_pointer_button_forward | mir_pointer_button_secondary; |
2522 | |
2523 | auto & pointer = expected.motion.pointer_coordinates[0]; |
2524 | pointer.id = 1; |
2525 | @@ -303,7 +302,7 @@ |
2526 | expected.motion.action, |
2527 | 0, /* flags */ |
2528 | expected.motion.modifiers, |
2529 | - expected.motion.button_state, |
2530 | + AMOTION_EVENT_BUTTON_FORWARD | AMOTION_EVENT_BUTTON_SECONDARY, |
2531 | 0, /* edge flags */ |
2532 | expected.motion.pointer_count, |
2533 | properties, |
2534 | |
2535 | === modified file 'tests/unit-tests/input/test_default_input_device_hub.cpp' |
2536 | --- tests/unit-tests/input/test_default_input_device_hub.cpp 2015-05-07 20:41:25 +0000 |
2537 | +++ tests/unit-tests/input/test_default_input_device_hub.cpp 2015-05-14 18:12:40 +0000 |
2538 | @@ -31,6 +31,7 @@ |
2539 | #include "mir/dispatch/multiplexing_dispatchable.h" |
2540 | #include "mir/dispatch/action_queue.h" |
2541 | #include "mir/events/event_builders.h" |
2542 | +#include "mir/input/cursor_listener.h" |
2543 | |
2544 | #include <gmock/gmock.h> |
2545 | #include <gtest/gtest.h> |
2546 | @@ -73,6 +74,13 @@ |
2547 | MOCK_METHOD0(changes_complete, void()); |
2548 | }; |
2549 | |
2550 | +struct MockCursorListener : public mi::CursorListener |
2551 | +{ |
2552 | + MOCK_METHOD2(cursor_moved_to, void(float, float)); |
2553 | + |
2554 | + ~MockCursorListener() noexcept {} |
2555 | +}; |
2556 | + |
2557 | struct MockInputDevice : public mi::InputDevice |
2558 | { |
2559 | mir::dispatch::ActionQueue queue; |
2560 | @@ -90,11 +98,12 @@ |
2561 | mtd::TriggeredMainLoop observer_loop; |
2562 | Nice<mtd::MockInputDispatcher> mock_dispatcher; |
2563 | Nice<mtd::MockInputRegion> mock_region; |
2564 | + Nice<MockCursorListener> mock_cursor_listener; |
2565 | Nice<MockTouchVisualizer> mock_visualizer; |
2566 | mir::dispatch::MultiplexingDispatchable multiplexer; |
2567 | mi::DefaultInputDeviceHub hub{mt::fake_shared(mock_dispatcher), mt::fake_shared(multiplexer), |
2568 | mt::fake_shared(observer_loop), mt::fake_shared(mock_visualizer), |
2569 | - mt::fake_shared(mock_region)}; |
2570 | + mt::fake_shared(mock_cursor_listener), mt::fake_shared(mock_region)}; |
2571 | Nice<MockInputDeviceObserver> mock_observer; |
2572 | Nice<MockInputDevice> device; |
2573 | Nice<MockInputDevice> another_device; |
2574 | @@ -352,3 +361,21 @@ |
2575 | EXPECT_THAT(pos1, Eq(confined_pos)); |
2576 | EXPECT_THAT(pos2, Eq(confined_pos)); |
2577 | } |
2578 | + |
2579 | +TEST_F(InputDeviceHubTest, forwards_pointer_updates_to_cursor_listener) |
2580 | +{ |
2581 | + using namespace ::testing; |
2582 | + |
2583 | + auto x = 12.2f, y = 14.3f; |
2584 | + auto event = mir::events::make_event(0, std::chrono::nanoseconds(0), |
2585 | + mir_input_event_modifier_none, mir_pointer_action_motion, 0, |
2586 | + x, y, 0.0f, 0.0f); |
2587 | + |
2588 | + EXPECT_CALL(mock_cursor_listener, cursor_moved_to(x, y)).Times(1); |
2589 | + |
2590 | + mi::InputSink* sink; |
2591 | + capture_input_sink(device, sink); |
2592 | + hub.add_device(mt::fake_shared(device)); |
2593 | + |
2594 | + sink->handle_input(*event); |
2595 | +} |
2596 | |
2597 | === modified file 'tests/unit-tests/input/test_event_builders.cpp' |
2598 | --- tests/unit-tests/input/test_event_builders.cpp 2015-05-08 20:54:52 +0000 |
2599 | +++ tests/unit-tests/input/test_event_builders.cpp 2015-05-14 18:12:40 +0000 |
2600 | @@ -99,8 +99,7 @@ |
2601 | TEST_F(InputEventBuilder, makes_valid_pointer_event) |
2602 | { |
2603 | MirPointerAction action = mir_pointer_action_enter; |
2604 | - std::vector<MirPointerButton> depressed_buttons = |
2605 | - {mir_pointer_button_back, mir_pointer_button_tertiary}; |
2606 | + auto depressed_buttons = mir_pointer_button_back | mir_pointer_button_tertiary; |
2607 | float x_axis_value = 3.9, y_axis_value = 7.4, hscroll_value = .9, vscroll_value = .3; |
2608 | auto ev = mev::make_event(device_id, timestamp, modifiers, |
2609 | action, depressed_buttons, x_axis_value, y_axis_value, hscroll_value, vscroll_value); |
2610 | @@ -162,11 +161,10 @@ |
2611 | |
2612 | TEST_F(InputEventBuilder, map_to_hover_if_no_button_pressed) |
2613 | { |
2614 | - std::vector<MirPointerButton> no_pressed_buttons; |
2615 | float x_axis_value = 3.9, y_axis_value = 7.4, hscroll_value = .9, vscroll_value = .3; |
2616 | MirPointerAction action = mir_pointer_action_motion; |
2617 | auto ev = mev::make_event(device_id, timestamp, modifiers, |
2618 | - action, no_pressed_buttons, x_axis_value, y_axis_value, hscroll_value, vscroll_value); |
2619 | + action, 0, x_axis_value, y_axis_value, hscroll_value, vscroll_value); |
2620 | auto e = ev.get(); |
2621 | |
2622 | auto ie = mir_event_get_input_event(e); |
2623 | |
2624 | === modified file 'tests/unit-tests/input/test_input_event.cpp' |
2625 | --- tests/unit-tests/input/test_input_event.cpp 2015-05-05 18:01:08 +0000 |
2626 | +++ tests/unit-tests/input/test_input_event.cpp 2015-05-14 18:12:40 +0000 |
2627 | @@ -61,15 +61,21 @@ |
2628 | MirEvent a_key_ev() |
2629 | { |
2630 | MirEvent key_ev; |
2631 | + memset(&key_ev, 0, sizeof(key_ev)); |
2632 | + |
2633 | key_ev.type = mir_event_type_key; |
2634 | + |
2635 | return key_ev; |
2636 | } |
2637 | |
2638 | MirEvent a_motion_ev(int device_class = AINPUT_SOURCE_UNKNOWN) |
2639 | { |
2640 | MirEvent motion_ev; |
2641 | + memset(&motion_ev, 0, sizeof(motion_ev)); |
2642 | + |
2643 | motion_ev.type = mir_event_type_motion; |
2644 | motion_ev.motion.source_id = device_class; |
2645 | + |
2646 | return motion_ev; |
2647 | } |
2648 | |
2649 | @@ -350,13 +356,13 @@ |
2650 | { |
2651 | auto old_ev = a_motion_ev(AINPUT_SOURCE_MOUSE); |
2652 | |
2653 | - old_ev.motion.button_state = mir_motion_button_primary; |
2654 | + old_ev.motion.buttons = mir_pointer_button_primary; |
2655 | auto pev = mir_input_event_get_pointer_event(mir_event_get_input_event(&old_ev)); |
2656 | |
2657 | EXPECT_TRUE(mir_pointer_event_button_state(pev, mir_pointer_button_primary)); |
2658 | EXPECT_FALSE(mir_pointer_event_button_state(pev, mir_pointer_button_secondary)); |
2659 | |
2660 | - old_ev.motion.button_state = static_cast<MirMotionButton>(old_ev.motion.button_state | (mir_motion_button_secondary)); |
2661 | + old_ev.motion.buttons |= mir_pointer_button_secondary; |
2662 | |
2663 | EXPECT_TRUE(mir_pointer_event_button_state(pev, mir_pointer_button_primary)); |
2664 | EXPECT_TRUE(mir_pointer_event_button_state(pev, mir_pointer_button_secondary)); |
2665 | |
2666 | === modified file 'tests/unit-tests/scene/test_abstract_shell.cpp' |
2667 | --- tests/unit-tests/scene/test_abstract_shell.cpp 2015-05-11 18:19:27 +0000 |
2668 | +++ tests/unit-tests/scene/test_abstract_shell.cpp 2015-05-14 18:12:40 +0000 |
2669 | @@ -283,7 +283,7 @@ |
2670 | { |
2671 | MirInputEventModifiers const modifiers{mir_input_event_modifier_none}; |
2672 | MirPointerAction const action{mir_pointer_action_button_down}; |
2673 | - std::vector<MirPointerButton> const buttons_pressed{mir_pointer_button_primary}; |
2674 | + auto const buttons_pressed = mir_pointer_button_primary; |
2675 | float const x_axis_value{0.0}; |
2676 | float const y_axis_value{0.0}; |
2677 | float const hscroll_value{0.0}; |
FAILED: Continuous integration, rev:2545 jenkins. qa.ubuntu. com/job/ mir-ci/ 3724/ jenkins. qa.ubuntu. com/job/ mir-android- vivid-i386- build/2323 jenkins. qa.ubuntu. com/job/ mir-clang- vivid-amd64- build/2322/ console jenkins. qa.ubuntu. com/job/ mir-mediumtests -vivid- touch/2271/ console jenkins. qa.ubuntu. com/job/ mir-vivid- amd64-ci/ 1721/console jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- vivid-armhf/ 2271/console
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/mir- ci/3724/ rebuild
http://