Merge lp:~robertcarr/mir/enable-pointer-touch-input into lp:~mir-team/mir/trunk
- enable-pointer-touch-input
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~robertcarr/mir/enable-pointer-touch-input |
Merge into: | lp:~mir-team/mir/trunk |
Prerequisite: | lp:~robertcarr/mir/reflow-input-focus-selection |
Diff against target: |
2660 lines (+1016/-387) 50 files modified
include/server/mir/default_server_configuration.h (+3/-3) include/server/mir/input/input_manager.h (+0/-1) include/server/mir/input/null_input_manager.h (+0/-5) include/server/mir/input/null_input_target_listener.h (+26/-11) include/server/mir/input/surface_target.h (+2/-0) include/server/mir/shell/application_session.h (+4/-1) include/server/mir/shell/input_focus_selector.h (+0/-52) include/server/mir/shell/input_target_listener.h (+59/-0) include/server/mir/shell/session_manager.h (+5/-2) include/server/mir/shell/single_visibility_focus_mechanism.h (+1/-4) include/server/mir/shell/surface.h (+1/-0) include/test/mir_test/event_matchers.h (+64/-0) include/test/mir_test/fake_event_hub_input_configuration.h (+2/-0) include/test/mir_test_doubles/mock_event_filter.h (+0/-32) include/test/mir_test_doubles/mock_input_focus_selector.h (+0/-40) include/test/mir_test_doubles/mock_input_target_listener.h (+49/-0) include/test/mir_test_doubles/stub_input_target_listener.h (+59/-0) include/test/mir_test_doubles/stub_surface_target.h (+4/-0) include/test/mir_test_framework/testing_server_configuration.h (+1/-1) src/server/default_server_configuration.cpp (+8/-8) src/server/display_server.cpp (+1/-1) src/server/input/android/android_dispatcher_controller.cpp (+73/-23) src/server/input/android/android_dispatcher_controller.h (+19/-6) src/server/input/android/android_input_reader_policy.cpp (+3/-0) src/server/input/android/android_input_window_handle.cpp (+8/-2) src/server/input/android/default_android_input_configuration.cpp (+6/-1) src/server/input/android/default_android_input_configuration.h (+2/-0) src/server/input/android/event_filter_dispatcher_policy.cpp (+6/-5) src/server/input/android/event_filter_dispatcher_policy.h (+2/-1) src/server/shell/application_session.cpp (+6/-2) src/server/shell/session_manager.cpp (+27/-10) src/server/shell/single_visibility_focus_mechanism.cpp (+2/-7) src/server/shell/surface.cpp (+12/-0) tests/acceptance-tests/test_client_input.cpp (+145/-35) tests/acceptance-tests/test_focus_selection.cpp (+21/-21) tests/death-tests/test_application_manager_death.cpp (+4/-3) tests/integration-tests/input/android/test_android_input_manager.cpp (+71/-12) tests/integration-tests/input/android/test_fake_event_hub_to_event_filter.cpp (+2/-1) tests/integration-tests/shell/test_session_manager.cpp (+24/-17) tests/mir_test_doubles/fake_event_hub.cpp (+2/-2) tests/mir_test_framework/testing_server_options.cpp (+3/-11) tests/unit-tests/input/android/test_android_dispatcher_controller.cpp (+138/-13) tests/unit-tests/input/android/test_android_input_window_handle.cpp (+11/-0) tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp (+15/-2) tests/unit-tests/shell/test_application_session.cpp (+11/-5) tests/unit-tests/shell/test_registration_order_focus_sequence.cpp (+16/-11) tests/unit-tests/shell/test_session_manager.cpp (+72/-8) tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp (+1/-24) tests/unit-tests/shell/test_surface.cpp (+18/-0) tests/unit-tests/shell/test_the_session_container_implementation.cpp (+7/-4) |
To merge this branch: | bzr merge lp:~robertcarr/mir/enable-pointer-touch-input |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel van Vugt | Needs Information | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+160153@code.launchpad.net |
This proposal supersedes a proposal from 2013-04-22.
This proposal has been superseded by a proposal from 2013-04-23.
Commit message
Enable motion and touch/button events
Description of the change
Enable motion events in the DispatcherPolicy and Window Handle. This branch is largely new acceptance tests! (small changes to event_filter_
Depends on:
~robertcarr/
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:606
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:607
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
1744 +TEST_F(
It's not the test that needs fixing, but the fundamental assumption behind it. Touch and pointer events are never affected by focus. Focus only relates to key events, because key events lack an (x,y).
Because touch and pointer events already have (x,y) they do not relate to focus. Please remove this assumption if it has been made... ?
Alan Griffiths (alan-griffiths) wrote : | # |
Looks mostly sensible. I'm not convinced by the name "InputTargetLis
I'll comment further after a closer look.
Preview Diff
1 | === modified file 'include/server/mir/default_server_configuration.h' |
2 | --- include/server/mir/default_server_configuration.h 2013-04-19 15:59:41 +0000 |
3 | +++ include/server/mir/default_server_configuration.h 2013-04-22 21:32:25 +0000 |
4 | @@ -50,7 +50,7 @@ |
5 | { |
6 | class SurfaceFactory; |
7 | class SurfaceBuilder; |
8 | -class InputFocusSelector; |
9 | +class InputTargetListener; |
10 | class SessionContainer; |
11 | class FocusSetter; |
12 | class FocusSequence; |
13 | @@ -156,7 +156,6 @@ |
14 | /** @name shell configuration - dependencies |
15 | * dependencies of shell on the rest of the Mir |
16 | * @{ */ |
17 | - virtual std::shared_ptr<shell::InputFocusSelector> the_input_focus_selector(); |
18 | virtual std::shared_ptr<shell::SurfaceBuilder> the_surface_builder(); |
19 | /** @} */ |
20 | |
21 | @@ -178,6 +177,7 @@ |
22 | * @{ */ |
23 | virtual std::shared_ptr<input::android::InputConfiguration> the_input_configuration(); |
24 | virtual std::initializer_list<std::shared_ptr<input::EventFilter> const> the_event_filters(); |
25 | + virtual std::shared_ptr<shell::InputTargetListener> the_input_target_listener(); |
26 | /** @} */ |
27 | |
28 | /** @name logging configuration - customization |
29 | @@ -197,7 +197,7 @@ |
30 | CachedPtr<frontend::Shell> session_manager; |
31 | std::shared_ptr<input::android::InputConfiguration> input_configuration; |
32 | CachedPtr<input::InputManager> input_manager; |
33 | - CachedPtr<shell::InputFocusSelector> input_focus_selector; |
34 | + CachedPtr<shell::InputTargetListener> input_target_listener; |
35 | CachedPtr<graphics::Platform> graphics_platform; |
36 | CachedPtr<graphics::BufferInitializer> buffer_initializer; |
37 | CachedPtr<compositor::GraphicBufferAllocator> buffer_allocator; |
38 | |
39 | === modified file 'include/server/mir/input/input_manager.h' |
40 | --- include/server/mir/input/input_manager.h 2013-04-16 09:08:29 +0000 |
41 | +++ include/server/mir/input/input_manager.h 2013-04-22 21:32:25 +0000 |
42 | @@ -21,7 +21,6 @@ |
43 | #define MIR_INPUT_INPUT_MANAGER_H_ |
44 | |
45 | #include "mir/input/input_channel_factory.h" |
46 | -#include "mir/shell/input_focus_selector.h" |
47 | |
48 | #include <memory> |
49 | |
50 | |
51 | === modified file 'include/server/mir/input/null_input_manager.h' |
52 | --- include/server/mir/input/null_input_manager.h 2013-04-16 09:08:29 +0000 |
53 | +++ include/server/mir/input/null_input_manager.h 2013-04-22 21:32:25 +0000 |
54 | @@ -40,11 +40,6 @@ |
55 | return std::shared_ptr<InputChannel>(); |
56 | } |
57 | |
58 | - virtual void set_input_focus_to(std::shared_ptr<input::SessionTarget> const& /* session */, |
59 | - std::shared_ptr<input::SurfaceTarget> const& /* surface */) |
60 | - { |
61 | - } |
62 | - |
63 | protected: |
64 | NullInputManager(const NullInputManager&) = delete; |
65 | NullInputManager& operator=(const NullInputManager&) = delete; |
66 | |
67 | === renamed file 'include/server/mir/input/null_input_focus_selector.h' => 'include/server/mir/input/null_input_target_listener.h' |
68 | --- include/server/mir/input/null_input_focus_selector.h 2013-04-17 02:04:35 +0000 |
69 | +++ include/server/mir/input/null_input_target_listener.h 2013-04-22 21:32:25 +0000 |
70 | @@ -16,33 +16,48 @@ |
71 | * Authored by: Robert Carr <robert.carr@canonical.com> |
72 | */ |
73 | |
74 | -#ifndef MIR_INPUT_NULL_INPUT_FOCUS_SELECTOR_H_ |
75 | -#define MIR_INPUT_NULL_INPUT_FOCUS_SELECTOR_H_ |
76 | +#ifndef MIR_INPUT_NULL_INPUT_TARGET_LISTENER_H_ |
77 | +#define MIR_INPUT_NULL_INPUT_TARGET_LISTENER_H_ |
78 | |
79 | -#include "mir/shell/input_focus_selector.h" |
80 | +#include "mir/shell/input_target_listener.h" |
81 | |
82 | namespace mir |
83 | { |
84 | namespace input |
85 | { |
86 | |
87 | -class NullInputFocusSelector : public shell::InputFocusSelector |
88 | +class NullInputTargetListener : public shell::InputTargetListener |
89 | { |
90 | public: |
91 | - NullInputFocusSelector() {}; |
92 | - virtual ~NullInputFocusSelector() {} |
93 | + NullInputTargetListener() {}; |
94 | + virtual ~NullInputTargetListener() noexcept(true) {} |
95 | |
96 | - virtual void set_input_focus_to(std::shared_ptr<input::SessionTarget> const&, |
97 | - std::shared_ptr<input::SurfaceTarget> const&) |
98 | + virtual void input_application_opened(std::shared_ptr<input::SessionTarget> const&) |
99 | + { |
100 | + } |
101 | + virtual void input_application_closed(std::shared_ptr<input::SessionTarget> const&) |
102 | + { |
103 | + } |
104 | + virtual void input_surface_opened(std::shared_ptr<input::SessionTarget> const&, |
105 | + std::shared_ptr<input::SurfaceTarget> const&) |
106 | + { |
107 | + } |
108 | + virtual void input_surface_closed(std::shared_ptr<input::SurfaceTarget> const&) |
109 | + { |
110 | + } |
111 | + virtual void focus_changed(std::shared_ptr<input::SurfaceTarget> const&) |
112 | + { |
113 | + } |
114 | + virtual void focus_cleared() |
115 | { |
116 | } |
117 | |
118 | protected: |
119 | - NullInputFocusSelector(const NullInputFocusSelector&) = delete; |
120 | - NullInputFocusSelector& operator=(const NullInputFocusSelector&) = delete; |
121 | + NullInputTargetListener(const NullInputTargetListener&) = delete; |
122 | + NullInputTargetListener& operator=(const NullInputTargetListener&) = delete; |
123 | }; |
124 | |
125 | } |
126 | } |
127 | |
128 | -#endif // MIR_INPUT_NULL_INPUT_FOCUS_SELECTOR_H_ |
129 | +#endif // MIR_INPUT_NULL_INPUT_TARGET_LISTENER_H_ |
130 | |
131 | === modified file 'include/server/mir/input/surface_target.h' |
132 | --- include/server/mir/input/surface_target.h 2013-04-16 09:08:29 +0000 |
133 | +++ include/server/mir/input/surface_target.h 2013-04-22 21:32:25 +0000 |
134 | @@ -20,6 +20,7 @@ |
135 | #define MIR_INPUT_SURFACE_TARGET_H_ |
136 | |
137 | #include "mir/geometry/size.h" |
138 | +#include "mir/geometry/point.h" |
139 | |
140 | #include <string> |
141 | |
142 | @@ -33,6 +34,7 @@ |
143 | public: |
144 | virtual ~SurfaceTarget() {} |
145 | |
146 | + virtual geometry::Point top_left() const = 0; |
147 | virtual geometry::Size size() const = 0; |
148 | virtual std::string name() const = 0; |
149 | |
150 | |
151 | === modified file 'include/server/mir/shell/application_session.h' |
152 | --- include/server/mir/shell/application_session.h 2013-04-16 17:42:26 +0000 |
153 | +++ include/server/mir/shell/application_session.h 2013-04-22 21:32:25 +0000 |
154 | @@ -30,11 +30,13 @@ |
155 | { |
156 | class SurfaceFactory; |
157 | class Surface; |
158 | +class InputTargetListener; |
159 | |
160 | class ApplicationSession : public Session |
161 | { |
162 | public: |
163 | - explicit ApplicationSession(std::shared_ptr<SurfaceFactory> const& surface_factory, std::string const& session_name); |
164 | + explicit ApplicationSession(std::shared_ptr<SurfaceFactory> const& surface_factory, |
165 | + std::shared_ptr<InputTargetListener> const& input_target_listener, std::string const& session_name); |
166 | ~ApplicationSession(); |
167 | |
168 | frontend::SurfaceId create_surface(frontend::SurfaceCreationParameters const& params); |
169 | @@ -58,6 +60,7 @@ |
170 | |
171 | private: |
172 | std::shared_ptr<SurfaceFactory> const surface_factory; |
173 | + std::shared_ptr<InputTargetListener> const input_target_listener; |
174 | std::string const session_name; |
175 | |
176 | frontend::SurfaceId next_id(); |
177 | |
178 | === removed file 'include/server/mir/shell/input_focus_selector.h' |
179 | --- include/server/mir/shell/input_focus_selector.h 2013-04-16 09:08:29 +0000 |
180 | +++ include/server/mir/shell/input_focus_selector.h 1970-01-01 00:00:00 +0000 |
181 | @@ -1,52 +0,0 @@ |
182 | -/* |
183 | - * Copyright © 2013 Canonical Ltd. |
184 | - * |
185 | - * This program is free software: you can redistribute it and/or modify it |
186 | - * under the terms of the GNU General Public License version 3, |
187 | - * as published by the Free Software Foundation. |
188 | - * |
189 | - * This program is distributed in the hope that it will be useful, |
190 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
191 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
192 | - * GNU General Public License for more details. |
193 | - * |
194 | - * You should have received a copy of the GNU General Public License |
195 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
196 | - * |
197 | - * Authored by: Robert Carr <robert.carr@canonical.com> |
198 | - */ |
199 | - |
200 | -#ifndef MIR_SHELL_INPUT_FOCUS_SELECTOR_H_ |
201 | -#define MIR_SHELL_INPUT_FOCUS_SELECTOR_H_ |
202 | - |
203 | -#include <memory> |
204 | - |
205 | -namespace mir |
206 | -{ |
207 | -namespace input |
208 | -{ |
209 | -class SessionTarget; |
210 | -class SurfaceTarget; |
211 | -} |
212 | - |
213 | -namespace shell |
214 | -{ |
215 | - |
216 | -class InputFocusSelector |
217 | -{ |
218 | -public: |
219 | - virtual ~InputFocusSelector() {} |
220 | - |
221 | - virtual void set_input_focus_to(std::shared_ptr<input::SessionTarget> const& focus_application, |
222 | - std::shared_ptr<input::SurfaceTarget> const& focus_surface) = 0; |
223 | - |
224 | -protected: |
225 | - InputFocusSelector() = default; |
226 | - InputFocusSelector(InputFocusSelector const&) = delete; |
227 | - InputFocusSelector& operator=(InputFocusSelector const&) = delete; |
228 | -}; |
229 | - |
230 | -} |
231 | -} // namespace mir |
232 | - |
233 | -#endif // MIR_SHELL_INPUT_FOCUS_SELECTOR_H_ |
234 | |
235 | === added file 'include/server/mir/shell/input_target_listener.h' |
236 | --- include/server/mir/shell/input_target_listener.h 1970-01-01 00:00:00 +0000 |
237 | +++ include/server/mir/shell/input_target_listener.h 2013-04-22 21:32:25 +0000 |
238 | @@ -0,0 +1,59 @@ |
239 | +/* |
240 | + * Copyright © 2013 Canonical Ltd. |
241 | + * |
242 | + * This program is free software: you can redistribute it and/or modify it |
243 | + * under the terms of the GNU General Public License version 3, |
244 | + * as published by the Free Software Foundation. |
245 | + * |
246 | + * This program is distributed in the hope that it will be useful, |
247 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
248 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
249 | + * GNU General Public License for more details. |
250 | + * |
251 | + * You should have received a copy of the GNU General Public License |
252 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
253 | + * |
254 | + * Authored by: Robert Carr <robert.carr@canonical.com> |
255 | + */ |
256 | + |
257 | +#ifndef MIR_SHELL_INPUT_TARGET_LISTENER_H_ |
258 | +#define MIR_SHELL_INPUT_TARGET_LISTENER_H_ |
259 | + |
260 | +#include <memory> |
261 | + |
262 | +namespace mir |
263 | +{ |
264 | +namespace input |
265 | +{ |
266 | +class SessionTarget; |
267 | +class SurfaceTarget; |
268 | +} |
269 | + |
270 | +namespace shell |
271 | +{ |
272 | + |
273 | +class InputTargetListener |
274 | +{ |
275 | +public: |
276 | + virtual ~InputTargetListener() = default; |
277 | + |
278 | + virtual void input_application_opened(std::shared_ptr<input::SessionTarget> const& application) = 0; |
279 | + virtual void input_application_closed(std::shared_ptr<input::SessionTarget> const& application) = 0; |
280 | + |
281 | + virtual void input_surface_opened(std::shared_ptr<input::SessionTarget> const& application, |
282 | + std::shared_ptr<input::SurfaceTarget> const& opened_surface) = 0; |
283 | + virtual void input_surface_closed(std::shared_ptr<input::SurfaceTarget> const& closed_surface) = 0; |
284 | + |
285 | + virtual void focus_changed(std::shared_ptr<input::SurfaceTarget> const& focus_surface) = 0; |
286 | + virtual void focus_cleared() = 0; |
287 | + |
288 | +protected: |
289 | + InputTargetListener() = default; |
290 | + InputTargetListener(InputTargetListener const&) = delete; |
291 | + InputTargetListener& operator=(InputTargetListener const&) = delete; |
292 | +}; |
293 | + |
294 | +} |
295 | +} // namespace mir |
296 | + |
297 | +#endif // MIR_SHELL_INPUT_TARGET_LISTENER_H_ |
298 | |
299 | === modified file 'include/server/mir/shell/session_manager.h' |
300 | --- include/server/mir/shell/session_manager.h 2013-04-19 09:15:31 +0000 |
301 | +++ include/server/mir/shell/session_manager.h 2013-04-22 21:32:25 +0000 |
302 | @@ -40,15 +40,17 @@ |
303 | class SessionContainer; |
304 | class FocusSequence; |
305 | class FocusSetter; |
306 | +class InputTargetListener; |
307 | class Session; |
308 | |
309 | class SessionManager : public frontend::Shell |
310 | { |
311 | public: |
312 | explicit SessionManager(std::shared_ptr<SurfaceFactory> const& surface_factory, |
313 | - std::shared_ptr<SessionContainer> const& session_container, |
314 | + std::shared_ptr<SessionContainer> const& app_container, |
315 | std::shared_ptr<FocusSequence> const& focus_sequence, |
316 | - std::shared_ptr<FocusSetter> const& focus_setter); |
317 | + std::shared_ptr<FocusSetter> const& focus_setter, |
318 | + std::shared_ptr<InputTargetListener> const& input_target_listener); |
319 | virtual ~SessionManager(); |
320 | |
321 | virtual std::shared_ptr<frontend::Session> open_session(std::string const& name); |
322 | @@ -71,6 +73,7 @@ |
323 | std::shared_ptr<SessionContainer> const app_container; |
324 | std::shared_ptr<FocusSequence> const focus_sequence; |
325 | std::shared_ptr<FocusSetter> const focus_setter; |
326 | + std::shared_ptr<InputTargetListener> const input_target_listener; |
327 | |
328 | std::mutex mutex; |
329 | std::weak_ptr<Session> focus_application; |
330 | |
331 | === modified file 'include/server/mir/shell/single_visibility_focus_mechanism.h' |
332 | --- include/server/mir/shell/single_visibility_focus_mechanism.h 2013-04-16 09:08:29 +0000 |
333 | +++ include/server/mir/shell/single_visibility_focus_mechanism.h 2013-04-22 21:32:25 +0000 |
334 | @@ -28,13 +28,11 @@ |
335 | namespace shell |
336 | { |
337 | class SessionContainer; |
338 | -class InputFocusSelector; |
339 | |
340 | class SingleVisibilityFocusMechanism : public FocusSetter |
341 | { |
342 | public: |
343 | - explicit SingleVisibilityFocusMechanism(std::shared_ptr<SessionContainer> const& app_container, |
344 | - std::shared_ptr<shell::InputFocusSelector> const& input_selector); |
345 | + explicit SingleVisibilityFocusMechanism(std::shared_ptr<SessionContainer> const& app_container); |
346 | virtual ~SingleVisibilityFocusMechanism() {} |
347 | |
348 | void set_focus_to(std::shared_ptr<shell::Session> const& new_focus); |
349 | @@ -44,7 +42,6 @@ |
350 | SingleVisibilityFocusMechanism& operator=(const SingleVisibilityFocusMechanism&) = delete; |
351 | private: |
352 | std::shared_ptr<SessionContainer> const app_container; |
353 | - std::shared_ptr<shell::InputFocusSelector> const input_selector; |
354 | }; |
355 | |
356 | } |
357 | |
358 | === modified file 'include/server/mir/shell/surface.h' |
359 | --- include/server/mir/shell/surface.h 2013-04-16 17:42:26 +0000 |
360 | +++ include/server/mir/shell/surface.h 2013-04-22 21:32:25 +0000 |
361 | @@ -63,6 +63,7 @@ |
362 | virtual std::string name() const; |
363 | |
364 | virtual geometry::Size size() const; |
365 | + virtual geometry::Point top_left() const; |
366 | |
367 | virtual geometry::PixelFormat pixel_format() const; |
368 | |
369 | |
370 | === added file 'include/test/mir_test/event_matchers.h' |
371 | --- include/test/mir_test/event_matchers.h 1970-01-01 00:00:00 +0000 |
372 | +++ include/test/mir_test/event_matchers.h 2013-04-22 21:32:25 +0000 |
373 | @@ -0,0 +1,64 @@ |
374 | +/* |
375 | + * Copyright © 2013 Canonical Ltd. |
376 | + * |
377 | + * This program is free software: you can redistribute it and/or modify it |
378 | + * under the terms of the GNU General Public License version 3, |
379 | + * as published by the Free Software Foundation. |
380 | + * |
381 | + * This program is distributed in the hope that it will be useful, |
382 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
383 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
384 | + * GNU General Public License for more details. |
385 | + * |
386 | + * You should have received a copy of the GNU General Public License |
387 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
388 | + * |
389 | + * Authored by: Robert Carr <robert.carr@canonical.com> |
390 | + */ |
391 | + |
392 | +#ifndef MIR_TEST_EVENT_MATCHERS_H_ |
393 | +#define MIR_TEST_EVENT_MATCHERS_H_ |
394 | + |
395 | +#include <androidfw/Input.h> |
396 | + |
397 | +#include <gmock/gmock.h> |
398 | + |
399 | +namespace mir |
400 | +{ |
401 | +namespace test |
402 | +{ |
403 | + |
404 | +MATCHER_P(IsKeyEventWithKey, key, "") |
405 | +{ |
406 | + if (arg.type != mir_event_type_key) |
407 | + return false; |
408 | + |
409 | + return arg.key.key_code == key; |
410 | +} |
411 | +MATCHER(KeyDownEvent, "") |
412 | +{ |
413 | + if (arg.type != mir_event_type_key) |
414 | + return false; |
415 | + |
416 | + return arg.key.action == AKEY_EVENT_ACTION_DOWN; |
417 | +} |
418 | +MATCHER(ButtonDownEvent, "") |
419 | +{ |
420 | + if (arg.type != mir_event_type_motion) |
421 | + return false; |
422 | + if (arg.motion.button_state == 0) |
423 | + return false; |
424 | + return arg.motion.action == AMOTION_EVENT_ACTION_DOWN; |
425 | +} |
426 | +MATCHER_P2(MotionEvent, dx, dy, "") |
427 | +{ |
428 | + if (arg.type != mir_event_type_motion) |
429 | + return false; |
430 | + auto coords = &arg.motion.pointer_coordinates[0]; |
431 | + return (coords->x == dx) && (coords->y == dy); |
432 | +} |
433 | + |
434 | +} |
435 | +} // namespace mir |
436 | + |
437 | +#endif // MIR_TEST_EVENT_MATCHERS_H_ |
438 | |
439 | === modified file 'include/test/mir_test/fake_event_hub_input_configuration.h' |
440 | --- include/test/mir_test/fake_event_hub_input_configuration.h 2013-04-16 09:08:29 +0000 |
441 | +++ include/test/mir_test/fake_event_hub_input_configuration.h 2013-04-22 21:32:25 +0000 |
442 | @@ -63,6 +63,8 @@ |
443 | |
444 | droidinput::sp<droidinput::EventHubInterface> the_event_hub(); |
445 | input::android::FakeEventHub* the_fake_event_hub(); |
446 | + |
447 | + bool is_key_repeat_enabled() override { return false; } |
448 | |
449 | |
450 | protected: |
451 | |
452 | === modified file 'include/test/mir_test_doubles/mock_event_filter.h' |
453 | --- include/test/mir_test_doubles/mock_event_filter.h 2013-04-16 09:08:29 +0000 |
454 | +++ include/test/mir_test_doubles/mock_event_filter.h 2013-04-22 21:32:25 +0000 |
455 | @@ -21,8 +21,6 @@ |
456 | |
457 | #include "mir/input/event_filter.h" |
458 | |
459 | -#include <androidfw/Input.h> |
460 | - |
461 | #include <gmock/gmock.h> |
462 | |
463 | namespace mir |
464 | @@ -36,36 +34,6 @@ |
465 | MOCK_METHOD1(handles, bool(const MirEvent&)); |
466 | }; |
467 | } |
468 | - |
469 | -MATCHER_P(IsKeyEventWithKey, key, "") |
470 | -{ |
471 | - if (arg.type != mir_event_type_key) |
472 | - return false; |
473 | - |
474 | - return arg.key.key_code == key; |
475 | -} |
476 | -MATCHER(KeyDownEvent, "") |
477 | -{ |
478 | - if (arg.type != mir_event_type_key) |
479 | - return false; |
480 | - |
481 | - return arg.key.action == AKEY_EVENT_ACTION_DOWN; |
482 | -} |
483 | -MATCHER(ButtonDownEvent, "") |
484 | -{ |
485 | - if (arg.type != mir_event_type_motion) |
486 | - return false; |
487 | - if (arg.motion.button_state == 0) |
488 | - return false; |
489 | - return arg.motion.action == AKEY_EVENT_ACTION_DOWN; |
490 | -} |
491 | -MATCHER_P2(MotionEvent, dx, dy, "") |
492 | -{ |
493 | - if (arg.type != mir_event_type_motion) |
494 | - return false; |
495 | - auto coords = &arg.motion.pointer_coordinates[0]; |
496 | - return (coords->x == dx) && (coords->y == dy); |
497 | -} |
498 | } |
499 | } |
500 | |
501 | |
502 | === removed file 'include/test/mir_test_doubles/mock_input_focus_selector.h' |
503 | --- include/test/mir_test_doubles/mock_input_focus_selector.h 2013-04-16 09:08:29 +0000 |
504 | +++ include/test/mir_test_doubles/mock_input_focus_selector.h 1970-01-01 00:00:00 +0000 |
505 | @@ -1,40 +0,0 @@ |
506 | -/* |
507 | - * Copyright © 2013 Canonical Ltd. |
508 | - * |
509 | - * This program is free software: you can redistribute it and/or modify it |
510 | - * under the terms of the GNU General Public License version 3, |
511 | - * as published by the Free Software Foundation. |
512 | - * |
513 | - * This program is distributed in the hope that it will be useful, |
514 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
515 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
516 | - * GNU General Public License for more details. |
517 | - * |
518 | - * You should have received a copy of the GNU General Public License |
519 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
520 | - * |
521 | - * Authored by: Robert Carr <robert.carr@canonical.com> |
522 | - */ |
523 | - |
524 | -#ifndef MIR_TEST_DOUBLES_MOCK_INPUT_FOCUS_SELECTOR_H_ |
525 | -#define MIR_TEST_DOUBLES_MOCK_INPUT_FOCUS_SELECTOR_H_ |
526 | - |
527 | -#include "mir/shell/input_focus_selector.h" |
528 | - |
529 | -namespace mir |
530 | -{ |
531 | -namespace test |
532 | -{ |
533 | -namespace doubles |
534 | -{ |
535 | - |
536 | -struct MockInputFocusSelector : public shell::InputFocusSelector |
537 | -{ |
538 | - MOCK_METHOD2(set_input_focus_to, void(std::shared_ptr<input::SessionTarget> const&, std::shared_ptr<input::SurfaceTarget> const&)); |
539 | -}; |
540 | - |
541 | -} |
542 | -} |
543 | -} // namespace mir |
544 | - |
545 | -#endif // MIR_TEST_DOUBLES_MOCK_INPUT_FOCUS_SELECTOR_H_ |
546 | |
547 | === added file 'include/test/mir_test_doubles/mock_input_target_listener.h' |
548 | --- include/test/mir_test_doubles/mock_input_target_listener.h 1970-01-01 00:00:00 +0000 |
549 | +++ include/test/mir_test_doubles/mock_input_target_listener.h 2013-04-22 21:32:25 +0000 |
550 | @@ -0,0 +1,49 @@ |
551 | +/* |
552 | + * Copyright © 2013 Canonical Ltd. |
553 | + * |
554 | + * This program is free software: you can redistribute it and/or modify it |
555 | + * under the terms of the GNU General Public License version 3, |
556 | + * as published by the Free Software Foundation. |
557 | + * |
558 | + * This program is distributed in the hope that it will be useful, |
559 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
560 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
561 | + * GNU General Public License for more details. |
562 | + * |
563 | + * You should have received a copy of the GNU General Public License |
564 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
565 | + * |
566 | + * Authored by: Robert Carr <robert.carr@canonical.com> |
567 | + */ |
568 | + |
569 | +#ifndef MIR_TEST_DOUBLES_MOCK_INPUT_TARGET_LISTENER_H_ |
570 | +#define MIR_TEST_DOUBLES_MOCK_INPUT_TARGET_LISTENER_H_ |
571 | + |
572 | +#include "mir/shell/input_target_listener.h" |
573 | + |
574 | +#include <gmock/gmock.h> |
575 | + |
576 | +namespace mir |
577 | +{ |
578 | +namespace test |
579 | +{ |
580 | +namespace doubles |
581 | +{ |
582 | + |
583 | +struct MockInputTargetListener : public shell::InputTargetListener |
584 | +{ |
585 | + virtual ~MockInputTargetListener() noexcept(true) {} |
586 | + MOCK_METHOD1(input_application_opened, void(std::shared_ptr<input::SessionTarget> const& application)); |
587 | + MOCK_METHOD1(input_application_closed, void(std::shared_ptr<input::SessionTarget> const& application)); |
588 | + MOCK_METHOD2(input_surface_opened, void(std::shared_ptr<input::SessionTarget> const& application, |
589 | + std::shared_ptr<input::SurfaceTarget> const& opened_surface)); |
590 | + MOCK_METHOD1(input_surface_closed, void(std::shared_ptr<input::SurfaceTarget> const& closed_surface)); |
591 | + MOCK_METHOD1(focus_changed, void(std::shared_ptr<input::SurfaceTarget> const& focus_surface)); |
592 | + MOCK_METHOD0(focus_cleared, void()); |
593 | +}; |
594 | + |
595 | +} |
596 | +} |
597 | +} // namespace mir |
598 | + |
599 | +#endif // MIR_TEST_DOUBLES_MOCK_INPUT_TARGET_LISTENER_H_ |
600 | |
601 | === added file 'include/test/mir_test_doubles/stub_input_target_listener.h' |
602 | --- include/test/mir_test_doubles/stub_input_target_listener.h 1970-01-01 00:00:00 +0000 |
603 | +++ include/test/mir_test_doubles/stub_input_target_listener.h 2013-04-22 21:32:25 +0000 |
604 | @@ -0,0 +1,59 @@ |
605 | +/* |
606 | + * Copyright © 2013 Canonical Ltd. |
607 | + * |
608 | + * This program is free software: you can redistribute it and/or modify it |
609 | + * under the terms of the GNU General Public License version 3, |
610 | + * as published by the Free Software Foundation. |
611 | + * |
612 | + * This program is distributed in the hope that it will be useful, |
613 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
614 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
615 | + * GNU General Public License for more details. |
616 | + * |
617 | + * You should have received a copy of the GNU General Public License |
618 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
619 | + * |
620 | + * Authored by: Robert Carr <robert.carr@canonical.com> |
621 | + */ |
622 | + |
623 | +#ifndef MIR_TEST_DOUBLES_STUB_INPUT_LISTENER_H_ |
624 | +#define MIR_TEST_DOUBLES_STUB_INPUT_LISTENER_H_ |
625 | + |
626 | +#include "mir/shell/input_target_listener.h" |
627 | + |
628 | +namespace mir |
629 | +{ |
630 | +namespace test |
631 | +{ |
632 | +namespace doubles |
633 | +{ |
634 | + |
635 | +struct StubInputTargetListener : public shell::InputTargetListener |
636 | +{ |
637 | + void input_application_opened(std::shared_ptr<input::SessionTarget> const&) |
638 | + { |
639 | + } |
640 | + void input_application_closed(std::shared_ptr<input::SessionTarget> const&) |
641 | + { |
642 | + } |
643 | + void input_surface_opened(std::shared_ptr<input::SessionTarget> const&, |
644 | + std::shared_ptr<input::SurfaceTarget> const&) |
645 | + { |
646 | + } |
647 | + void input_surface_closed(std::shared_ptr<input::SurfaceTarget> const&) |
648 | + { |
649 | + } |
650 | + void focus_changed(std::shared_ptr<input::SurfaceTarget> const&) |
651 | + { |
652 | + } |
653 | + |
654 | + void focus_cleared() |
655 | + { |
656 | + } |
657 | +}; |
658 | + |
659 | +} |
660 | +} |
661 | +} // namespace mir |
662 | + |
663 | +#endif // MIR_TEST_DOUBLES_STUB_INPUT_LISTENER_H_ |
664 | |
665 | === modified file 'include/test/mir_test_doubles/stub_surface_target.h' |
666 | --- include/test/mir_test_doubles/stub_surface_target.h 2013-04-16 09:08:29 +0000 |
667 | +++ include/test/mir_test_doubles/stub_surface_target.h 2013-04-22 21:32:25 +0000 |
668 | @@ -43,6 +43,10 @@ |
669 | { |
670 | return geometry::Size(); |
671 | } |
672 | + geometry::Point top_left() const override |
673 | + { |
674 | + return geometry::Point(); |
675 | + } |
676 | std::string name() const override |
677 | { |
678 | return std::string(); |
679 | |
680 | === modified file 'include/test/mir_test_framework/testing_server_configuration.h' |
681 | --- include/test/mir_test_framework/testing_server_configuration.h 2013-04-16 09:08:29 +0000 |
682 | +++ include/test/mir_test_framework/testing_server_configuration.h 2013-04-22 21:32:25 +0000 |
683 | @@ -49,7 +49,7 @@ |
684 | // to avoid starting and stopping the full android input stack for tests |
685 | // which do not leverage input. |
686 | std::shared_ptr<input::InputManager> the_input_manager(); |
687 | - std::shared_ptr<shell::InputFocusSelector> the_input_focus_selector(); |
688 | + std::shared_ptr<shell::InputTargetListener> the_input_target_listener(); |
689 | |
690 | virtual std::string the_socket_file() const; |
691 | using DefaultServerConfiguration::the_options; |
692 | |
693 | === modified file 'src/server/default_server_configuration.cpp' |
694 | --- src/server/default_server_configuration.cpp 2013-04-19 12:49:42 +0000 |
695 | +++ src/server/default_server_configuration.cpp 2013-04-22 21:32:25 +0000 |
696 | @@ -45,7 +45,7 @@ |
697 | #include "mir/graphics/buffer_initializer.h" |
698 | #include "mir/graphics/null_display_report.h" |
699 | #include "mir/input/null_input_manager.h" |
700 | -#include "mir/input/null_input_focus_selector.h" |
701 | +#include "mir/input/null_input_target_listener.h" |
702 | #include "input/android/default_android_input_configuration.h" |
703 | #include "input/android/android_input_manager.h" |
704 | #include "input/android/android_dispatcher_controller.h" |
705 | @@ -310,8 +310,7 @@ |
706 | [this] |
707 | { |
708 | return std::make_shared<msh::SingleVisibilityFocusMechanism>( |
709 | - the_shell_session_container(), |
710 | - the_input_focus_selector()); |
711 | + the_shell_session_container()); |
712 | }); |
713 | } |
714 | |
715 | @@ -347,7 +346,8 @@ |
716 | the_shell_surface_factory(), |
717 | the_shell_session_container(), |
718 | the_shell_focus_sequence(), |
719 | - the_shell_focus_setter()); |
720 | + the_shell_focus_setter(), |
721 | + the_input_target_listener()); |
722 | }); |
723 | } |
724 | |
725 | @@ -562,15 +562,15 @@ |
726 | return the_input_manager(); |
727 | } |
728 | |
729 | -std::shared_ptr<msh::InputFocusSelector> mir::DefaultServerConfiguration::the_input_focus_selector() |
730 | +std::shared_ptr<msh::InputTargetListener> mir::DefaultServerConfiguration::the_input_target_listener() |
731 | { |
732 | - return input_focus_selector( |
733 | - [&]() -> std::shared_ptr<msh::InputFocusSelector> |
734 | + return input_target_listener( |
735 | + [&]() -> std::shared_ptr<msh::InputTargetListener> |
736 | { |
737 | if (the_options()->get("enable-input", false)) |
738 | return std::make_shared<mia::DispatcherController>(the_input_configuration()); |
739 | else |
740 | - return std::make_shared<mi::NullInputFocusSelector>(); |
741 | + return std::make_shared<mi::NullInputTargetListener>(); |
742 | }); |
743 | } |
744 | |
745 | |
746 | === modified file 'src/server/display_server.cpp' |
747 | --- src/server/display_server.cpp 2013-04-19 14:52:23 +0000 |
748 | +++ src/server/display_server.cpp 2013-04-22 21:32:25 +0000 |
749 | @@ -31,9 +31,9 @@ |
750 | |
751 | namespace mc = mir::compositor; |
752 | namespace mf = mir::frontend; |
753 | -namespace msh = mir::shell; |
754 | namespace mg = mir::graphics; |
755 | namespace mi = mir::input; |
756 | +namespace msh = mir::shell; |
757 | |
758 | namespace |
759 | { |
760 | |
761 | === modified file 'src/server/input/android/android_dispatcher_controller.cpp' |
762 | --- src/server/input/android/android_dispatcher_controller.cpp 2013-04-11 23:06:12 +0000 |
763 | +++ src/server/input/android/android_dispatcher_controller.cpp 2013-04-22 21:32:25 +0000 |
764 | @@ -25,35 +25,85 @@ |
765 | |
766 | #include <InputDispatcher.h> |
767 | |
768 | +#include <boost/throw_exception.hpp> |
769 | + |
770 | +#include <stdexcept> |
771 | +#include <mutex> |
772 | + |
773 | namespace mi = mir::input; |
774 | namespace mia = mi::android; |
775 | |
776 | mia::DispatcherController::DispatcherController(std::shared_ptr<mia::InputConfiguration> const& config) : |
777 | - input_dispatcher(config->the_dispatcher()), |
778 | - focused_window_handle(0), |
779 | - focused_application_handle(0) |
780 | -{ |
781 | -} |
782 | - |
783 | -void mia::DispatcherController::set_input_focus_to(std::shared_ptr<mi::SessionTarget> const& session, |
784 | - std::shared_ptr<mi::SurfaceTarget> const& surface) |
785 | -{ |
786 | - if (focused_window_handle.get()) |
787 | - { |
788 | - input_dispatcher->unregisterInputChannel(focused_window_handle->getInfo()->inputChannel); |
789 | - focused_window_handle.clear(); |
790 | - focused_application_handle.clear(); |
791 | - } |
792 | + input_dispatcher(config->the_dispatcher()) |
793 | +{ |
794 | +} |
795 | + |
796 | +void mia::DispatcherController::input_application_opened(std::shared_ptr<mi::SessionTarget> const& session) |
797 | +{ |
798 | + std::unique_lock<std::mutex> lock(handles_mutex); |
799 | + if (application_handles.find(session) != application_handles.end()) |
800 | + BOOST_THROW_EXCEPTION(std::logic_error("An application was opened twice")); |
801 | + application_handles[session] = new mia::InputApplicationHandle(session); |
802 | +} |
803 | + |
804 | +void mia::DispatcherController::input_application_closed(std::shared_ptr<mi::SessionTarget> const& session) |
805 | +{ |
806 | + std::unique_lock<std::mutex> lock(handles_mutex); |
807 | + if (application_handles.find(session) == application_handles.end()) |
808 | + BOOST_THROW_EXCEPTION(std::logic_error("An application was closed twice")); |
809 | + application_handles.erase(session); |
810 | +} |
811 | + |
812 | +void mia::DispatcherController::input_surface_opened(std::shared_ptr<mi::SessionTarget> const& session, |
813 | + std::shared_ptr<input::SurfaceTarget> const& opened_surface) |
814 | +{ |
815 | + std::unique_lock<std::mutex> lock(handles_mutex); |
816 | + auto application_handle = application_handles.find(session); |
817 | + if (application_handle == application_handles.end()) |
818 | + BOOST_THROW_EXCEPTION(std::logic_error("A surface was opened for an unopened application")); |
819 | + if (window_handles.find(opened_surface) != window_handles.end()) |
820 | + BOOST_THROW_EXCEPTION(std::logic_error("A surface was opened twice")); |
821 | + |
822 | + droidinput::sp<droidinput::InputWindowHandle> window_handle = new mia::InputWindowHandle(application_handle->second, opened_surface); |
823 | + input_dispatcher->registerInputChannel(window_handle->getInfo()->inputChannel, window_handle, false); |
824 | + |
825 | + window_handles[opened_surface] = window_handle; |
826 | +} |
827 | + |
828 | +void mia::DispatcherController::input_surface_closed(std::shared_ptr<input::SurfaceTarget> const& closed_surface) |
829 | +{ |
830 | + std::unique_lock<std::mutex> lock(handles_mutex); |
831 | + auto it = window_handles.find(closed_surface); |
832 | + if (it == window_handles.end()) |
833 | + BOOST_THROW_EXCEPTION(std::logic_error("A surface was closed twice")); |
834 | + |
835 | + input_dispatcher->unregisterInputChannel(it->second->getInfo()->inputChannel); |
836 | + window_handles.erase(it); |
837 | +} |
838 | + |
839 | +void mia::DispatcherController::focus_cleared() |
840 | +{ |
841 | + droidinput::Vector<droidinput::sp<droidinput::InputWindowHandle>> empty_windows; |
842 | + droidinput::sp<droidinput::InputApplicationHandle> null_application = nullptr; |
843 | + |
844 | + input_dispatcher->setFocusedApplication(null_application); |
845 | + input_dispatcher->setInputWindows(empty_windows); |
846 | +} |
847 | + |
848 | +void mia::DispatcherController::focus_changed(std::shared_ptr<mi::SurfaceTarget> const& surface) |
849 | +{ |
850 | + std::unique_lock<std::mutex> lock(handles_mutex); |
851 | + |
852 | + auto window_handle = window_handles[surface]; |
853 | + |
854 | + if (!window_handle.get()) |
855 | + BOOST_THROW_EXCEPTION(std::logic_error("Focus changed to an unopened surface")); |
856 | + auto application_handle = window_handle->inputApplicationHandle; |
857 | + |
858 | + input_dispatcher->setFocusedApplication(application_handle); |
859 | |
860 | droidinput::Vector<droidinput::sp<droidinput::InputWindowHandle>> windows; |
861 | - if (surface) |
862 | - { |
863 | - focused_application_handle = new mia::InputApplicationHandle(session); |
864 | - focused_window_handle = new mia::InputWindowHandle(focused_application_handle, surface); |
865 | - input_dispatcher->setFocusedApplication(focused_application_handle); |
866 | + windows.push_back(window_handle); |
867 | |
868 | - input_dispatcher->registerInputChannel(focused_window_handle->getInfo()->inputChannel, focused_window_handle, false); |
869 | - windows.push_back(focused_window_handle); |
870 | - } |
871 | input_dispatcher->setInputWindows(windows); |
872 | } |
873 | |
874 | === modified file 'src/server/input/android/android_dispatcher_controller.h' |
875 | --- src/server/input/android/android_dispatcher_controller.h 2013-04-11 23:06:12 +0000 |
876 | +++ src/server/input/android/android_dispatcher_controller.h 2013-04-22 21:32:25 +0000 |
877 | @@ -19,10 +19,13 @@ |
878 | #ifndef MIR_INPUT_ANDROID_DISPATCHER_CONTROLLER_H_ |
879 | #define MIR_INPUT_ANDROID_DISPATCHER_CONTROLLER_H_ |
880 | |
881 | -#include "mir/shell/input_focus_selector.h" |
882 | +#include "mir/shell/input_target_listener.h" |
883 | |
884 | #include <utils/StrongPointer.h> |
885 | |
886 | +#include <map> |
887 | +#include <mutex> |
888 | + |
889 | namespace android |
890 | { |
891 | class InputDispatcherInterface; |
892 | @@ -40,13 +43,21 @@ |
893 | { |
894 | class InputConfiguration; |
895 | |
896 | -class DispatcherController : public shell::InputFocusSelector |
897 | +class DispatcherController : public shell::InputTargetListener |
898 | { |
899 | public: |
900 | explicit DispatcherController(std::shared_ptr<InputConfiguration> const& input_configuration); |
901 | - virtual ~DispatcherController() = default; |
902 | + virtual ~DispatcherController() noexcept(true) {} |
903 | |
904 | - void set_input_focus_to(std::shared_ptr<input::SessionTarget> const& session, std::shared_ptr<input::SurfaceTarget> const& surface); |
905 | + void input_application_opened(std::shared_ptr<input::SessionTarget> const& application); |
906 | + void input_application_closed(std::shared_ptr<input::SessionTarget> const& application); |
907 | + |
908 | + void input_surface_opened(std::shared_ptr<input::SessionTarget> const& application, |
909 | + std::shared_ptr<input::SurfaceTarget> const& opened_surface); |
910 | + void input_surface_closed(std::shared_ptr<input::SurfaceTarget> const& closed_surface); |
911 | + |
912 | + void focus_changed(std::shared_ptr<input::SurfaceTarget> const& focus_surface); |
913 | + void focus_cleared(); |
914 | |
915 | protected: |
916 | DispatcherController(const DispatcherController&) = delete; |
917 | @@ -55,8 +66,10 @@ |
918 | private: |
919 | droidinput::sp<droidinput::InputDispatcherInterface> input_dispatcher; |
920 | |
921 | - droidinput::sp<droidinput::InputWindowHandle> focused_window_handle; |
922 | - droidinput::sp<droidinput::InputApplicationHandle> focused_application_handle; |
923 | + std::map<std::shared_ptr<input::SessionTarget>, droidinput::sp<droidinput::InputApplicationHandle>> application_handles; |
924 | + std::map<std::shared_ptr<input::SurfaceTarget>, droidinput::sp<droidinput::InputWindowHandle>> window_handles; |
925 | + |
926 | + std::mutex handles_mutex; |
927 | }; |
928 | |
929 | } |
930 | |
931 | === modified file 'src/server/input/android/android_input_reader_policy.cpp' |
932 | --- src/server/input/android/android_input_reader_policy.cpp 2013-04-16 09:08:29 +0000 |
933 | +++ src/server/input/android/android_input_reader_policy.cpp 2013-04-22 21:32:25 +0000 |
934 | @@ -47,7 +47,10 @@ |
935 | width, |
936 | height, |
937 | default_display_orientation); |
938 | + |
939 | + out_config->pointerVelocityControlParameters.acceleration = 1.0; |
940 | } |
941 | + |
942 | droidinput::sp<droidinput::PointerControllerInterface> mia::InputReaderPolicy::obtainPointerController(int32_t /*device_id*/) |
943 | { |
944 | return pointer_controller; |
945 | |
946 | === modified file 'src/server/input/android/android_input_window_handle.cpp' |
947 | --- src/server/input/android/android_input_window_handle.cpp 2013-03-29 16:51:35 +0000 |
948 | +++ src/server/input/android/android_input_window_handle.cpp 2013-04-22 21:32:25 +0000 |
949 | @@ -48,11 +48,17 @@ |
950 | surface->server_input_fd()); |
951 | } |
952 | |
953 | - mInfo->frameLeft = 0; |
954 | - mInfo->frameTop = 0; |
955 | + auto surface_position = surface->top_left(); |
956 | + mInfo->frameLeft = surface_position.x.as_uint32_t(); |
957 | + mInfo->frameTop = surface_position.y.as_uint32_t(); |
958 | auto surface_size = surface->size(); |
959 | mInfo->frameRight = mInfo->frameLeft + surface_size.width.as_uint32_t(); |
960 | mInfo->frameBottom = mInfo->frameTop + surface_size.height.as_uint32_t(); |
961 | + |
962 | + mInfo->touchableRegionLeft = mInfo->frameLeft; |
963 | + mInfo->touchableRegionTop = mInfo->frameTop; |
964 | + mInfo->touchableRegionRight = mInfo->frameRight; |
965 | + mInfo->touchableRegionBottom = mInfo->frameBottom; |
966 | |
967 | mInfo->name = droidinput::String8(surface->name().c_str()); |
968 | mInfo->layoutParamsFlags = droidinput::InputWindowInfo::FLAG_NOT_TOUCH_MODAL; |
969 | |
970 | === modified file 'src/server/input/android/default_android_input_configuration.cpp' |
971 | --- src/server/input/android/default_android_input_configuration.cpp 2013-04-16 09:08:29 +0000 |
972 | +++ src/server/input/android/default_android_input_configuration.cpp 2013-04-22 21:32:25 +0000 |
973 | @@ -98,7 +98,7 @@ |
974 | return dispatcher_policy( |
975 | [this]() |
976 | { |
977 | - return new mia::EventFilterDispatcherPolicy(filter_chain); |
978 | + return new mia::EventFilterDispatcherPolicy(filter_chain, is_key_repeat_enabled()); |
979 | }); |
980 | } |
981 | |
982 | @@ -149,3 +149,8 @@ |
983 | new droidinput::InputReaderThread(the_reader())); |
984 | }); |
985 | } |
986 | + |
987 | +bool mia::DefaultInputConfiguration::is_key_repeat_enabled() |
988 | +{ |
989 | + return true; |
990 | +} |
991 | |
992 | === modified file 'src/server/input/android/default_android_input_configuration.h' |
993 | --- src/server/input/android/default_android_input_configuration.h 2013-04-16 09:08:29 +0000 |
994 | +++ src/server/input/android/default_android_input_configuration.h 2013-04-22 21:32:25 +0000 |
995 | @@ -69,6 +69,8 @@ |
996 | |
997 | virtual droidinput::sp<droidinput::InputDispatcherPolicyInterface> the_dispatcher_policy(); |
998 | virtual droidinput::sp<droidinput::InputReaderPolicyInterface> the_reader_policy(); |
999 | + |
1000 | + virtual bool is_key_repeat_enabled(); |
1001 | |
1002 | protected: |
1003 | DefaultInputConfiguration(DefaultInputConfiguration const&) = delete; |
1004 | |
1005 | === modified file 'src/server/input/android/event_filter_dispatcher_policy.cpp' |
1006 | --- src/server/input/android/event_filter_dispatcher_policy.cpp 2013-04-16 09:27:00 +0000 |
1007 | +++ src/server/input/android/event_filter_dispatcher_policy.cpp 2013-04-22 21:32:25 +0000 |
1008 | @@ -21,8 +21,9 @@ |
1009 | namespace mi = mir::input; |
1010 | namespace mia = mi::android; |
1011 | |
1012 | -mia::EventFilterDispatcherPolicy::EventFilterDispatcherPolicy(std::shared_ptr<mi::EventFilter> const& event_filter) : |
1013 | - event_filter(event_filter) |
1014 | +mia::EventFilterDispatcherPolicy::EventFilterDispatcherPolicy(std::shared_ptr<mi::EventFilter> const& event_filter, bool key_repeat_enabled) : |
1015 | + event_filter(event_filter), |
1016 | + key_repeat_enabled(key_repeat_enabled) |
1017 | { |
1018 | } |
1019 | |
1020 | @@ -46,7 +47,7 @@ |
1021 | |
1022 | bool mia::EventFilterDispatcherPolicy::isKeyRepeatEnabled() |
1023 | { |
1024 | - return true; |
1025 | + return key_repeat_enabled; |
1026 | } |
1027 | |
1028 | bool mia::EventFilterDispatcherPolicy::filterInputEvent(const droidinput::InputEvent* input_event, uint32_t /*policy_flags*/) |
1029 | @@ -67,9 +68,9 @@ |
1030 | policy_flags |= droidinput::POLICY_FLAG_PASS_TO_USER; |
1031 | } |
1032 | |
1033 | -void mia::EventFilterDispatcherPolicy::interceptMotionBeforeQueueing(nsecs_t /* when */, uint32_t& /* policyFlags */) |
1034 | +void mia::EventFilterDispatcherPolicy::interceptMotionBeforeQueueing(nsecs_t /* when */, uint32_t& policy_flags) |
1035 | { |
1036 | - // TODO: Implement for motion events to client. |
1037 | + policy_flags |= droidinput::POLICY_FLAG_PASS_TO_USER; |
1038 | } |
1039 | |
1040 | nsecs_t mia::EventFilterDispatcherPolicy::interceptKeyBeforeDispatching( |
1041 | |
1042 | === modified file 'src/server/input/android/event_filter_dispatcher_policy.h' |
1043 | --- src/server/input/android/event_filter_dispatcher_policy.h 2013-04-16 09:08:29 +0000 |
1044 | +++ src/server/input/android/event_filter_dispatcher_policy.h 2013-04-22 21:32:25 +0000 |
1045 | @@ -40,7 +40,7 @@ |
1046 | class EventFilterDispatcherPolicy : public droidinput::InputDispatcherPolicyInterface |
1047 | { |
1048 | public: |
1049 | - EventFilterDispatcherPolicy(std::shared_ptr<EventFilter> const& event_filter); |
1050 | + EventFilterDispatcherPolicy(std::shared_ptr<EventFilter> const& event_filter, bool key_repeat_enabled); |
1051 | virtual ~EventFilterDispatcherPolicy() {} |
1052 | |
1053 | void notifyConfigurationChanged(nsecs_t when); |
1054 | @@ -71,6 +71,7 @@ |
1055 | EventFilterDispatcherPolicy& operator=(const EventFilterDispatcherPolicy&) = delete; |
1056 | private: |
1057 | std::shared_ptr<EventFilter> event_filter; |
1058 | + bool key_repeat_enabled; |
1059 | }; |
1060 | |
1061 | } |
1062 | |
1063 | === modified file 'src/server/shell/application_session.cpp' |
1064 | --- src/server/shell/application_session.cpp 2013-04-16 17:42:26 +0000 |
1065 | +++ src/server/shell/application_session.cpp 2013-04-22 21:32:25 +0000 |
1066 | @@ -18,8 +18,8 @@ |
1067 | |
1068 | #include "mir/shell/application_session.h" |
1069 | #include "mir/shell/surface.h" |
1070 | - |
1071 | #include "mir/shell/surface_factory.h" |
1072 | +#include "mir/shell/input_target_listener.h" |
1073 | |
1074 | #include <boost/throw_exception.hpp> |
1075 | |
1076 | @@ -32,9 +32,11 @@ |
1077 | namespace msh = mir::shell; |
1078 | |
1079 | msh::ApplicationSession::ApplicationSession( |
1080 | - std::shared_ptr<SurfaceFactory> const& surface_factory, |
1081 | + std::shared_ptr<msh::SurfaceFactory> const& surface_factory, |
1082 | + std::shared_ptr<msh::InputTargetListener> const& input_target_listener, |
1083 | std::string const& session_name) : |
1084 | surface_factory(surface_factory), |
1085 | + input_target_listener(input_target_listener), |
1086 | session_name(session_name), |
1087 | next_surface_id(0) |
1088 | { |
1089 | @@ -46,6 +48,7 @@ |
1090 | std::unique_lock<std::mutex> lock(surfaces_mutex); |
1091 | for (auto const& pair_id_surface : surfaces) |
1092 | { |
1093 | + input_target_listener->input_surface_closed(pair_id_surface.second); |
1094 | pair_id_surface.second->destroy(); |
1095 | } |
1096 | } |
1097 | @@ -95,6 +98,7 @@ |
1098 | std::unique_lock<std::mutex> lock(surfaces_mutex); |
1099 | auto p = checked_find(id); |
1100 | |
1101 | + input_target_listener->input_surface_closed(p->second); |
1102 | p->second->destroy(); |
1103 | surfaces.erase(p); |
1104 | } |
1105 | |
1106 | === modified file 'src/server/shell/session_manager.cpp' |
1107 | --- src/server/shell/session_manager.cpp 2013-04-19 09:15:31 +0000 |
1108 | +++ src/server/shell/session_manager.cpp 2013-04-22 21:32:25 +0000 |
1109 | @@ -23,6 +23,8 @@ |
1110 | #include "mir/shell/focus_sequence.h" |
1111 | #include "mir/shell/focus_setter.h" |
1112 | #include "mir/shell/session.h" |
1113 | +#include "mir/shell/surface.h" |
1114 | +#include "mir/shell/input_target_listener.h" |
1115 | |
1116 | #include <memory> |
1117 | #include <cassert> |
1118 | @@ -31,20 +33,22 @@ |
1119 | namespace mf = mir::frontend; |
1120 | namespace msh = mir::shell; |
1121 | |
1122 | -msh::SessionManager::SessionManager( |
1123 | - std::shared_ptr<msh::SurfaceFactory> const& surface_factory, |
1124 | +msh::SessionManager::SessionManager(std::shared_ptr<msh::SurfaceFactory> const& surface_factory, |
1125 | std::shared_ptr<msh::SessionContainer> const& container, |
1126 | std::shared_ptr<msh::FocusSequence> const& sequence, |
1127 | - std::shared_ptr<msh::FocusSetter> const& focus_setter) : |
1128 | + std::shared_ptr<msh::FocusSetter> const& focus_setter, |
1129 | + std::shared_ptr<msh::InputTargetListener> const& input_target_listener) : |
1130 | surface_factory(surface_factory), |
1131 | app_container(container), |
1132 | focus_sequence(sequence), |
1133 | - focus_setter(focus_setter) |
1134 | + focus_setter(focus_setter), |
1135 | + input_target_listener(input_target_listener) |
1136 | { |
1137 | assert(surface_factory); |
1138 | assert(sequence); |
1139 | assert(container); |
1140 | assert(focus_setter); |
1141 | + assert(input_target_listener); |
1142 | } |
1143 | |
1144 | msh::SessionManager::~SessionManager() |
1145 | @@ -53,25 +57,36 @@ |
1146 | |
1147 | std::shared_ptr<mf::Session> msh::SessionManager::open_session(std::string const& name) |
1148 | { |
1149 | - auto new_session = std::make_shared<msh::ApplicationSession>(surface_factory, name); |
1150 | + auto new_session = std::make_shared<msh::ApplicationSession>(surface_factory, input_target_listener, name); |
1151 | |
1152 | app_container->insert_session(new_session); |
1153 | + |
1154 | + input_target_listener->input_application_opened(new_session); |
1155 | |
1156 | set_focus_to_locked(std::unique_lock<std::mutex>(mutex), new_session); |
1157 | |
1158 | return new_session; |
1159 | } |
1160 | |
1161 | -inline void msh::SessionManager::set_focus_to_locked(std::unique_lock<std::mutex> const&, std::shared_ptr<Session> const& next_focus) |
1162 | +inline void msh::SessionManager::set_focus_to_locked(std::unique_lock<std::mutex> const&, std::shared_ptr<Session> const& shell_session) |
1163 | { |
1164 | - focus_application = next_focus; |
1165 | - focus_setter->set_focus_to(next_focus); |
1166 | + auto old_focus = focus_application.lock(); |
1167 | + |
1168 | + focus_application = shell_session; |
1169 | + focus_setter->set_focus_to(shell_session); |
1170 | + |
1171 | + if (shell_session && shell_session->default_surface()) |
1172 | + input_target_listener->focus_changed(shell_session->default_surface()); |
1173 | + else if (shell_session == old_focus || !shell_session) |
1174 | + input_target_listener->focus_cleared(); |
1175 | } |
1176 | |
1177 | void msh::SessionManager::close_session(std::shared_ptr<mf::Session> const& session) |
1178 | { |
1179 | auto shell_session = std::dynamic_pointer_cast<Session>(session); |
1180 | |
1181 | + input_target_listener->input_application_closed(shell_session); |
1182 | + |
1183 | app_container->remove_session(shell_session); |
1184 | |
1185 | std::unique_lock<std::mutex> lock(mutex); |
1186 | @@ -133,9 +148,11 @@ |
1187 | mf::SurfaceCreationParameters const& params) |
1188 | { |
1189 | auto shell_session = std::dynamic_pointer_cast<Session>(session); |
1190 | - auto id = session->create_surface(params); |
1191 | + auto id = shell_session->create_surface(params); |
1192 | + |
1193 | + input_target_listener->input_surface_opened(shell_session, |
1194 | + std::dynamic_pointer_cast<msh::Surface>(shell_session->get_surface(id))); |
1195 | set_focus_to_locked(std::unique_lock<std::mutex>(mutex), shell_session); |
1196 | |
1197 | return id; |
1198 | } |
1199 | - |
1200 | |
1201 | === modified file 'src/server/shell/single_visibility_focus_mechanism.cpp' |
1202 | --- src/server/shell/single_visibility_focus_mechanism.cpp 2013-04-18 22:57:01 +0000 |
1203 | +++ src/server/shell/single_visibility_focus_mechanism.cpp 2013-04-22 21:32:25 +0000 |
1204 | @@ -19,7 +19,6 @@ |
1205 | #include "mir/shell/session_container.h" |
1206 | #include "mir/frontend/session.h" |
1207 | #include "mir/shell/single_visibility_focus_mechanism.h" |
1208 | -#include "mir/shell/input_focus_selector.h" |
1209 | |
1210 | #include "mir/shell/session.h" |
1211 | #include "mir/shell/surface.h" |
1212 | @@ -27,10 +26,8 @@ |
1213 | namespace mf = mir::frontend; |
1214 | namespace msh = mir::shell; |
1215 | |
1216 | -msh::SingleVisibilityFocusMechanism::SingleVisibilityFocusMechanism(std::shared_ptr<msh::SessionContainer> const& app_container, |
1217 | - std::shared_ptr<msh::InputFocusSelector> const& input_selector) |
1218 | - : app_container(app_container), |
1219 | - input_selector(input_selector) |
1220 | +msh::SingleVisibilityFocusMechanism::SingleVisibilityFocusMechanism(std::shared_ptr<msh::SessionContainer> const& app_container) |
1221 | + : app_container(app_container) |
1222 | { |
1223 | } |
1224 | |
1225 | @@ -41,8 +38,6 @@ |
1226 | if (session == focus_session) |
1227 | { |
1228 | session->show(); |
1229 | - |
1230 | - input_selector->set_input_focus_to(focus_session, focus_session->default_surface()); |
1231 | } |
1232 | else |
1233 | { |
1234 | |
1235 | === modified file 'src/server/shell/surface.cpp' |
1236 | --- src/server/shell/surface.cpp 2013-04-16 17:42:26 +0000 |
1237 | +++ src/server/shell/surface.cpp 2013-04-22 21:32:25 +0000 |
1238 | @@ -88,6 +88,18 @@ |
1239 | } |
1240 | } |
1241 | |
1242 | +mir::geometry::Point msh::Surface::top_left() const |
1243 | +{ |
1244 | + if (auto const& s = surface.lock()) |
1245 | + { |
1246 | + return s->top_left(); |
1247 | + } |
1248 | + else |
1249 | + { |
1250 | + BOOST_THROW_EXCEPTION(std::runtime_error("Invalid surface")); |
1251 | + } |
1252 | +} |
1253 | + |
1254 | std::string msh::Surface::name() const |
1255 | { |
1256 | if (auto const& s = surface.lock()) |
1257 | |
1258 | === modified file 'tests/acceptance-tests/test_client_input.cpp' |
1259 | --- tests/acceptance-tests/test_client_input.cpp 2013-04-17 07:31:40 +0000 |
1260 | +++ tests/acceptance-tests/test_client_input.cpp 2013-04-22 21:32:25 +0000 |
1261 | @@ -65,10 +65,9 @@ |
1262 | |
1263 | } |
1264 | |
1265 | - void set_input_focus_to( |
1266 | - std::shared_ptr<mi::SessionTarget> const& session, std::shared_ptr<mi::SurfaceTarget> const& surface) override |
1267 | + void focus_changed(std::shared_ptr<mi::SurfaceTarget> const& surface) override |
1268 | { |
1269 | - DispatcherController::set_input_focus_to(session, surface); |
1270 | + DispatcherController::focus_changed(surface); |
1271 | |
1272 | // We need a synchronization primitive inorder to halt test event injection |
1273 | // until after a surface has taken focus (lest the events be discarded). |
1274 | @@ -96,6 +95,7 @@ |
1275 | { |
1276 | on_focus_set.wait_for_at_most_seconds(10); |
1277 | fake_event_hub->synthesize_builtin_keyboard_added(); |
1278 | + fake_event_hub->synthesize_builtin_cursor_added(); |
1279 | fake_event_hub->synthesize_device_scan_complete(); |
1280 | inject_input(); |
1281 | }); |
1282 | @@ -122,10 +122,10 @@ |
1283 | }); |
1284 | } |
1285 | |
1286 | - std::shared_ptr<msh::InputFocusSelector> |
1287 | - the_input_focus_selector() override |
1288 | + std::shared_ptr<msh::InputTargetListener> |
1289 | + the_input_target_listener() override |
1290 | { |
1291 | - return input_focus_selector( |
1292 | + return input_target_listener( |
1293 | [this]() |
1294 | { |
1295 | return std::make_shared<FocusNotifyingDispatcherController>(mt::fake_shared(input_config), on_focus_set); |
1296 | @@ -186,7 +186,7 @@ |
1297 | |
1298 | struct MockInputHandler |
1299 | { |
1300 | - MOCK_METHOD1(handle_key_down, void(MirEvent const*)); |
1301 | + MOCK_METHOD1(handle_input, bool(MirEvent const*)); |
1302 | }; |
1303 | |
1304 | struct InputReceivingClient : ClientConfigCommon |
1305 | @@ -201,9 +201,9 @@ |
1306 | static void handle_input(MirSurface* /* surface */, MirEvent const* ev, void* context) |
1307 | { |
1308 | auto client = static_cast<InputReceivingClient *>(context); |
1309 | - if (ev->key.action == 0) |
1310 | + |
1311 | + if(client->handler->handle_input(ev)) |
1312 | { |
1313 | - client->handler->handle_key_down(ev); |
1314 | client->event_received[client->events_received].wake_up_everyone(); |
1315 | client->events_received++; |
1316 | } |
1317 | @@ -227,7 +227,7 @@ |
1318 | MirSurfaceParameters const request_params = |
1319 | { |
1320 | __PRETTY_FUNCTION__, |
1321 | - 640, 480, |
1322 | + surface_width, surface_height, |
1323 | mir_pixel_format_abgr_8888, |
1324 | mir_buffer_usage_hardware |
1325 | }; |
1326 | @@ -259,9 +259,66 @@ |
1327 | |
1328 | int events_to_receive; |
1329 | int events_received; |
1330 | + |
1331 | + static int const surface_width = 100; |
1332 | + static int const surface_height = 100; |
1333 | }; |
1334 | |
1335 | -} |
1336 | +MATCHER(KeyDownEvent, "") |
1337 | +{ |
1338 | + if (arg->type != mir_event_type_key) |
1339 | + return false; |
1340 | + if (arg->key.action != 0) // Key down |
1341 | + return false; |
1342 | + |
1343 | + return true; |
1344 | +} |
1345 | +MATCHER_P(KeyOfSymbol, keysym, "") |
1346 | +{ |
1347 | + if (static_cast<xkb_keysym_t>(arg->key.key_code) == (uint)keysym) |
1348 | + return true; |
1349 | + return false; |
1350 | +} |
1351 | + |
1352 | +MATCHER(HoverEnterEvent, "") |
1353 | +{ |
1354 | + if (arg->type != mir_event_type_motion) |
1355 | + return false; |
1356 | + if (arg->motion.action != AMOTION_EVENT_ACTION_HOVER_ENTER) |
1357 | + return false; |
1358 | + |
1359 | + return true; |
1360 | +} |
1361 | + |
1362 | +MATCHER_P2(ButtonDownEvent, x, y, "") |
1363 | +{ |
1364 | + if (arg->type != mir_event_type_motion) |
1365 | + return false; |
1366 | + if (arg->motion.action != AMOTION_EVENT_ACTION_DOWN) |
1367 | + return false; |
1368 | + printf("action: %d \n", arg->motion.action); |
1369 | + if (arg->motion.button_state == 0) |
1370 | + return false; |
1371 | + if (arg->motion.pointer_coordinates[0].x != x) |
1372 | + return false; |
1373 | + if (arg->motion.pointer_coordinates[0].y != y) |
1374 | + return false; |
1375 | + return true; |
1376 | +} |
1377 | + |
1378 | +MATCHER_P2(MotionEventWithPosition, x, y, "") |
1379 | +{ |
1380 | + if (arg->type != mir_event_type_motion) |
1381 | + return false; |
1382 | + if (arg->motion.pointer_coordinates[0].x != x) |
1383 | + return false; |
1384 | + if (arg->motion.pointer_coordinates[0].y != y) |
1385 | + return false; |
1386 | + return true; |
1387 | +} |
1388 | + |
1389 | +} |
1390 | + |
1391 | |
1392 | using TestClientInput = BespokeDisplayServerTestFixture; |
1393 | |
1394 | @@ -290,22 +347,13 @@ |
1395 | void expect_input() |
1396 | { |
1397 | using namespace ::testing; |
1398 | - EXPECT_CALL(*handler, handle_key_down(_)).Times(num_events_produced); |
1399 | + EXPECT_CALL(*handler, handle_input(KeyDownEvent())).Times(num_events_produced) |
1400 | + .WillRepeatedly(Return(true)); |
1401 | } |
1402 | } client_config; |
1403 | launch_client_process(client_config); |
1404 | } |
1405 | |
1406 | -namespace |
1407 | -{ |
1408 | -MATCHER_P(KeyOfSymbol, keysym, "") |
1409 | -{ |
1410 | - if (static_cast<xkb_keysym_t>(arg->key.key_code) == (uint)keysym) |
1411 | - return true; |
1412 | - return false; |
1413 | -} |
1414 | -} |
1415 | - |
1416 | TEST_F(TestClientInput, clients_receive_us_english_mapped_keys) |
1417 | { |
1418 | using namespace ::testing; |
1419 | @@ -319,12 +367,6 @@ |
1420 | fake_event_hub->synthesize_event(mis::a_key_down_event() |
1421 | .of_scancode(KEY_4)); |
1422 | |
1423 | - // Release the keys so we don't get repeat events. |
1424 | - fake_event_hub->synthesize_event(mis::a_key_up_event() |
1425 | - .of_scancode(KEY_4)); |
1426 | - fake_event_hub->synthesize_event(mis::a_key_up_event() |
1427 | - .of_scancode(KEY_LEFTSHIFT)); |
1428 | - |
1429 | } |
1430 | } server_config; |
1431 | launch_server_process(server_config); |
1432 | @@ -338,10 +380,78 @@ |
1433 | using namespace ::testing; |
1434 | |
1435 | InSequence seq; |
1436 | - EXPECT_CALL(*handler, handle_key_down(KeyOfSymbol(XKB_KEY_Shift_L))).Times(1); |
1437 | - EXPECT_CALL(*handler, handle_key_down(KeyOfSymbol(XKB_KEY_dollar))).Times(1); |
1438 | - } |
1439 | - } client_config; |
1440 | - launch_client_process(client_config); |
1441 | -} |
1442 | - |
1443 | + EXPECT_CALL(*handler, handle_input(AllOf(KeyDownEvent(), KeyOfSymbol(XKB_KEY_Shift_L)))).Times(1) |
1444 | + .WillOnce(Return(true)); |
1445 | + EXPECT_CALL(*handler, handle_input(AllOf(KeyDownEvent(), KeyOfSymbol(XKB_KEY_dollar)))).Times(1) |
1446 | + .WillOnce(Return(true)); |
1447 | + } |
1448 | + } client_config; |
1449 | + launch_client_process(client_config); |
1450 | +} |
1451 | + |
1452 | +// TODO: This assumes that clients are placed by shell at 0,0. Which probably isn't quite safe! |
1453 | +TEST_F(TestClientInput, clients_receive_motion_inside_window) |
1454 | +{ |
1455 | + using namespace ::testing; |
1456 | + |
1457 | + struct InputProducingServerConfiguration : FakeInputServerConfiguration |
1458 | + { |
1459 | + void inject_input() |
1460 | + { |
1461 | + fake_event_hub->synthesize_event(mis::a_motion_event().with_movement(InputReceivingClient::surface_width, |
1462 | + InputReceivingClient::surface_height)); |
1463 | + fake_event_hub->synthesize_event(mis::a_motion_event().with_movement(2,2)); |
1464 | + } |
1465 | + } server_config; |
1466 | + launch_server_process(server_config); |
1467 | + |
1468 | + struct MotionReceivingClient : InputReceivingClient |
1469 | + { |
1470 | + MotionReceivingClient() : InputReceivingClient(2) {} |
1471 | + |
1472 | + void expect_input() |
1473 | + { |
1474 | + using namespace ::testing; |
1475 | + |
1476 | + InSequence seq; |
1477 | + |
1478 | + // We should see the cursor enter |
1479 | + EXPECT_CALL(*handler, handle_input(HoverEnterEvent())).Times(1).WillOnce(Return(true)); |
1480 | + EXPECT_CALL(*handler, handle_input( |
1481 | + MotionEventWithPosition(InputReceivingClient::surface_width, |
1482 | + InputReceivingClient::surface_height))).Times(1).WillOnce(Return(true)); |
1483 | + // But we should not receive an event for the second movement outside of our surface! |
1484 | + } |
1485 | + } client_config; |
1486 | + launch_client_process(client_config); |
1487 | +} |
1488 | + |
1489 | +TEST_F(TestClientInput, clients_receive_button_events_inside_window) |
1490 | +{ |
1491 | + using namespace ::testing; |
1492 | + |
1493 | + struct InputProducingServerConfiguration : FakeInputServerConfiguration |
1494 | + { |
1495 | + void inject_input() |
1496 | + { |
1497 | + fake_event_hub->synthesize_event(mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down)); |
1498 | + } |
1499 | + } server_config; |
1500 | + launch_server_process(server_config); |
1501 | + |
1502 | + struct ButtonReceivingClient : InputReceivingClient |
1503 | + { |
1504 | + ButtonReceivingClient() : InputReceivingClient(1) {} |
1505 | + |
1506 | + void expect_input() |
1507 | + { |
1508 | + using namespace ::testing; |
1509 | + |
1510 | + InSequence seq; |
1511 | + |
1512 | + // The cursor starts at (0, 0). |
1513 | + EXPECT_CALL(*handler, handle_input(ButtonDownEvent(0, 0))).Times(1).WillOnce(Return(true)); |
1514 | + } |
1515 | + } client_config; |
1516 | + launch_client_process(client_config); |
1517 | +} |
1518 | |
1519 | === modified file 'tests/acceptance-tests/test_focus_selection.cpp' |
1520 | --- tests/acceptance-tests/test_focus_selection.cpp 2013-04-18 02:52:30 +0000 |
1521 | +++ tests/acceptance-tests/test_focus_selection.cpp 2013-04-22 21:32:25 +0000 |
1522 | @@ -24,11 +24,11 @@ |
1523 | #include "mir/shell/organising_surface_factory.h" |
1524 | #include "mir/shell/session_manager.h" |
1525 | #include "mir/graphics/display.h" |
1526 | -#include "mir/shell/input_focus_selector.h" |
1527 | +#include "mir/shell/input_target_listener.h" |
1528 | |
1529 | #include "mir_test_framework/display_server_test_fixture.h" |
1530 | #include "mir_test_doubles/mock_focus_setter.h" |
1531 | -#include "mir_test_doubles/mock_input_focus_selector.h" |
1532 | +#include "mir_test_doubles/mock_input_target_listener.h" |
1533 | |
1534 | #include <gtest/gtest.h> |
1535 | #include <gmock/gmock.h> |
1536 | @@ -36,7 +36,8 @@ |
1537 | namespace mf = mir::frontend; |
1538 | namespace msh = mir::shell; |
1539 | namespace mi = mir::input; |
1540 | -namespace mtd = mir::test::doubles; |
1541 | +namespace mt = mir::test; |
1542 | +namespace mtd = mt::doubles; |
1543 | namespace mtf = mir_test_framework; |
1544 | |
1545 | namespace |
1546 | @@ -46,6 +47,7 @@ |
1547 | |
1548 | namespace |
1549 | { |
1550 | + |
1551 | struct ClientConfigCommon : TestingClientConfiguration |
1552 | { |
1553 | ClientConfigCommon() : |
1554 | @@ -121,18 +123,10 @@ |
1555 | { |
1556 | return arg != std::shared_ptr<msh::Session>(); |
1557 | } |
1558 | -MATCHER(NonNullSessionTarget, "") |
1559 | -{ |
1560 | - return arg != std::shared_ptr<mi::SessionTarget>(); |
1561 | -} |
1562 | MATCHER(NonNullSurfaceTarget, "") |
1563 | { |
1564 | return arg != std::shared_ptr<mi::SurfaceTarget>(); |
1565 | } |
1566 | -MATCHER(NullSurfaceTarget, "") |
1567 | -{ |
1568 | - return arg == std::shared_ptr<mi::SurfaceTarget>(); |
1569 | -} |
1570 | } |
1571 | |
1572 | TEST_F(BespokeDisplayServerTestFixture, sessions_creating_surface_receive_focus) |
1573 | @@ -148,7 +142,6 @@ |
1574 | using namespace ::testing; |
1575 | |
1576 | auto focus_setter = std::make_shared<mtd::MockFocusSetter>(); |
1577 | - |
1578 | { |
1579 | InSequence seq; |
1580 | // Once on application registration and once on surface creation |
1581 | @@ -174,30 +167,37 @@ |
1582 | { |
1583 | struct ServerConfig : TestingServerConfiguration |
1584 | { |
1585 | - std::shared_ptr<mtd::MockInputFocusSelector> focus_selector; |
1586 | + std::shared_ptr<mtd::MockInputTargetListener> target_listener; |
1587 | bool expected; |
1588 | |
1589 | ServerConfig() |
1590 | - : focus_selector(std::make_shared<mtd::MockInputFocusSelector>()), |
1591 | + : target_listener(std::make_shared<mtd::MockInputTargetListener>()), |
1592 | expected(false) |
1593 | { |
1594 | } |
1595 | |
1596 | - std::shared_ptr<msh::InputFocusSelector> |
1597 | - the_input_focus_selector() override |
1598 | + std::shared_ptr<msh::InputTargetListener> |
1599 | + the_input_target_listener() override |
1600 | { |
1601 | using namespace ::testing; |
1602 | |
1603 | if (!expected) |
1604 | { |
1605 | - InSequence seq; |
1606 | + |
1607 | + EXPECT_CALL(*target_listener, input_application_opened(_)).Times(AtLeast(0)); |
1608 | + EXPECT_CALL(*target_listener, input_application_closed(_)).Times(AtLeast(0)); |
1609 | + EXPECT_CALL(*target_listener, input_surface_opened(_,_)).Times(AtLeast(0)); |
1610 | + EXPECT_CALL(*target_listener, input_surface_closed(_)).Times(AtLeast(0)); |
1611 | + EXPECT_CALL(*target_listener, focus_cleared()).Times(AtLeast(0)); |
1612 | |
1613 | - EXPECT_CALL(*focus_selector, set_input_focus_to(NonNullSessionTarget(), NullSurfaceTarget())).Times(1); |
1614 | - EXPECT_CALL(*focus_selector, set_input_focus_to(NonNullSessionTarget(), NonNullSurfaceTarget())).Times(1); |
1615 | - expected = true; |
1616 | + { |
1617 | + InSequence seq; |
1618 | + EXPECT_CALL(*target_listener, focus_changed(NonNullSurfaceTarget())).Times(1); |
1619 | + expected = true; |
1620 | + } |
1621 | } |
1622 | |
1623 | - return focus_selector; |
1624 | + return target_listener; |
1625 | } |
1626 | } server_config; |
1627 | |
1628 | |
1629 | === modified file 'tests/death-tests/test_application_manager_death.cpp' |
1630 | --- tests/death-tests/test_application_manager_death.cpp 2013-03-21 03:32:59 +0000 |
1631 | +++ tests/death-tests/test_application_manager_death.cpp 2013-04-22 21:32:25 +0000 |
1632 | @@ -30,11 +30,12 @@ |
1633 | // ::testing::FLAGS_gtest_death_test_style = "threadsafe"; |
1634 | // leads to the test failing under valgrind |
1635 | EXPECT_EXIT( |
1636 | - std::shared_ptr<msh::SurfaceFactory> factory; |
1637 | - mir::shell::SessionManager app(factory, |
1638 | + std::shared_ptr<msh::SurfaceFactory> surface_factory; |
1639 | + mir::shell::SessionManager app(surface_factory, |
1640 | std::shared_ptr<msh::SessionContainer>(), |
1641 | std::shared_ptr<msh::FocusSequence>(), |
1642 | - std::shared_ptr<msh::FocusSetter>()), |
1643 | + std::shared_ptr<msh::FocusSetter>(), |
1644 | + std::shared_ptr<msh::InputTargetListener>()), |
1645 | ::testing::KilledBySignal(SIGABRT), |
1646 | ".*"); |
1647 | } |
1648 | |
1649 | === modified file 'tests/integration-tests/input/android/test_android_input_manager.cpp' |
1650 | --- tests/integration-tests/input/android/test_android_input_manager.cpp 2013-04-10 23:48:23 +0000 |
1651 | +++ tests/integration-tests/input/android/test_android_input_manager.cpp 2013-04-22 21:32:25 +0000 |
1652 | @@ -35,6 +35,7 @@ |
1653 | #include "mir_test_doubles/stub_surface_target.h" |
1654 | #include "mir_test/wait_condition.h" |
1655 | #include "mir_test/event_factory.h" |
1656 | +#include "mir_test/event_matchers.h" |
1657 | |
1658 | #include <EventHub.h> |
1659 | #include <InputDispatcher.h> |
1660 | @@ -171,7 +172,7 @@ |
1661 | struct MockDispatcherPolicy : public mia::EventFilterDispatcherPolicy |
1662 | { |
1663 | MockDispatcherPolicy(std::shared_ptr<mi::EventFilter> const& filter) |
1664 | - : EventFilterDispatcherPolicy(filter) |
1665 | + : EventFilterDispatcherPolicy(filter, false) |
1666 | { |
1667 | } |
1668 | MOCK_METHOD3(interceptKeyBeforeDispatching, nsecs_t(droidinput::sp<droidinput::InputWindowHandle> const&, |
1669 | @@ -211,24 +212,31 @@ |
1670 | ON_CALL(viewable_area, view_area()) |
1671 | .WillByDefault(Return(default_view_area)); |
1672 | input_manager = std::make_shared<mia::InputManager>(configuration); |
1673 | - input_focus_selector = std::make_shared<mia::DispatcherController>(configuration); |
1674 | + input_target_listener = std::make_shared<mia::DispatcherController>(configuration); |
1675 | |
1676 | dispatcher_policy = configuration->the_mock_dispatcher_policy(); |
1677 | |
1678 | } |
1679 | |
1680 | + ~AndroidInputManagerDispatcherInterceptSetup() |
1681 | + { |
1682 | + input_manager->stop(); |
1683 | + } |
1684 | + |
1685 | // TODO: It would be nice if it were possible to mock the interface between |
1686 | // droidinput::InputChannel and droidinput::InputDispatcher rather than use |
1687 | // valid fds to allow non-throwing construction of a real input channel. |
1688 | void SetUp() |
1689 | { |
1690 | - test_input_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); |
1691 | input_manager->start(); |
1692 | } |
1693 | - void TearDown() |
1694 | + |
1695 | + int test_fd() |
1696 | { |
1697 | - input_manager->stop(); |
1698 | - close(test_input_fd); |
1699 | + int fds[2]; |
1700 | + // Closed by droidinput InputChannel on shutdown |
1701 | + socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds); |
1702 | + return fds[0]; |
1703 | } |
1704 | |
1705 | MockEventFilter event_filter; |
1706 | @@ -238,9 +246,7 @@ |
1707 | droidinput::sp<MockDispatcherPolicy> dispatcher_policy; |
1708 | |
1709 | std::shared_ptr<mia::InputManager> input_manager; |
1710 | - std::shared_ptr<msh::InputFocusSelector> input_focus_selector; |
1711 | - |
1712 | - int test_input_fd; |
1713 | + std::shared_ptr<msh::InputTargetListener> input_target_listener; |
1714 | }; |
1715 | |
1716 | MATCHER_P(WindowHandleWithInputFd, input_fd, "") |
1717 | @@ -259,14 +265,18 @@ |
1718 | mt::WaitCondition wait_condition; |
1719 | |
1720 | mtd::StubSessionTarget session; |
1721 | - mtd::StubSurfaceTarget surface(test_input_fd); |
1722 | + |
1723 | + auto input_fd = test_fd(); |
1724 | + mtd::StubSurfaceTarget surface(input_fd); |
1725 | |
1726 | EXPECT_CALL(event_filter, handles(_)).Times(1).WillOnce(Return(false)); |
1727 | // We return -1 here to skip publishing of the event (to an unconnected test socket!). |
1728 | - EXPECT_CALL(*dispatcher_policy, interceptKeyBeforeDispatching(WindowHandleWithInputFd(test_input_fd), _, _)) |
1729 | + EXPECT_CALL(*dispatcher_policy, interceptKeyBeforeDispatching(WindowHandleWithInputFd(input_fd), _, _)) |
1730 | .Times(1).WillOnce(DoAll(mt::WakeUp(&wait_condition), Return(-1))); |
1731 | |
1732 | - input_focus_selector->set_input_focus_to(mt::fake_shared(session), mt::fake_shared(surface)); |
1733 | + input_target_listener->input_application_opened(mt::fake_shared(session)); |
1734 | + input_target_listener->input_surface_opened(mt::fake_shared(session), mt::fake_shared(surface)); |
1735 | + input_target_listener->focus_changed(mt::fake_shared(surface)); |
1736 | |
1737 | fake_event_hub->synthesize_builtin_keyboard_added(); |
1738 | fake_event_hub->synthesize_device_scan_complete(); |
1739 | @@ -275,3 +285,52 @@ |
1740 | |
1741 | wait_condition.wait_for_at_most_seconds(1); |
1742 | } |
1743 | + |
1744 | +TEST_F(AndroidInputManagerDispatcherInterceptSetup, changing_focus_changes_event_recipient) |
1745 | +{ |
1746 | + using namespace ::testing; |
1747 | + |
1748 | + mt::WaitCondition wait1, wait2, wait3; |
1749 | + |
1750 | + mtd::StubSessionTarget session; |
1751 | + |
1752 | + auto input_fd_1 = test_fd(); |
1753 | + mtd::StubSurfaceTarget surface1(input_fd_1); |
1754 | + auto input_fd_2 = test_fd(); |
1755 | + mtd::StubSurfaceTarget surface2(input_fd_2); |
1756 | + |
1757 | + input_target_listener->input_application_opened(mt::fake_shared(session)); |
1758 | + input_target_listener->input_surface_opened(mt::fake_shared(session), mt::fake_shared(surface1)); |
1759 | + input_target_listener->input_surface_opened(mt::fake_shared(session), mt::fake_shared(surface2)); |
1760 | + |
1761 | + EXPECT_CALL(event_filter, handles(_)).Times(3).WillRepeatedly(Return(false)); |
1762 | + |
1763 | + { |
1764 | + InSequence seq; |
1765 | + |
1766 | + EXPECT_CALL(*dispatcher_policy, interceptKeyBeforeDispatching(WindowHandleWithInputFd(input_fd_1), _, _)) |
1767 | + .Times(1).WillOnce(DoAll(mt::WakeUp(&wait1), Return(-1))); |
1768 | + EXPECT_CALL(*dispatcher_policy, interceptKeyBeforeDispatching(WindowHandleWithInputFd(input_fd_2), _, _)) |
1769 | + .Times(1).WillOnce(DoAll(mt::WakeUp(&wait2), Return(-1))); |
1770 | + EXPECT_CALL(*dispatcher_policy, interceptKeyBeforeDispatching(WindowHandleWithInputFd(input_fd_1), _, _)) |
1771 | + .Times(1).WillOnce(DoAll(mt::WakeUp(&wait3), Return(-1))); |
1772 | + } |
1773 | + |
1774 | + fake_event_hub->synthesize_builtin_keyboard_added(); |
1775 | + fake_event_hub->synthesize_device_scan_complete(); |
1776 | + |
1777 | + input_target_listener->focus_changed(mt::fake_shared(surface1)); |
1778 | + fake_event_hub->synthesize_event(mis::a_key_down_event() |
1779 | + .of_scancode(KEY_1)); |
1780 | + wait1.wait_for_at_most_seconds(1); |
1781 | + |
1782 | + input_target_listener->focus_changed(mt::fake_shared(surface2)); |
1783 | + fake_event_hub->synthesize_event(mis::a_key_down_event() |
1784 | + .of_scancode(KEY_2)); |
1785 | + wait2.wait_for_at_most_seconds(1); |
1786 | + |
1787 | + input_target_listener->focus_changed(mt::fake_shared(surface1)); |
1788 | + fake_event_hub->synthesize_event(mis::a_key_down_event() |
1789 | + .of_scancode(KEY_3)); |
1790 | + wait3.wait_for_at_most_seconds(5); |
1791 | +} |
1792 | |
1793 | === modified file 'tests/integration-tests/input/android/test_fake_event_hub_to_event_filter.cpp' |
1794 | --- tests/integration-tests/input/android/test_fake_event_hub_to_event_filter.cpp 2013-04-02 18:26:40 +0000 |
1795 | +++ tests/integration-tests/input/android/test_fake_event_hub_to_event_filter.cpp 2013-04-22 21:32:25 +0000 |
1796 | @@ -26,6 +26,7 @@ |
1797 | #include "mir_test_doubles/mock_event_filter.h" |
1798 | #include "mir_test/wait_condition.h" |
1799 | #include "mir_test/event_factory.h" |
1800 | +#include "mir_test/event_matchers.h" |
1801 | |
1802 | #include <InputDispatcher.h> |
1803 | #include <InputReader.h> |
1804 | @@ -56,7 +57,7 @@ |
1805 | void SetUp() |
1806 | { |
1807 | event_hub = new mia::FakeEventHub(); |
1808 | - dispatcher_policy = new mia::EventFilterDispatcherPolicy(mt::fake_shared(event_filter)); |
1809 | + dispatcher_policy = new mia::EventFilterDispatcherPolicy(mt::fake_shared(event_filter), false); |
1810 | reader_policy = new mia::RudimentaryInputReaderPolicy(); |
1811 | dispatcher = new droidinput::InputDispatcher(dispatcher_policy); |
1812 | reader = new droidinput::InputReader(event_hub, reader_policy, dispatcher); |
1813 | |
1814 | === modified file 'tests/integration-tests/shell/test_session_manager.cpp' |
1815 | --- tests/integration-tests/shell/test_session_manager.cpp 2013-04-18 00:00:55 +0000 |
1816 | +++ tests/integration-tests/shell/test_session_manager.cpp 2013-04-22 21:32:25 +0000 |
1817 | @@ -33,6 +33,7 @@ |
1818 | #include "mir_test/fake_shared.h" |
1819 | #include "mir_test_doubles/mock_surface_factory.h" |
1820 | #include "mir_test_doubles/mock_focus_setter.h" |
1821 | +#include "mir_test_doubles/stub_input_target_listener.h" |
1822 | |
1823 | namespace mc = mir::compositor; |
1824 | namespace mf = mir::frontend; |
1825 | @@ -44,19 +45,22 @@ |
1826 | TEST(TestSessionManagerAndFocusSelectionStrategy, cycle_focus) |
1827 | { |
1828 | using namespace ::testing; |
1829 | + |
1830 | mtd::MockSurfaceFactory surface_factory; |
1831 | std::shared_ptr<msh::DefaultSessionContainer> container(new msh::DefaultSessionContainer()); |
1832 | msh::RegistrationOrderFocusSequence sequence(container); |
1833 | - mtd::MockFocusSetter focus_changer; |
1834 | + mtd::MockFocusSetter focus_setter; |
1835 | std::shared_ptr<mf::Session> new_session; |
1836 | + mtd::StubInputTargetListener input_target_listener; |
1837 | |
1838 | msh::SessionManager session_manager( |
1839 | mt::fake_shared(surface_factory), |
1840 | container, |
1841 | mt::fake_shared(sequence), |
1842 | - mt::fake_shared(focus_changer)); |
1843 | - |
1844 | - EXPECT_CALL(focus_changer, set_focus_to(_)).Times(3); |
1845 | + mt::fake_shared(focus_setter), |
1846 | + mt::fake_shared(input_target_listener)); |
1847 | + |
1848 | + EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3); |
1849 | |
1850 | auto session1 = session_manager.open_session("Visual Basic Studio"); |
1851 | auto session2 = session_manager.open_session("Microsoft Access"); |
1852 | @@ -64,9 +68,9 @@ |
1853 | |
1854 | { |
1855 | InSequence seq; |
1856 | - EXPECT_CALL(focus_changer, set_focus_to(Eq(session1))).Times(1); |
1857 | - EXPECT_CALL(focus_changer, set_focus_to(Eq(session2))).Times(1); |
1858 | - EXPECT_CALL(focus_changer, set_focus_to(Eq(session3))).Times(1); |
1859 | + EXPECT_CALL(focus_setter, set_focus_to(Eq(session1))).Times(1); |
1860 | + EXPECT_CALL(focus_setter, set_focus_to(Eq(session2))).Times(1); |
1861 | + EXPECT_CALL(focus_setter, set_focus_to(Eq(session3))).Times(1); |
1862 | } |
1863 | |
1864 | session_manager.focus_next(); |
1865 | @@ -77,19 +81,22 @@ |
1866 | TEST(TestSessionManagerAndFocusSelectionStrategy, closing_applications_transfers_focus) |
1867 | { |
1868 | using namespace ::testing; |
1869 | + |
1870 | mtd::MockSurfaceFactory surface_factory; |
1871 | - std::shared_ptr<msh::DefaultSessionContainer> model(new msh::DefaultSessionContainer()); |
1872 | - msh::RegistrationOrderFocusSequence sequence(model); |
1873 | - mtd::MockFocusSetter focus_changer; |
1874 | + std::shared_ptr<msh::DefaultSessionContainer> container(new msh::DefaultSessionContainer()); |
1875 | + msh::RegistrationOrderFocusSequence sequence(container); |
1876 | + mtd::MockFocusSetter focus_setter; |
1877 | std::shared_ptr<mf::Session> new_session; |
1878 | + mtd::StubInputTargetListener input_target_listener; |
1879 | |
1880 | msh::SessionManager session_manager( |
1881 | - mt::fake_shared(surface_factory), |
1882 | - model, |
1883 | - mt::fake_shared(sequence), |
1884 | - mt::fake_shared(focus_changer)); |
1885 | + mt::fake_shared(surface_factory), |
1886 | + container, |
1887 | + mt::fake_shared(sequence), |
1888 | + mt::fake_shared(focus_setter), |
1889 | + mt::fake_shared(input_target_listener)); |
1890 | |
1891 | - EXPECT_CALL(focus_changer, set_focus_to(_)).Times(3); |
1892 | + EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3); |
1893 | |
1894 | auto session1 = session_manager.open_session("Visual Basic Studio"); |
1895 | auto session2 = session_manager.open_session("Microsoft Access"); |
1896 | @@ -97,8 +104,8 @@ |
1897 | |
1898 | { |
1899 | InSequence seq; |
1900 | - EXPECT_CALL(focus_changer, set_focus_to(Eq(session2))).Times(1); |
1901 | - EXPECT_CALL(focus_changer, set_focus_to(Eq(session1))).Times(1); |
1902 | + EXPECT_CALL(focus_setter, set_focus_to(Eq(session2))).Times(1); |
1903 | + EXPECT_CALL(focus_setter, set_focus_to(Eq(session1))).Times(1); |
1904 | } |
1905 | |
1906 | session_manager.close_session(session3); |
1907 | |
1908 | === modified file 'tests/mir_test_doubles/fake_event_hub.cpp' |
1909 | --- tests/mir_test_doubles/fake_event_hub.cpp 2013-03-29 16:51:35 +0000 |
1910 | +++ tests/mir_test_doubles/fake_event_hub.cpp 2013-04-22 21:32:25 +0000 |
1911 | @@ -322,7 +322,7 @@ |
1912 | void mia::FakeEventHub::synthesize_event(const mis::ButtonParameters ¶meters) |
1913 | { |
1914 | RawEvent event; |
1915 | - event.when = 0; // TODO: This may need a timestamp to go over the wire ~racarr |
1916 | + event.when = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); |
1917 | event.type = EV_KEY; |
1918 | event.code = parameters.button; |
1919 | |
1920 | @@ -348,7 +348,7 @@ |
1921 | void mia::FakeEventHub::synthesize_event(const mis::MotionParameters ¶meters) |
1922 | { |
1923 | RawEvent event; |
1924 | - event.when = 0; |
1925 | + event.when = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); |
1926 | event.type = EV_REL; |
1927 | if (parameters.device_id) |
1928 | event.deviceId = parameters.device_id; |
1929 | |
1930 | === modified file 'tests/mir_test_framework/testing_server_options.cpp' |
1931 | --- tests/mir_test_framework/testing_server_options.cpp 2013-04-18 15:20:45 +0000 |
1932 | +++ tests/mir_test_framework/testing_server_options.cpp 2013-04-22 21:32:25 +0000 |
1933 | @@ -29,7 +29,7 @@ |
1934 | #include "mir/compositor/graphic_buffer_allocator.h" |
1935 | #include "mir/input/input_channel.h" |
1936 | #include "mir/input/input_manager.h" |
1937 | -#include "mir/shell/input_focus_selector.h" |
1938 | +#include "mir/input/null_input_target_listener.h" |
1939 | #include "src/server/input/android/android_input_manager.h" |
1940 | #include "src/server/input/android/android_dispatcher_controller.h" |
1941 | |
1942 | @@ -159,14 +159,6 @@ |
1943 | } |
1944 | }; |
1945 | |
1946 | -class StubInputFocusSelector : public msh::InputFocusSelector |
1947 | -{ |
1948 | -public: |
1949 | - void set_input_focus_to(std::shared_ptr<mi::SessionTarget> const& /* session */, std::shared_ptr<mi::SurfaceTarget> const& /* surface */) |
1950 | - { |
1951 | - } |
1952 | -}; |
1953 | - |
1954 | } |
1955 | |
1956 | mtf::TestingServerConfiguration::TestingServerConfiguration() : |
1957 | @@ -184,14 +176,14 @@ |
1958 | return std::make_shared<StubInputManager>(); |
1959 | } |
1960 | |
1961 | -std::shared_ptr<msh::InputFocusSelector> mtf::TestingServerConfiguration::the_input_focus_selector() |
1962 | +std::shared_ptr<msh::InputTargetListener> mtf::TestingServerConfiguration::the_input_target_listener() |
1963 | { |
1964 | auto options = the_options(); |
1965 | |
1966 | if (options->get("tests-use-real-input", false)) |
1967 | return std::make_shared<mia::DispatcherController>(the_input_configuration()); |
1968 | else |
1969 | - return std::make_shared<StubInputFocusSelector>(); |
1970 | + return std::make_shared<mi::NullInputTargetListener>(); |
1971 | } |
1972 | |
1973 | std::shared_ptr<mg::Platform> mtf::TestingServerConfiguration::the_graphics_platform() |
1974 | |
1975 | === modified file 'tests/unit-tests/input/android/test_android_dispatcher_controller.cpp' |
1976 | --- tests/unit-tests/input/android/test_android_dispatcher_controller.cpp 2013-04-15 14:39:18 +0000 |
1977 | +++ tests/unit-tests/input/android/test_android_dispatcher_controller.cpp 2013-04-22 21:32:25 +0000 |
1978 | @@ -31,6 +31,8 @@ |
1979 | #include <sys/types.h> |
1980 | #include <sys/socket.h> |
1981 | |
1982 | +#include <stdexcept> |
1983 | + |
1984 | namespace mi = mir::input; |
1985 | namespace mia = mi::android; |
1986 | namespace mt = mir::test; |
1987 | @@ -47,12 +49,16 @@ |
1988 | void SetUp() override |
1989 | { |
1990 | test_input_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); |
1991 | + |
1992 | + dispatcher = new mtd::MockInputDispatcher(); |
1993 | } |
1994 | void TearDown() override |
1995 | { |
1996 | close(test_input_fd); |
1997 | } |
1998 | int test_input_fd; |
1999 | + droidinput::sp<mtd::MockInputDispatcher> dispatcher; |
2000 | + mtd::MockInputConfiguration config; |
2001 | }; |
2002 | |
2003 | static bool |
2004 | @@ -104,12 +110,116 @@ |
2005 | |
2006 | } |
2007 | |
2008 | -TEST_F(AndroidDispatcherControllerFdSetup, set_input_focus) |
2009 | -{ |
2010 | - using namespace ::testing; |
2011 | - |
2012 | - auto dispatcher = new mtd::MockInputDispatcher(); // We need droidinput::sp |
2013 | - mtd::MockInputConfiguration config; |
2014 | +TEST_F(AndroidDispatcherControllerFdSetup, input_application_opened_behavior) |
2015 | +{ |
2016 | + using namespace ::testing; |
2017 | + |
2018 | + EXPECT_CALL(config, the_dispatcher()).Times(1) |
2019 | + .WillOnce(Return(dispatcher)); |
2020 | + mia::DispatcherController controller(mt::fake_shared(config)); |
2021 | + |
2022 | + auto session = std::make_shared<mtd::StubSessionTarget>(); |
2023 | + controller.input_application_opened(session); |
2024 | + EXPECT_THROW({ |
2025 | + // An application can not be opened twice! |
2026 | + controller.input_application_opened(session); |
2027 | + }, std::logic_error); |
2028 | +} |
2029 | + |
2030 | +TEST_F(AndroidDispatcherControllerFdSetup, input_application_closed_behavior) |
2031 | +{ |
2032 | + using namespace ::testing; |
2033 | + |
2034 | + EXPECT_CALL(config, the_dispatcher()).Times(1) |
2035 | + .WillOnce(Return(dispatcher)); |
2036 | + mia::DispatcherController controller(mt::fake_shared(config)); |
2037 | + |
2038 | + auto session = std::make_shared<mtd::StubSessionTarget>(); |
2039 | + EXPECT_THROW({ |
2040 | + // We can't close an application which is not open |
2041 | + controller.input_application_closed(session); |
2042 | + }, std::logic_error); |
2043 | + controller.input_application_opened(session); |
2044 | + controller.input_application_closed(session); |
2045 | + EXPECT_THROW({ |
2046 | + // Nor can we close an application twice |
2047 | + controller.input_application_closed(session); |
2048 | + }, std::logic_error); |
2049 | +} |
2050 | + |
2051 | +TEST_F(AndroidDispatcherControllerFdSetup, input_surface_opened_behavior) |
2052 | +{ |
2053 | + using namespace ::testing; |
2054 | + |
2055 | + auto session = std::make_shared<mtd::StubSessionTarget>(); |
2056 | + auto surface = std::make_shared<mtd::StubSurfaceTarget>(test_input_fd); |
2057 | + |
2058 | + EXPECT_CALL(config, the_dispatcher()).Times(1) |
2059 | + .WillOnce(Return(dispatcher)); |
2060 | + EXPECT_CALL(*dispatcher, registerInputChannel(_, WindowHandleFor(session, surface), false)).Times(1) |
2061 | + .WillOnce(Return(droidinput::OK)); |
2062 | + |
2063 | + mia::DispatcherController controller(mt::fake_shared(config)); |
2064 | + |
2065 | + EXPECT_THROW({ |
2066 | + // We can't open a surface with an unopened session! |
2067 | + controller.input_surface_opened(session, surface); |
2068 | + }, std::logic_error); |
2069 | + controller.input_application_opened(session); |
2070 | + controller.input_surface_opened(session, surface); |
2071 | + EXPECT_THROW({ |
2072 | + // We can't open a surface twice |
2073 | + controller.input_surface_opened(session, surface); |
2074 | + }, std::logic_error); |
2075 | +} |
2076 | + |
2077 | +TEST_F(AndroidDispatcherControllerFdSetup, input_surface_closed_behavior) |
2078 | +{ |
2079 | + using namespace ::testing; |
2080 | + |
2081 | + auto session = std::make_shared<mtd::StubSessionTarget>(); |
2082 | + auto surface = std::make_shared<mtd::StubSurfaceTarget>(test_input_fd); |
2083 | + |
2084 | + EXPECT_CALL(config, the_dispatcher()).Times(1) |
2085 | + .WillOnce(Return(dispatcher)); |
2086 | + EXPECT_CALL(*dispatcher, registerInputChannel(_, WindowHandleFor(session, surface), false)).Times(1) |
2087 | + .WillOnce(Return(droidinput::OK)); |
2088 | + EXPECT_CALL(*dispatcher, unregisterInputChannel(_)).Times(1); |
2089 | + mia::DispatcherController controller(mt::fake_shared(config)); |
2090 | + |
2091 | + controller.input_application_opened(session); |
2092 | + |
2093 | + EXPECT_THROW({ |
2094 | + // We can't close a surface which hasn't been opened |
2095 | + controller.input_surface_closed(surface); |
2096 | + }, std::logic_error); |
2097 | + controller.input_surface_opened(session, surface); |
2098 | + controller.input_surface_closed(surface); |
2099 | + EXPECT_THROW({ |
2100 | + // Nor can we close a surface twice |
2101 | + controller.input_surface_closed(surface); |
2102 | + }, std::logic_error); |
2103 | +} |
2104 | + |
2105 | +TEST_F(AndroidDispatcherControllerFdSetup, on_focus_cleared) |
2106 | +{ |
2107 | + using namespace ::testing; |
2108 | + |
2109 | + EXPECT_CALL(config, the_dispatcher()).Times(1) |
2110 | + .WillOnce(Return(dispatcher)); |
2111 | + |
2112 | + EXPECT_CALL(*dispatcher, setFocusedApplication(droidinput::sp<droidinput::InputApplicationHandle>(0))).Times(1); |
2113 | + EXPECT_CALL(*dispatcher, setInputWindows(EmptyVector())).Times(1); |
2114 | + |
2115 | + mia::DispatcherController controller(mt::fake_shared(config)); |
2116 | + |
2117 | + controller.focus_cleared(); |
2118 | +} |
2119 | + |
2120 | +TEST_F(AndroidDispatcherControllerFdSetup, on_focus_changed) |
2121 | +{ |
2122 | + using namespace ::testing; |
2123 | + |
2124 | EXPECT_CALL(config, the_dispatcher()).Times(1) |
2125 | .WillOnce(Return(dispatcher)); |
2126 | |
2127 | @@ -119,15 +229,30 @@ |
2128 | { |
2129 | InSequence seq; |
2130 | EXPECT_CALL(*dispatcher, setFocusedApplication(ApplicationHandleFor(session))).Times(1); |
2131 | - EXPECT_CALL(*dispatcher, registerInputChannel(_, WindowHandleFor(session, surface), false)).Times(1) |
2132 | - .WillOnce(Return(droidinput::OK)); |
2133 | EXPECT_CALL(*dispatcher, setInputWindows(VectorContainingWindowHandleFor(session, surface))).Times(1); |
2134 | - EXPECT_CALL(*dispatcher, unregisterInputChannel(_)).Times(1); |
2135 | - EXPECT_CALL(*dispatcher, setInputWindows(EmptyVector())).Times(1); |
2136 | } |
2137 | |
2138 | mia::DispatcherController controller(mt::fake_shared(config)); |
2139 | - |
2140 | - controller.set_input_focus_to(session, surface); |
2141 | - controller.set_input_focus_to(session, std::shared_ptr<mi::SurfaceTarget>()); |
2142 | + |
2143 | + controller.input_application_opened(session); |
2144 | + controller.input_surface_opened(session, surface); |
2145 | + |
2146 | + controller.focus_changed(surface); |
2147 | +} |
2148 | + |
2149 | +TEST_F(AndroidDispatcherControllerFdSetup, on_focus_changed_throw_behavior) |
2150 | +{ |
2151 | + using namespace ::testing; |
2152 | + |
2153 | + EXPECT_CALL(config, the_dispatcher()).Times(1) |
2154 | + .WillOnce(Return(dispatcher)); |
2155 | + |
2156 | + auto surface = std::make_shared<mtd::StubSurfaceTarget>(test_input_fd); |
2157 | + |
2158 | + mia::DispatcherController controller(mt::fake_shared(config)); |
2159 | + |
2160 | + EXPECT_THROW({ |
2161 | + // We can't focus surfaces which never opened |
2162 | + controller.focus_changed(surface); |
2163 | + }, std::logic_error); |
2164 | } |
2165 | |
2166 | === modified file 'tests/unit-tests/input/android/test_android_input_window_handle.cpp' |
2167 | --- tests/unit-tests/input/android/test_android_input_window_handle.cpp 2013-04-04 11:26:58 +0000 |
2168 | +++ tests/unit-tests/input/android/test_android_input_window_handle.cpp 2013-04-22 21:32:25 +0000 |
2169 | @@ -52,6 +52,7 @@ |
2170 | struct MockSurfaceTarget : public mi::SurfaceTarget |
2171 | { |
2172 | MOCK_CONST_METHOD0(server_input_fd, int()); |
2173 | + MOCK_CONST_METHOD0(top_left, geom::Point()); |
2174 | MOCK_CONST_METHOD0(size, geom::Size()); |
2175 | MOCK_CONST_METHOD0(name, std::string()); |
2176 | }; |
2177 | @@ -64,6 +65,7 @@ |
2178 | |
2179 | geom::Size const default_surface_size = geom::Size{geom::Width{256}, |
2180 | geom::Height{256}}; |
2181 | + geom::Point const default_surface_top_left = geom::Point{geom::X{10}, geom::Y{10}}; |
2182 | std::string const testing_surface_name = "Test"; |
2183 | |
2184 | // We need a real open fd, as InputWindowHandle's constructor will fcntl() it, and |
2185 | @@ -81,6 +83,8 @@ |
2186 | // for touch/pointer events we will need a position |
2187 | EXPECT_CALL(surface, size()).Times(1) |
2188 | .WillOnce(Return(default_surface_size)); |
2189 | + EXPECT_CALL(surface, top_left()).Times(1) |
2190 | + .WillOnce(Return(default_surface_top_left)); |
2191 | EXPECT_CALL(surface, name()).Times(1) |
2192 | .WillOnce(Return(testing_surface_name)); |
2193 | |
2194 | @@ -93,8 +97,15 @@ |
2195 | |
2196 | EXPECT_EQ(testing_server_fd, info->inputChannel->getFd()); |
2197 | |
2198 | + EXPECT_EQ(default_surface_top_left.x.as_uint32_t(), (uint32_t)(info->frameLeft)); |
2199 | + EXPECT_EQ(default_surface_top_left.y.as_uint32_t(), (uint32_t)(info->frameTop)); |
2200 | EXPECT_EQ(default_surface_size.height.as_uint32_t(), (uint32_t)(info->frameRight - info->frameLeft)); |
2201 | EXPECT_EQ(default_surface_size.height.as_uint32_t(), (uint32_t)(info->frameBottom - info->frameTop)); |
2202 | |
2203 | + EXPECT_EQ(info->frameLeft, info->touchableRegionLeft); |
2204 | + EXPECT_EQ(info->frameTop, info->touchableRegionTop); |
2205 | + EXPECT_EQ(info->frameRight, info->touchableRegionRight); |
2206 | + EXPECT_EQ(info->frameBottom, info->touchableRegionBottom); |
2207 | + |
2208 | free(filename); |
2209 | } |
2210 | |
2211 | === modified file 'tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp' |
2212 | --- tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp 2013-03-22 16:41:59 +0000 |
2213 | +++ tests/unit-tests/input/android/test_event_filter_input_dispatcher_policy.cpp 2013-04-22 21:32:25 +0000 |
2214 | @@ -32,12 +32,12 @@ |
2215 | namespace mt = mir::test; |
2216 | namespace mtd = mir::test::doubles; |
2217 | |
2218 | -TEST(EventFilterDispatcherPolicy, offers_events_to_filter) |
2219 | +TEST(EventFilterDispatcherPolicy, offers_key_events_to_filter) |
2220 | { |
2221 | using namespace ::testing; |
2222 | droidinput::KeyEvent ev; |
2223 | mtd::MockEventFilter filter; |
2224 | - mia::EventFilterDispatcherPolicy policy(mt::fake_shared(filter)); |
2225 | + mia::EventFilterDispatcherPolicy policy(mt::fake_shared(filter), true); |
2226 | uint32_t policy_flags; |
2227 | |
2228 | EXPECT_CALL(filter, handles(_)).Times(1).WillOnce(Return(false)); |
2229 | @@ -53,3 +53,16 @@ |
2230 | EXPECT_TRUE(policy.filterInputEvent(&ev, 0)); |
2231 | } |
2232 | |
2233 | +TEST(EventFilterDispatcherPolicy, motion_events_are_allowed_to_pass_to_clients) |
2234 | +{ |
2235 | + using namespace ::testing; |
2236 | + |
2237 | + mtd::MockEventFilter filter; |
2238 | + mia::EventFilterDispatcherPolicy policy(mt::fake_shared(filter), true); |
2239 | + |
2240 | + uint32_t policy_flags; |
2241 | + policy.interceptMotionBeforeQueueing(0, policy_flags); |
2242 | + |
2243 | + // All motion events are allowed. Of course they could later be removed by the input filter. |
2244 | + EXPECT_TRUE(policy_flags & droidinput::POLICY_FLAG_PASS_TO_USER); |
2245 | +} |
2246 | |
2247 | === modified file 'tests/unit-tests/shell/test_application_session.cpp' |
2248 | --- tests/unit-tests/shell/test_application_session.cpp 2013-04-17 18:18:31 +0000 |
2249 | +++ tests/unit-tests/shell/test_application_session.cpp 2013-04-22 21:32:25 +0000 |
2250 | @@ -22,6 +22,7 @@ |
2251 | #include "mir_test/fake_shared.h" |
2252 | #include "mir_test_doubles/mock_surface_factory.h" |
2253 | #include "mir_test_doubles/mock_surface.h" |
2254 | +#include "mir_test_doubles/stub_input_target_listener.h" |
2255 | #include "mir_test_doubles/stub_surface_builder.h" |
2256 | #include "mir_test_doubles/stub_surface.h" |
2257 | |
2258 | @@ -51,7 +52,8 @@ |
2259 | EXPECT_CALL(surface_factory, create_surface(_)); |
2260 | EXPECT_CALL(*mock_surface, destroy()); |
2261 | |
2262 | - msh::ApplicationSession session(mt::fake_shared(surface_factory), "Foo"); |
2263 | + mtd::StubInputTargetListener input_listener; |
2264 | + msh::ApplicationSession session(mt::fake_shared(surface_factory), mt::fake_shared(input_listener), "Foo"); |
2265 | |
2266 | mf::SurfaceCreationParameters params; |
2267 | auto surf = session.create_surface(params); |
2268 | @@ -75,7 +77,8 @@ |
2269 | .WillOnce(Return(std::make_shared<NiceMock<mtd::MockSurface>>(mt::fake_shared(surface_builder)))); |
2270 | } |
2271 | |
2272 | - msh::ApplicationSession app_session(mt::fake_shared(surface_factory), "Foo"); |
2273 | + mtd::StubInputTargetListener input_listener; |
2274 | + msh::ApplicationSession app_session(mt::fake_shared(surface_factory), mt::fake_shared(input_listener), "Foo"); |
2275 | |
2276 | mf::SurfaceCreationParameters params; |
2277 | auto id1 = app_session.create_surface(params); |
2278 | @@ -105,7 +108,8 @@ |
2279 | mtd::MockSurfaceFactory surface_factory; |
2280 | ON_CALL(surface_factory, create_surface(_)).WillByDefault(Return(mock_surface)); |
2281 | |
2282 | - msh::ApplicationSession app_session(mt::fake_shared(surface_factory), "Foo"); |
2283 | + mtd::StubInputTargetListener input_listener; |
2284 | + msh::ApplicationSession app_session(mt::fake_shared(surface_factory), mt::fake_shared(input_listener), "Foo"); |
2285 | |
2286 | EXPECT_CALL(surface_factory, create_surface(_)); |
2287 | |
2288 | @@ -130,7 +134,8 @@ |
2289 | using namespace ::testing; |
2290 | |
2291 | mtd::MockSurfaceFactory surface_factory; |
2292 | - msh::ApplicationSession app_session(mt::fake_shared(surface_factory), "Foo"); |
2293 | + mtd::StubInputTargetListener input_listener; |
2294 | + msh::ApplicationSession app_session(mt::fake_shared(surface_factory), mt::fake_shared(input_listener), "Foo"); |
2295 | mf::SurfaceId invalid_surface_id(1); |
2296 | |
2297 | EXPECT_THROW({ |
2298 | @@ -143,7 +148,8 @@ |
2299 | using namespace ::testing; |
2300 | |
2301 | mtd::MockSurfaceFactory surface_factory; |
2302 | - msh::ApplicationSession app_session(mt::fake_shared(surface_factory), "Foo"); |
2303 | + mtd::StubInputTargetListener input_listener; |
2304 | + msh::ApplicationSession app_session(mt::fake_shared(surface_factory), mt::fake_shared(input_listener), "Foo"); |
2305 | mf::SurfaceId invalid_surface_id(1); |
2306 | |
2307 | EXPECT_THROW({ |
2308 | |
2309 | === modified file 'tests/unit-tests/shell/test_registration_order_focus_sequence.cpp' |
2310 | --- tests/unit-tests/shell/test_registration_order_focus_sequence.cpp 2013-04-18 00:00:55 +0000 |
2311 | +++ tests/unit-tests/shell/test_registration_order_focus_sequence.cpp 2013-04-22 21:32:25 +0000 |
2312 | @@ -22,8 +22,11 @@ |
2313 | #include "mir/shell/registration_order_focus_sequence.h" |
2314 | #include "mir/frontend/surface_creation_parameters.h" |
2315 | #include "mir/surfaces/surface.h" |
2316 | + |
2317 | #include "mir_test_doubles/mock_buffer_bundle.h" |
2318 | #include "mir_test_doubles/mock_surface_factory.h" |
2319 | +#include "mir_test_doubles/stub_input_target_listener.h" |
2320 | +#include "mir_test/fake_shared.h" |
2321 | |
2322 | #include <gmock/gmock.h> |
2323 | #include <gtest/gtest.h> |
2324 | @@ -32,7 +35,8 @@ |
2325 | namespace mc = mir::compositor; |
2326 | namespace msh = mir::shell; |
2327 | namespace ms = mir::surfaces; |
2328 | -namespace mtd = mir::test::doubles; |
2329 | +namespace mt = mir::test; |
2330 | +namespace mtd = mt::doubles; |
2331 | |
2332 | namespace |
2333 | { |
2334 | @@ -45,6 +49,7 @@ |
2335 | } |
2336 | std::shared_ptr<mtd::MockSurfaceFactory> factory; |
2337 | std::shared_ptr<msh::DefaultSessionContainer> container; |
2338 | + mtd::StubInputTargetListener input_listener; |
2339 | |
2340 | static std::string const testing_app_name1; |
2341 | static std::string const testing_app_name2; |
2342 | @@ -60,9 +65,9 @@ |
2343 | { |
2344 | using namespace ::testing; |
2345 | |
2346 | - auto app1 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name1); |
2347 | - auto app2 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name2); |
2348 | - auto app3 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name3); |
2349 | + auto app1 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name1); |
2350 | + auto app2 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name2); |
2351 | + auto app3 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name3); |
2352 | |
2353 | container->insert_session(app1); |
2354 | container->insert_session(app2); |
2355 | @@ -78,9 +83,9 @@ |
2356 | { |
2357 | using namespace ::testing; |
2358 | |
2359 | - auto app1 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name1); |
2360 | - auto app2 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name2); |
2361 | - auto app3 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name3); |
2362 | + auto app1 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name1); |
2363 | + auto app2 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name2); |
2364 | + auto app3 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name3); |
2365 | container->insert_session(app1); |
2366 | container->insert_session(app2); |
2367 | container->insert_session(app3); |
2368 | @@ -95,7 +100,7 @@ |
2369 | { |
2370 | using namespace ::testing; |
2371 | |
2372 | - auto app1 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name1); |
2373 | + auto app1 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name1); |
2374 | container->insert_session(app1); |
2375 | |
2376 | msh::RegistrationOrderFocusSequence focus_sequence(container); |
2377 | @@ -107,8 +112,8 @@ |
2378 | { |
2379 | using namespace ::testing; |
2380 | |
2381 | - auto app1 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name1); |
2382 | - auto app2 = std::make_shared<msh::ApplicationSession>(factory, testing_app_name2); |
2383 | + auto app1 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name1); |
2384 | + auto app2 = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name2); |
2385 | auto null_session = std::shared_ptr<msh::ApplicationSession>(); |
2386 | |
2387 | msh::RegistrationOrderFocusSequence focus_sequence(container); |
2388 | @@ -124,7 +129,7 @@ |
2389 | { |
2390 | using namespace ::testing; |
2391 | |
2392 | - auto invalid_session = std::make_shared<msh::ApplicationSession>(factory, testing_app_name1); |
2393 | + auto invalid_session = std::make_shared<msh::ApplicationSession>(factory, mt::fake_shared(input_listener), testing_app_name1); |
2394 | auto null_session = std::shared_ptr<msh::ApplicationSession>(); |
2395 | |
2396 | msh::RegistrationOrderFocusSequence focus_sequence(container); |
2397 | |
2398 | === modified file 'tests/unit-tests/shell/test_session_manager.cpp' |
2399 | --- tests/unit-tests/shell/test_session_manager.cpp 2013-04-18 22:29:24 +0000 |
2400 | +++ tests/unit-tests/shell/test_session_manager.cpp 2013-04-22 21:32:25 +0000 |
2401 | @@ -21,15 +21,19 @@ |
2402 | #include "mir/shell/session_manager.h" |
2403 | #include "mir/shell/default_session_container.h" |
2404 | #include "mir/shell/session.h" |
2405 | +#include "mir/shell/input_target_listener.h" |
2406 | #include "mir/frontend/surface_creation_parameters.h" |
2407 | #include "mir/surfaces/surface.h" |
2408 | #include "mir/input/input_channel.h" |
2409 | + |
2410 | +#include "mir_test/fake_shared.h" |
2411 | #include "mir_test_doubles/mock_buffer_bundle.h" |
2412 | -#include "mir_test/fake_shared.h" |
2413 | #include "mir_test_doubles/mock_surface_factory.h" |
2414 | #include "mir_test_doubles/mock_focus_setter.h" |
2415 | #include "mir_test_doubles/null_buffer_bundle.h" |
2416 | #include "mir_test_doubles/stub_surface_builder.h" |
2417 | +#include "mir_test_doubles/stub_input_target_listener.h" |
2418 | +#include "mir_test_doubles/mock_input_target_listener.h" |
2419 | |
2420 | #include "mir/shell/surface.h" |
2421 | |
2422 | @@ -56,7 +60,7 @@ |
2423 | ~MockSessionContainer() noexcept {} |
2424 | }; |
2425 | |
2426 | -struct MockFocusSequence: public msh::FocusSequence |
2427 | +struct MockFocusSequence : public msh::FocusSequence |
2428 | { |
2429 | MOCK_CONST_METHOD1(successor_of, std::shared_ptr<msh::Session>(std::shared_ptr<msh::Session> const&)); |
2430 | MOCK_CONST_METHOD1(predecessor_of, std::shared_ptr<msh::Session>(std::shared_ptr<msh::Session> const&)); |
2431 | @@ -68,16 +72,18 @@ |
2432 | SessionManagerSetup() |
2433 | : session_manager(mt::fake_shared(surface_factory), |
2434 | mt::fake_shared(container), |
2435 | - mt::fake_shared(sequence), |
2436 | - mt::fake_shared(focus_setter)) |
2437 | + mt::fake_shared(focus_sequence), |
2438 | + mt::fake_shared(focus_setter), |
2439 | + mt::fake_shared(input_target_listener)) |
2440 | { |
2441 | } |
2442 | |
2443 | mtd::StubSurfaceBuilder surface_builder; |
2444 | mtd::MockSurfaceFactory surface_factory; |
2445 | testing::NiceMock<MockSessionContainer> container; // Inelegant but some tests need a stub |
2446 | - MockFocusSequence sequence; |
2447 | + MockFocusSequence focus_sequence; |
2448 | testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub |
2449 | + mtd::StubInputTargetListener input_target_listener; |
2450 | |
2451 | msh::SessionManager session_manager; |
2452 | }; |
2453 | @@ -93,7 +99,7 @@ |
2454 | EXPECT_CALL(focus_setter, set_focus_to(_)); |
2455 | EXPECT_CALL(focus_setter, set_focus_to(std::shared_ptr<msh::Session>())).Times(1); |
2456 | |
2457 | - EXPECT_CALL(sequence, default_focus()).WillOnce(Return((std::shared_ptr<msh::Session>()))); |
2458 | + EXPECT_CALL(focus_sequence, default_focus()).WillOnce(Return((std::shared_ptr<msh::Session>()))); |
2459 | |
2460 | auto session = session_manager.open_session("Visual Basic Studio"); |
2461 | session_manager.close_session(session); |
2462 | @@ -118,7 +124,7 @@ |
2463 | EXPECT_CALL(focus_setter, set_focus_to(_)).Times(1); |
2464 | EXPECT_CALL(focus_setter, set_focus_to(std::shared_ptr<msh::Session>())).Times(1); |
2465 | |
2466 | - EXPECT_CALL(sequence, default_focus()).WillOnce(Return((std::shared_ptr<msh::Session>()))); |
2467 | + EXPECT_CALL(focus_sequence, default_focus()).WillOnce(Return((std::shared_ptr<msh::Session>()))); |
2468 | |
2469 | auto session = session_manager.open_session("Visual Basic Studio"); |
2470 | session->create_surface(mf::a_surface().of_size(geom::Size{geom::Width{1024}, geom::Height{768}})); |
2471 | @@ -164,7 +170,7 @@ |
2472 | session_manager.tag_session_with_lightdm_id(session1, 1); |
2473 | session_manager.focus_session_with_lightdm_id(1); |
2474 | |
2475 | - EXPECT_CALL(sequence, default_focus()).WillOnce(Return(shell_session2)); |
2476 | + EXPECT_CALL(focus_sequence, default_focus()).WillOnce(Return(shell_session2)); |
2477 | EXPECT_CALL(focus_setter, set_focus_to(Eq(shell_session2))); |
2478 | |
2479 | session_manager.close_session(session1); |
2480 | @@ -193,3 +199,61 @@ |
2481 | session_manager.create_surface_for(session1, mf::a_surface()); |
2482 | } |
2483 | |
2484 | +namespace |
2485 | +{ |
2486 | + |
2487 | +struct SessionManagerInputTargetListenerSetup : public testing::Test |
2488 | +{ |
2489 | + SessionManagerInputTargetListenerSetup() |
2490 | + : session_manager(mt::fake_shared(surface_factory), |
2491 | + mt::fake_shared(container), |
2492 | + mt::fake_shared(focus_sequence), |
2493 | + mt::fake_shared(focus_setter), |
2494 | + mt::fake_shared(input_target_listener)) |
2495 | + { |
2496 | + } |
2497 | + |
2498 | + mtd::StubSurfaceBuilder surface_builder; |
2499 | + mtd::MockSurfaceFactory surface_factory; |
2500 | + testing::NiceMock<MockSessionContainer> container; // Inelegant but some tests need a stub |
2501 | + testing::NiceMock<MockFocusSequence> focus_sequence; |
2502 | + testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub |
2503 | + mtd::MockInputTargetListener input_target_listener; |
2504 | + |
2505 | + msh::SessionManager session_manager; |
2506 | +}; |
2507 | + |
2508 | +} |
2509 | + |
2510 | +TEST_F(SessionManagerInputTargetListenerSetup, listener_is_notified_of_session_and_surfacelifecycle) |
2511 | +{ |
2512 | + using namespace ::testing; |
2513 | + |
2514 | + std::shared_ptr<mi::InputChannel> null_input_channel; |
2515 | + ON_CALL(surface_factory, create_surface(_)).WillByDefault( |
2516 | + Return(std::make_shared<msh::Surface>( |
2517 | + mt::fake_shared(surface_builder), |
2518 | + mf::a_surface(), |
2519 | + null_input_channel))); |
2520 | + |
2521 | + EXPECT_CALL(focus_sequence, default_focus()).WillOnce(Return((std::shared_ptr<msh::Session>()))); |
2522 | + { |
2523 | + InSequence seq; |
2524 | + |
2525 | + EXPECT_CALL(input_target_listener, input_application_opened(_)) |
2526 | + .Times(1); |
2527 | + EXPECT_CALL(input_target_listener, input_surface_opened(_, _)).Times(1); |
2528 | + EXPECT_CALL(input_target_listener, focus_changed(_)).Times(1); |
2529 | + EXPECT_CALL(input_target_listener, input_surface_closed(_)).Times(1); |
2530 | + EXPECT_CALL(input_target_listener, input_application_closed(_)) |
2531 | + .Times(1); |
2532 | + EXPECT_CALL(input_target_listener, focus_cleared()).Times(1); |
2533 | + } |
2534 | + |
2535 | + { |
2536 | + auto session = session_manager.open_session("test"); |
2537 | + auto surf = session_manager.create_surface_for(session, mf::a_surface()); |
2538 | + session->destroy_surface(surf); |
2539 | + session_manager.close_session(session); |
2540 | + } |
2541 | +} |
2542 | |
2543 | === modified file 'tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp' |
2544 | --- tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp 2013-04-19 15:33:04 +0000 |
2545 | +++ tests/unit-tests/shell/test_single_visibility_focus_mechanism.cpp 2013-04-22 21:32:25 +0000 |
2546 | @@ -27,7 +27,6 @@ |
2547 | #include "mir_test_doubles/mock_buffer_bundle.h" |
2548 | #include "mir_test/fake_shared.h" |
2549 | #include "mir_test_doubles/mock_surface_factory.h" |
2550 | -#include "mir_test_doubles/mock_input_focus_selector.h" |
2551 | #include "mir_test_doubles/stub_surface.h" |
2552 | #include "mir_test_doubles/mock_surface.h" |
2553 | #include "mir_test_doubles/stub_surface_builder.h" |
2554 | @@ -64,8 +63,6 @@ |
2555 | { |
2556 | using namespace ::testing; |
2557 | |
2558 | - NiceMock<mtd::MockInputFocusSelector> input_focus_selector; |
2559 | - |
2560 | NiceMock<MockShellSession> app1, app2, app3; |
2561 | msh::DefaultSessionContainer model; |
2562 | |
2563 | @@ -73,7 +70,7 @@ |
2564 | ON_CALL(app2, default_surface()).WillByDefault(Return(std::shared_ptr<msh::Surface>())); |
2565 | ON_CALL(app3, default_surface()).WillByDefault(Return(std::shared_ptr<msh::Surface>())); |
2566 | |
2567 | - msh::SingleVisibilityFocusMechanism focus_mechanism(mt::fake_shared(model), mt::fake_shared(input_focus_selector)); |
2568 | + msh::SingleVisibilityFocusMechanism focus_mechanism(mt::fake_shared(model)); |
2569 | |
2570 | EXPECT_CALL(app1, show()).Times(1); |
2571 | EXPECT_CALL(app2, hide()).Times(1); |
2572 | @@ -89,23 +86,3 @@ |
2573 | |
2574 | focus_mechanism.set_focus_to(mt::fake_shared(app1)); |
2575 | } |
2576 | - |
2577 | -TEST(SingleVisibilityFocusMechanism, mechanism_sets_input_focus_from_default_surface) |
2578 | -{ |
2579 | - using namespace ::testing; |
2580 | - |
2581 | - mtd::MockInputFocusSelector input_focus_selector; |
2582 | - msh::DefaultSessionContainer model; |
2583 | - auto session = std::make_shared<NiceMock<MockShellSession>>(); |
2584 | - auto surface = std::make_shared<mtd::MockSurface>(std::make_shared<mtd::StubSurfaceBuilder>()); |
2585 | - |
2586 | - msh::SingleVisibilityFocusMechanism focus_mechanism(mt::fake_shared(model), mt::fake_shared(input_focus_selector)); |
2587 | - |
2588 | - EXPECT_CALL(*session, default_surface()).Times(1).WillOnce(Return(surface)); |
2589 | - |
2590 | - EXPECT_CALL(input_focus_selector, set_input_focus_to(Eq(session), Eq(surface))).Times(1); |
2591 | - |
2592 | - model.insert_session(session); |
2593 | - focus_mechanism.set_focus_to(session); |
2594 | -} |
2595 | - |
2596 | |
2597 | === modified file 'tests/unit-tests/shell/test_surface.cpp' |
2598 | --- tests/unit-tests/shell/test_surface.cpp 2013-04-16 17:42:26 +0000 |
2599 | +++ tests/unit-tests/shell/test_surface.cpp 2013-04-22 21:32:25 +0000 |
2600 | @@ -220,6 +220,24 @@ |
2601 | }, std::runtime_error); |
2602 | } |
2603 | |
2604 | +TEST_F(ShellSurface, top_left_throw_behavior) |
2605 | +{ |
2606 | + msh::Surface test( |
2607 | + mt::fake_shared(surface_builder), |
2608 | + mf::a_surface(), |
2609 | + null_input_channel); |
2610 | + |
2611 | + EXPECT_NO_THROW({ |
2612 | + test.top_left(); |
2613 | + }); |
2614 | + |
2615 | + surface_builder.reset_surface(); |
2616 | + |
2617 | + EXPECT_THROW({ |
2618 | + test.top_left(); |
2619 | + }, std::runtime_error); |
2620 | +} |
2621 | + |
2622 | TEST_F(ShellSurface, name_throw_behavior) |
2623 | { |
2624 | msh::Surface test( |
2625 | |
2626 | === modified file 'tests/unit-tests/shell/test_the_session_container_implementation.cpp' |
2627 | --- tests/unit-tests/shell/test_the_session_container_implementation.cpp 2013-04-18 00:00:55 +0000 |
2628 | +++ tests/unit-tests/shell/test_the_session_container_implementation.cpp 2013-04-22 21:32:25 +0000 |
2629 | @@ -22,6 +22,7 @@ |
2630 | #include "mir/frontend/surface_creation_parameters.h" |
2631 | #include "mir/surfaces/surface.h" |
2632 | #include "mir_test_doubles/mock_buffer_bundle.h" |
2633 | +#include "mir_test_doubles/stub_input_target_listener.h" |
2634 | #include "mir_test_doubles/mock_surface_factory.h" |
2635 | |
2636 | #include <gmock/gmock.h> |
2637 | @@ -38,8 +39,10 @@ |
2638 | auto factory = std::make_shared<mtd::MockSurfaceFactory>(); |
2639 | msh::DefaultSessionContainer container; |
2640 | |
2641 | - container.insert_session(std::make_shared<msh::ApplicationSession>(factory, "Visual Studio 7")); |
2642 | - container.insert_session(std::make_shared<msh::ApplicationSession>(factory, "Visual Studio 8")); |
2643 | + container.insert_session(std::make_shared<msh::ApplicationSession>(factory, std::make_shared<mtd::StubInputTargetListener>(), |
2644 | + "Visual Studio 7")); |
2645 | + container.insert_session(std::make_shared<msh::ApplicationSession>(factory, std::make_shared<mtd::StubInputTargetListener>(), |
2646 | + "Visual Studio 8")); |
2647 | |
2648 | struct local |
2649 | { |
2650 | @@ -64,8 +67,8 @@ |
2651 | auto factory = std::make_shared<mtd::MockSurfaceFactory>(); |
2652 | msh::DefaultSessionContainer container; |
2653 | |
2654 | - auto session = std::make_shared<msh::ApplicationSession>(factory, |
2655 | - "Visual Studio 7"); |
2656 | + auto session = std::make_shared<msh::ApplicationSession>(factory, std::make_shared<mtd::StubInputTargetListener>(), |
2657 | + "Visual Studio 7"); |
2658 | EXPECT_THROW({ |
2659 | container.remove_session(session); |
2660 | }, std::logic_error); |
FAILED: Continuous integration, rev:605 /code.launchpad .net/~robertcar r/mir/enable- pointer- touch-input/ +merge/ 160153/ +edit-commit- message
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http:// jenkins. qa.ubuntu. com/job/ mir-ci/ 468/ jenkins. qa.ubuntu. com/job/ mir-android- raring- i386-build/ 498 jenkins. qa.ubuntu. com/job/ mir-clang- raring- amd64-build/ 381 jenkins. qa.ubuntu. com/job/ mir-quantal- amd64-ci/ 473/console
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ mir-ci/ 468/rebuild
http://