Merge lp:~andreas-pokorny/unity-system-compositor/override-orientation-dbus-api into lp:unity-system-compositor
- override-orientation-dbus-api
- Merge into trunk
Proposed by
Andreas Pokorny
Status: | Work in progress |
---|---|
Proposed branch: | lp:~andreas-pokorny/unity-system-compositor/override-orientation-dbus-api |
Merge into: | lp:unity-system-compositor |
Diff against target: |
971 lines (+396/-224) 19 files modified
debian/control (+1/-1) src/CMakeLists.txt (+2/-2) src/cursor_enabler.cpp (+72/-0) src/cursor_enabler.h (+58/-0) src/dbus_screen.cpp (+16/-2) src/dbus_screen.h (+6/-1) src/powerkey_handler.cpp (+16/-9) src/screen_state_handler.cpp (+17/-8) src/server.cpp (+7/-29) src/server.h (+7/-0) src/shell.cpp (+59/-20) src/shell.h (+13/-13) src/surface_coordinator.cpp (+0/-87) src/surface_coordinator.h (+0/-47) src/system_compositor.cpp (+8/-0) src/system_compositor.h (+2/-0) tests/unit-tests/CMakeLists.txt (+1/-0) tests/unit-tests/test_cursor_enabler.cpp (+110/-0) tests/unit-tests/test_session_switcher.cpp (+1/-5) |
To merge this branch: | bzr merge lp:~andreas-pokorny/unity-system-compositor/override-orientation-dbus-api |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity System Compositor Development Team | Pending | ||
Review via email: mp+248896@code.launchpad.net |
Commit message
Ugly hack to have a different orientation for cursors without changing the orientation
Description of the change
Ugly hack to have a different orientation for cursors without changing the orientation
To post a comment you must log in.
Unmerged revisions
- 205. By Andreas Pokorny
-
add a dbus api to override orientation
- 204. By Andreas Pokorny
-
merge event-2.0 changes back in
*fingers-crossed*
- 203. By Andreas Pokorny
-
keep display on when mouse pointer moves
- 202. By Andreas Pokorny
-
merged mirevent-2.0
- 201. By Andreas Pokorny
-
further cleanup drops all references to cursor image again
- 200. By Andreas Pokorny
-
ok nearly
- 199. By Andreas Pokorny
-
merged msh changes
- 198. By Andreas Pokorny
-
merged event-2.0 changes
- 197. By Andreas Pokorny
-
add test and cleanup further
- 196. By Andreas Pokorny
-
Rework Cursor enablement inside Unity-System-
Compositor
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/control' |
2 | --- debian/control 2015-01-07 23:33:32 +0000 |
3 | +++ debian/control 2015-02-06 12:38:32 +0000 |
4 | @@ -19,7 +19,7 @@ |
5 | libglib2.0-dev, |
6 | libgles2-mesa-dev, |
7 | libmirclient-dev (>= 0.6.0), |
8 | - libmirserver-dev (>= 0.10.0), |
9 | + libmirserver-dev (>= 0.11.0), |
10 | libprotobuf-dev, |
11 | pkg-config, |
12 | python:any (>= 2.7), |
13 | |
14 | === modified file 'src/CMakeLists.txt' |
15 | --- src/CMakeLists.txt 2014-11-06 12:18:08 +0000 |
16 | +++ src/CMakeLists.txt 2015-02-06 12:38:32 +0000 |
17 | @@ -16,15 +16,15 @@ |
18 | |
19 | set(USC_SRCS |
20 | asio_dm_connection.cpp |
21 | + cursor_enabler.cpp |
22 | dbus_screen.cpp |
23 | external_spinner.cpp |
24 | powerd_mediator.cpp |
25 | powerkey_handler.cpp |
26 | screen_state_handler.cpp |
27 | server.cpp |
28 | - session_coordinator.cpp |
29 | + shell.cpp |
30 | session_switcher.cpp |
31 | - surface_coordinator.cpp |
32 | system_compositor.cpp |
33 | worker_thread.cpp |
34 | ) |
35 | |
36 | === added file 'src/cursor_enabler.cpp' |
37 | --- src/cursor_enabler.cpp 1970-01-01 00:00:00 +0000 |
38 | +++ src/cursor_enabler.cpp 2015-02-06 12:38:32 +0000 |
39 | @@ -0,0 +1,72 @@ |
40 | +/* |
41 | + * Copyright © 2015 Canonical Ltd. |
42 | + * |
43 | + * This program is free software: you can redistribute it and/or modify |
44 | + * it under the terms of the GNU General Public License version 3 as |
45 | + * published by the Free Software Foundation. |
46 | + * |
47 | + * This program is distributed in the hope that it will be useful, |
48 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
49 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
50 | + * GNU General Public License for more details. |
51 | + * |
52 | + * You should have received a copy of the GNU General Public License |
53 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
54 | + */ |
55 | + |
56 | +#include "cursor_enabler.h" |
57 | + |
58 | +#include "mir/graphics/cursor.h" |
59 | +#include "mir_toolkit/event.h" |
60 | + |
61 | +namespace mi = mir::input; |
62 | + |
63 | +CursorEnabler::CursorEnabler( |
64 | + std::shared_ptr<mir::graphics::Cursor> const& cursor, |
65 | + std::chrono::milliseconds remove_pointer_timeout) |
66 | + : cursor_shown(false), remove_delay{static_cast<uint32_t>(remove_pointer_timeout.count())}, last_cursor_movement(0), |
67 | + cursor(cursor) |
68 | +{ |
69 | + cursor->hide(); |
70 | +} |
71 | + |
72 | +CursorEnabler::~CursorEnabler() = default; |
73 | + |
74 | +bool CursorEnabler::handle(MirEvent const& event) |
75 | +{ |
76 | + if (mir_event_get_type(&event) != mir_event_type_input) |
77 | + { |
78 | + return false; |
79 | + } |
80 | + auto const* ev = mir_event_get_input_event(&event); |
81 | + if (mir_input_event_type_pointer == mir_input_event_get_type(ev)) |
82 | + { |
83 | + enable_cursor(); |
84 | + last_cursor_movement = event.motion.event_time; |
85 | + } |
86 | + else if (remove_delay && |
87 | + mir_input_event_type_touch == mir_input_event_get_type(ev) && |
88 | + (event.motion.event_time - last_cursor_movement > remove_delay)) |
89 | + { |
90 | + disable_cursor(); |
91 | + } |
92 | + return false; |
93 | +} |
94 | + |
95 | +void CursorEnabler::enable_cursor() |
96 | +{ |
97 | + if (!cursor_shown) |
98 | + { |
99 | + cursor->show(); |
100 | + cursor_shown = true; |
101 | + } |
102 | +} |
103 | + |
104 | +void CursorEnabler::disable_cursor() |
105 | +{ |
106 | + if (cursor_shown) |
107 | + { |
108 | + cursor->hide(); |
109 | + cursor_shown = false; |
110 | + } |
111 | +} |
112 | |
113 | === added file 'src/cursor_enabler.h' |
114 | --- src/cursor_enabler.h 1970-01-01 00:00:00 +0000 |
115 | +++ src/cursor_enabler.h 2015-02-06 12:38:32 +0000 |
116 | @@ -0,0 +1,58 @@ |
117 | +/* |
118 | + * Copyright © 2015 Canonical Ltd. |
119 | + * |
120 | + * This program is free software: you can redistribute it and/or modify |
121 | + * it under the terms of the GNU General Public License version 3 as |
122 | + * published by the Free Software Foundation. |
123 | + * |
124 | + * This program is distributed in the hope that it will be useful, |
125 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
126 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
127 | + * GNU General Public License for more details. |
128 | + * |
129 | + * You should have received a copy of the GNU General Public License |
130 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
131 | + */ |
132 | + |
133 | +#ifndef USC_CURSOR_IMAGE_ENABLER_H_ |
134 | +#define USC_CURSOR_IMAGE_ENABLER_H_ |
135 | + |
136 | +#include "mir/input/event_filter.h" |
137 | + |
138 | +#include <memory> |
139 | +#include <chrono> |
140 | + |
141 | +namespace mir |
142 | +{ |
143 | +namespace graphics |
144 | +{ |
145 | +class Cursor; |
146 | +class CursorImage; |
147 | +} |
148 | +} |
149 | + |
150 | +/* |
151 | + * Disables the cursor on construction and waits for the first mir pointer/cursor |
152 | + * event to come by for enabling the cursor again. |
153 | + */ |
154 | +class CursorEnabler : public mir::input::EventFilter |
155 | +{ |
156 | +public: |
157 | + CursorEnabler(std::shared_ptr<mir::graphics::Cursor> const& cursor, |
158 | + std::chrono::milliseconds remove_pointer_timeout); |
159 | + |
160 | + ~CursorEnabler(); |
161 | + |
162 | + bool handle(MirEvent const& event) override; |
163 | + |
164 | +private: |
165 | + void enable_cursor(); |
166 | + void disable_cursor(); |
167 | + |
168 | + bool cursor_shown; |
169 | + uint32_t remove_delay; |
170 | + uint32_t last_cursor_movement; |
171 | + std::shared_ptr<mir::graphics::Cursor> const cursor; |
172 | +}; |
173 | + |
174 | +#endif |
175 | |
176 | === modified file 'src/dbus_screen.cpp' |
177 | --- src/dbus_screen.cpp 2014-10-10 22:43:34 +0000 |
178 | +++ src/dbus_screen.cpp 2015-02-06 12:38:32 +0000 |
179 | @@ -20,6 +20,9 @@ |
180 | #include "power_state_change_reason.h" |
181 | #include "worker_thread.h" |
182 | |
183 | +#include "mir/input/input_region.h" |
184 | +#include "mir/graphics/cursor.h" |
185 | + |
186 | #include <atomic> |
187 | #include <memory> |
188 | #include <thread> |
189 | @@ -53,12 +56,17 @@ |
190 | } |
191 | |
192 | |
193 | -DBusScreen::DBusScreen(DBusScreenObserver& observer, QObject *parent) |
194 | +DBusScreen::DBusScreen(DBusScreenObserver& observer, |
195 | + std::shared_ptr<mir::input::InputRegion> const& region, |
196 | + std::shared_ptr<mir::graphics::Cursor> const& cursor, |
197 | + QObject *parent) |
198 | : QObject(parent), |
199 | dbus_adaptor{new DBusScreenAdaptor(this)}, |
200 | service_watcher{new QDBusServiceWatcher()}, |
201 | observer{&observer}, |
202 | - worker_thread{new usc::WorkerThread("USC/DBusHandler")} |
203 | + worker_thread{new usc::WorkerThread("USC/DBusHandler")}, |
204 | + region(region), |
205 | + cursor(cursor) |
206 | { |
207 | QDBusConnection bus = QDBusConnection::systemBus(); |
208 | bus.registerObject("/com/canonical/Unity/Screen", this); |
209 | @@ -211,3 +219,9 @@ |
210 | { |
211 | observer->set_touch_visualization_enabled(enabled); |
212 | } |
213 | + |
214 | +void DBusScreen::overrideOrientation(unsigned int index, int orientation) |
215 | +{ |
216 | + region->override_orientation(index, static_cast<MirOrientation>(orientation)); |
217 | + cursor->override_orientation(index, static_cast<MirOrientation>(orientation)); |
218 | +} |
219 | |
220 | === modified file 'src/dbus_screen.h' |
221 | --- src/dbus_screen.h 2014-09-22 17:19:52 +0000 |
222 | +++ src/dbus_screen.h 2015-02-06 12:38:32 +0000 |
223 | @@ -30,6 +30,8 @@ |
224 | |
225 | namespace usc {class WorkerThread;} |
226 | |
227 | +namespace mir { namespace graphics { class Cursor; } namespace input { class InputRegion; } } |
228 | + |
229 | class DBusScreenAdaptor; |
230 | class DBusScreenObserver; |
231 | class QDBusInterface; |
232 | @@ -42,7 +44,7 @@ |
233 | Q_CLASSINFO("D-Bus Interface", "com.canonical.Unity.Screen") |
234 | |
235 | public: |
236 | - explicit DBusScreen(DBusScreenObserver& observer, QObject *parent = 0); |
237 | + explicit DBusScreen(DBusScreenObserver& observer, std::shared_ptr<mir::input::InputRegion> const& region, std::shared_ptr<mir::graphics::Cursor> const& cursor, QObject *parent = 0); |
238 | virtual ~DBusScreen(); |
239 | |
240 | void emit_power_state_change(MirPowerMode mode, PowerStateChangeReason reason); |
241 | @@ -59,6 +61,7 @@ |
242 | void setInactivityTimeouts(int poweroff_timeout, int dimmer_timeout); |
243 | |
244 | void setTouchVisualizationEnabled(bool enabled); |
245 | + void overrideOrientation(unsigned int index, int orientation); |
246 | |
247 | private Q_SLOTS: |
248 | void remove_display_on_requestor(QString const& requestor); |
249 | @@ -72,6 +75,8 @@ |
250 | std::unordered_map<std::string, std::unordered_set<int>> display_requests; |
251 | DBusScreenObserver* const observer; |
252 | std::unique_ptr<usc::WorkerThread> worker_thread; |
253 | + std::shared_ptr<mir::input::InputRegion> const region; |
254 | + std::shared_ptr<mir::graphics::Cursor> const cursor; |
255 | }; |
256 | |
257 | #endif /* DBUS_SCREEN_H_ */ |
258 | |
259 | === modified file 'src/powerkey_handler.cpp' |
260 | --- src/powerkey_handler.cpp 2014-07-21 21:33:35 +0000 |
261 | +++ src/powerkey_handler.cpp 2015-02-06 12:38:32 +0000 |
262 | @@ -44,15 +44,22 @@ |
263 | bool PowerKeyHandler::handle(MirEvent const& event) |
264 | { |
265 | static const int32_t POWER_KEY_CODE = 26; |
266 | - |
267 | - if (event.type == mir_event_type_key && |
268 | - event.key.key_code == POWER_KEY_CODE) |
269 | - { |
270 | - if (event.key.action == mir_key_action_down) |
271 | - power_key_down(); |
272 | - else if (event.key.action == mir_key_action_up) |
273 | - power_key_up(); |
274 | - } |
275 | + |
276 | + if (mir_event_get_type(&event) != mir_event_type_input) |
277 | + return false; |
278 | + auto input_event = mir_event_get_input_event(&event); |
279 | + if (mir_input_event_get_type(input_event) != mir_input_event_type_key) |
280 | + return false; |
281 | + auto kev = mir_input_event_get_key_input_event(input_event); |
282 | + if (mir_key_input_event_get_key_code(kev) != POWER_KEY_CODE) |
283 | + return false; |
284 | + |
285 | + auto action = mir_key_input_event_get_action(kev); |
286 | + if (action == mir_key_input_event_action_down) |
287 | + power_key_down(); |
288 | + else if (action == mir_key_input_event_action_up) |
289 | + power_key_up(); |
290 | + |
291 | return false; |
292 | } |
293 | |
294 | |
295 | === modified file 'src/screen_state_handler.cpp' |
296 | --- src/screen_state_handler.cpp 2015-01-26 22:59:20 +0000 |
297 | +++ src/screen_state_handler.cpp 2015-02-06 12:38:32 +0000 |
298 | @@ -47,7 +47,7 @@ |
299 | std::bind(&ScreenStateHandler::power_off_alarm_notification, this))}, |
300 | dimmer_alarm{server->the_main_loop()->create_alarm( |
301 | std::bind(&ScreenStateHandler::dimmer_alarm_notification, this))}, |
302 | - dbus_screen{new DBusScreen(*this)} |
303 | + dbus_screen{new DBusScreen(*this, server->the_input_region(), server->the_cursor())} |
304 | { |
305 | /* |
306 | * Make sure the compositor is running as certain conditions can |
307 | @@ -62,13 +62,22 @@ |
308 | |
309 | bool ScreenStateHandler::handle(MirEvent const& event) |
310 | { |
311 | - if (event.type == mir_event_type_motion) |
312 | - { |
313 | - std::lock_guard<std::mutex> lock{guard}; |
314 | - reset_timers_l(); |
315 | - if (current_power_mode == MirPowerMode::mir_power_mode_on) |
316 | - powerd_mediator->set_normal_backlight(); |
317 | - } |
318 | + if (mir_event_get_type(&event) != mir_event_type_input) |
319 | + return false; |
320 | + |
321 | + auto input_event_type = mir_input_event_get_type(mir_event_get_input_event(&event)); |
322 | + // TODO: We should consider resetting the timer for key events too |
323 | + // we have to make sure we wont introduce a bug where pressing the power |
324 | + // key (to turn screen off) or just the volume keys will wake the screen though! |
325 | + if (!(input_event_type == mir_input_event_type_touch |
326 | + || input_event_type == mir_input_event_type_pointer)) |
327 | + return false; |
328 | + |
329 | + std::lock_guard<std::mutex> lock{guard}; |
330 | + reset_timers_l(); |
331 | + if (current_power_mode == MirPowerMode::mir_power_mode_on) |
332 | + powerd_mediator->set_normal_backlight(); |
333 | + |
334 | return false; |
335 | } |
336 | |
337 | |
338 | === modified file 'src/server.cpp' |
339 | --- src/server.cpp 2014-11-28 11:39:04 +0000 |
340 | +++ src/server.cpp 2015-02-06 12:38:32 +0000 |
341 | @@ -1,5 +1,5 @@ |
342 | /* |
343 | - * Copyright © 2014 Canonical Ltd. |
344 | + * Copyright © 2014-2015 Canonical Ltd. |
345 | * |
346 | * This program is free software: you can redistribute it and/or modify |
347 | * it under the terms of the GNU General Public License version 3 as |
348 | @@ -18,8 +18,7 @@ |
349 | |
350 | #include "server.h" |
351 | #include "external_spinner.h" |
352 | -#include "session_coordinator.h" |
353 | -#include "surface_coordinator.h" |
354 | +#include "shell.h" |
355 | #include "asio_dm_connection.h" |
356 | #include "session_switcher.h" |
357 | |
358 | @@ -103,44 +102,23 @@ |
359 | add_configuration_option("inactivity-display-dim-timeout", "The time in seconds before the screen is dimmed when there are no active sessions", mir::OptionType::integer); |
360 | add_configuration_option("shutdown-timeout", "The time in milli-seconds the power key must be held to initiate a clean system shutdown", mir::OptionType::integer); |
361 | add_configuration_option("power-key-ignore-timeout", "The time in milli-seconds the power key must be held to ignore - must be less than shutdown-timeout", mir::OptionType::integer); |
362 | + add_configuration_option("remove_pointer_timeout", "The time in milli-seconds the cursor image stays visible after touch screen is used again - by default the cursor image stays visible", mir::OptionType::integer); |
363 | add_configuration_option("disable-inactivity-policy", "Disables handling user inactivity and power key", mir::OptionType::boolean); |
364 | |
365 | set_command_line(argc, const_cast<char const **>(argv)); |
366 | |
367 | set_command_line_handler(&ignore_unknown_arguments); |
368 | |
369 | - wrap_cursor_listener([this](std::shared_ptr<mir::input::CursorListener> const& default_) |
370 | - -> std::shared_ptr<mir::input::CursorListener> |
371 | - { |
372 | - // This is a workaround for u8 desktop preview in 14.04 for the lack of client cursor API. |
373 | - // We need to disable the cursor for XMir but leave it on for the desktop preview. |
374 | - // Luckily as it stands they run inside seperate instances of USC. ~racarr |
375 | - if (enable_hardware_cursor()) |
376 | - return default_; |
377 | - else |
378 | - return std::make_shared<NullCursorListener>(); |
379 | - }); |
380 | - |
381 | override_the_server_status_listener([this]() |
382 | -> std::shared_ptr<mir::ServerStatusListener> |
383 | { |
384 | return std::make_shared<ServerStatusListener>(the_focus_controller()); |
385 | }); |
386 | |
387 | - wrap_session_coordinator([this](std::shared_ptr<ms::SessionCoordinator> const& wrapped) |
388 | - -> std::shared_ptr<ms::SessionCoordinator> |
389 | - { |
390 | - return std::make_shared<SessionCoordinator>( |
391 | - wrapped, |
392 | - the_session_switcher()); |
393 | - }); |
394 | - |
395 | - wrap_surface_coordinator([this](std::shared_ptr<ms::SurfaceCoordinator> const& wrapped) |
396 | - -> std::shared_ptr<mir::scene::SurfaceCoordinator> |
397 | - { |
398 | - return std::make_shared<SurfaceCoordinator>( |
399 | - wrapped, |
400 | - the_session_switcher()); |
401 | + wrap_shell([this](std::shared_ptr<msh::Shell> const& wrapped) |
402 | + -> std::shared_ptr<msh::Shell> |
403 | + { |
404 | + return std::make_shared<Shell>(wrapped, the_session_switcher()); |
405 | }); |
406 | |
407 | set_config_filename("unity-system-compositor.conf"); |
408 | |
409 | === modified file 'src/server.h' |
410 | --- src/server.h 2014-11-28 11:39:04 +0000 |
411 | +++ src/server.h 2015-02-06 12:38:32 +0000 |
412 | @@ -42,6 +42,8 @@ |
413 | using mir::Server::the_display; |
414 | using mir::Server::the_compositor; |
415 | using mir::Server::the_touch_visualizer; |
416 | + using mir::Server::the_cursor; |
417 | + using mir::Server::the_input_region; |
418 | |
419 | virtual std::shared_ptr<Spinner> the_spinner(); |
420 | virtual std::shared_ptr<DMMessageHandler> the_dm_message_handler(); |
421 | @@ -72,6 +74,11 @@ |
422 | return the_options()->get("power-key-ignore-timeout", 2000); |
423 | } |
424 | |
425 | + int remove_pointer_timeout() |
426 | + { |
427 | + return the_options()->get("remove-pointer-timeout", 0); |
428 | + } |
429 | + |
430 | bool enable_hardware_cursor() |
431 | { |
432 | return the_options()->get("enable-hardware-cursor", false); |
433 | |
434 | === renamed file 'src/session_coordinator.cpp' => 'src/shell.cpp' |
435 | --- src/session_coordinator.cpp 2014-08-01 21:58:43 +0000 |
436 | +++ src/shell.cpp 2015-02-06 12:38:32 +0000 |
437 | @@ -1,5 +1,5 @@ |
438 | /* |
439 | - * Copyright © 2014 Canonical Ltd. |
440 | + * Copyright © 2014-2015 Canonical Ltd. |
441 | * |
442 | * This program is free software: you can redistribute it and/or modify |
443 | * it under the terms of the GNU General Public License version 3 as |
444 | @@ -16,10 +16,12 @@ |
445 | * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com> |
446 | */ |
447 | |
448 | -#include "session_coordinator.h" |
449 | +#include "shell.h" |
450 | #include "session_switcher.h" |
451 | |
452 | +#include <mir/scene/null_surface_observer.h> |
453 | #include <mir/scene/session.h> |
454 | +#include <mir/scene/surface.h> |
455 | #include <mir/frontend/session.h> |
456 | |
457 | #include <iostream> |
458 | @@ -71,34 +73,59 @@ |
459 | msh::FocusController& focus_controller; |
460 | }; |
461 | |
462 | + |
463 | +struct SessionReadyObserver : ms::NullSurfaceObserver, |
464 | + std::enable_shared_from_this<SessionReadyObserver> |
465 | +{ |
466 | + SessionReadyObserver( |
467 | + std::shared_ptr<usc::SessionSwitcher> const& switcher, |
468 | + std::shared_ptr<ms::Surface> const& surface, |
469 | + ms::Session const* session) |
470 | + : switcher{switcher}, |
471 | + surface{surface}, |
472 | + session{session} |
473 | + { |
474 | + } |
475 | + |
476 | + void frame_posted(int) override |
477 | + { |
478 | + ++num_frames_posted; |
479 | + if (num_frames_posted == num_frames_for_session_ready) |
480 | + { |
481 | + switcher->mark_ready(session); |
482 | + surface->remove_observer(shared_from_this()); |
483 | + } |
484 | + } |
485 | + |
486 | + std::shared_ptr<usc::SessionSwitcher> const switcher; |
487 | + std::shared_ptr<ms::Surface> const surface; |
488 | + ms::Session const* const session; |
489 | + // We need to wait for the second frame before marking the session |
490 | + // as ready. The first frame posted from sessions is a blank frame. |
491 | + // TODO: Solve this issue at its root and remove this workaround |
492 | + int const num_frames_for_session_ready{2}; |
493 | + int num_frames_posted{0}; |
494 | +}; |
495 | + |
496 | } |
497 | |
498 | -usc::SessionCoordinator::SessionCoordinator( |
499 | - std::shared_ptr<ms::SessionCoordinator> const& wrapped, |
500 | +usc::Shell::Shell( |
501 | + std::shared_ptr<msh::Shell> const& wrapped, |
502 | std::shared_ptr<SessionSwitcher> const& session_switcher) |
503 | - : msh::SessionCoordinatorWrapper{wrapped}, |
504 | + : msh::ShellWrapper{wrapped}, |
505 | session_switcher{session_switcher} |
506 | { |
507 | } |
508 | |
509 | -std::shared_ptr<mf::Session> |
510 | -usc::SessionCoordinator::open_session( |
511 | +std::shared_ptr<ms::Session> |
512 | +usc::Shell::open_session( |
513 | pid_t client_pid, |
514 | std::string const& name, |
515 | std::shared_ptr<mf::EventSink> const& sink) |
516 | { |
517 | std::cerr << "Opening session " << name << std::endl; |
518 | |
519 | - // We need ms::Session objects because that is what the focus controller |
520 | - // works with. But the mf::SessionCoordinator interface deals with mf::Session objects. |
521 | - // So we cast here since in practice, these objects are also ms::Sessions. |
522 | - auto orig = std::dynamic_pointer_cast<ms::Session>( |
523 | - msh::SessionCoordinatorWrapper::open_session(client_pid, name, sink)); |
524 | - if (!orig) |
525 | - { |
526 | - std::cerr << "Unexpected non-shell session" << std::endl; |
527 | - return std::shared_ptr<mf::Session>(); |
528 | - } |
529 | + auto orig = msh::ShellWrapper::open_session(client_pid, name, sink); |
530 | |
531 | auto const usc_session = std::make_shared<UscSession>(orig, *this); |
532 | |
533 | @@ -107,12 +134,24 @@ |
534 | return orig; |
535 | } |
536 | |
537 | -void usc::SessionCoordinator::close_session( |
538 | - std::shared_ptr<mf::Session> const& session) |
539 | +void usc::Shell::close_session(std::shared_ptr<ms::Session> const& session) |
540 | { |
541 | std::cerr << "Closing session " << session->name() << std::endl; |
542 | |
543 | - msh::SessionCoordinatorWrapper::close_session(session); |
544 | + msh::ShellWrapper::close_session(session); |
545 | |
546 | session_switcher->remove(session); |
547 | } |
548 | + |
549 | +mf::SurfaceId usc::Shell::create_surface(std::shared_ptr<ms::Session> const& session, ms::SurfaceCreationParameters const& params) |
550 | +{ |
551 | + auto const id = msh::ShellWrapper::create_surface(session, params); |
552 | + |
553 | + auto const surface = session->surface(id); |
554 | + auto const session_ready_observer = std::make_shared<SessionReadyObserver>( |
555 | + session_switcher, surface, session.get()); |
556 | + |
557 | + surface->add_observer(session_ready_observer); |
558 | + |
559 | + return id; |
560 | +} |
561 | |
562 | === renamed file 'src/session_coordinator.h' => 'src/shell.h' |
563 | --- src/session_coordinator.h 2014-07-09 06:58:05 +0000 |
564 | +++ src/shell.h 2015-02-06 12:38:32 +0000 |
565 | @@ -1,5 +1,5 @@ |
566 | /* |
567 | - * Copyright © 2014 Canonical Ltd. |
568 | + * Copyright © 2014-2015 Canonical Ltd. |
569 | * |
570 | * This program is free software: you can redistribute it and/or modify |
571 | * it under the terms of the GNU General Public License version 3 as |
572 | @@ -16,35 +16,35 @@ |
573 | * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com> |
574 | */ |
575 | |
576 | -#ifndef USC_SESSION_COORDINATOR_H_ |
577 | -#define USC_SESSION_COORDINATOR_H_ |
578 | +#ifndef USC_SHELL_H_ |
579 | +#define USC_SHELL_H_ |
580 | |
581 | -#include <mir/shell/session_coordinator_wrapper.h> |
582 | +#include <mir/shell/shell_wrapper.h> |
583 | |
584 | #include <memory> |
585 | |
586 | -namespace mir |
587 | -{ |
588 | -namespace scene { class SurfaceCoordinator; } |
589 | -} |
590 | |
591 | namespace usc |
592 | { |
593 | class SessionSwitcher; |
594 | |
595 | -class SessionCoordinator : public mir::shell::SessionCoordinatorWrapper |
596 | +class Shell : public mir::shell::ShellWrapper |
597 | { |
598 | public: |
599 | - SessionCoordinator( |
600 | - std::shared_ptr<mir::scene::SessionCoordinator> const& wrapped, |
601 | + Shell( |
602 | + std::shared_ptr<mir::shell::Shell> const& wrapped, |
603 | std::shared_ptr<SessionSwitcher> const& session_switcher); |
604 | |
605 | private: |
606 | - std::shared_ptr<mir::frontend::Session> open_session( |
607 | + std::shared_ptr<mir::scene::Session> open_session( |
608 | pid_t client_pid, |
609 | std::string const& name, |
610 | std::shared_ptr<mir::frontend::EventSink> const& sink) override; |
611 | - void close_session(std::shared_ptr<mir::frontend::Session> const& session) override; |
612 | + void close_session(std::shared_ptr<mir::scene::Session> const& session) override; |
613 | + |
614 | + mir::frontend::SurfaceId create_surface( |
615 | + std::shared_ptr<mir::scene::Session> const& session, |
616 | + mir::scene::SurfaceCreationParameters const& params) override; |
617 | |
618 | std::shared_ptr<SessionSwitcher> const session_switcher; |
619 | }; |
620 | |
621 | === removed file 'src/surface_coordinator.cpp' |
622 | --- src/surface_coordinator.cpp 2014-08-01 21:58:43 +0000 |
623 | +++ src/surface_coordinator.cpp 1970-01-01 00:00:00 +0000 |
624 | @@ -1,87 +0,0 @@ |
625 | -/* |
626 | - * Copyright © 2014 Canonical Ltd. |
627 | - * |
628 | - * This program is free software: you can redistribute it and/or modify |
629 | - * it under the terms of the GNU General Public License version 3 as |
630 | - * published by the Free Software Foundation. |
631 | - * |
632 | - * This program is distributed in the hope that it will be useful, |
633 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
634 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
635 | - * GNU General Public License for more details. |
636 | - * |
637 | - * You should have received a copy of the GNU General Public License |
638 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
639 | - * |
640 | - * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com> |
641 | - */ |
642 | - |
643 | -#include "surface_coordinator.h" |
644 | -#include "session_switcher.h" |
645 | - |
646 | -#include <mir/scene/null_surface_observer.h> |
647 | -#include <mir/scene/surface.h> |
648 | -#include <mir/scene/session.h> |
649 | - |
650 | -namespace ms = mir::scene; |
651 | -namespace msh = mir::shell; |
652 | - |
653 | -namespace |
654 | -{ |
655 | - |
656 | -struct SessionReadyObserver : ms::NullSurfaceObserver, |
657 | - std::enable_shared_from_this<SessionReadyObserver> |
658 | -{ |
659 | - SessionReadyObserver( |
660 | - std::shared_ptr<usc::SessionSwitcher> const& switcher, |
661 | - std::shared_ptr<ms::Surface> const& surface, |
662 | - ms::Session const* session) |
663 | - : switcher{switcher}, |
664 | - surface{surface}, |
665 | - session{session} |
666 | - { |
667 | - } |
668 | - |
669 | - void frame_posted(int) override |
670 | - { |
671 | - ++num_frames_posted; |
672 | - if (num_frames_posted == num_frames_for_session_ready) |
673 | - { |
674 | - switcher->mark_ready(session); |
675 | - surface->remove_observer(shared_from_this()); |
676 | - } |
677 | - } |
678 | - |
679 | - std::shared_ptr<usc::SessionSwitcher> const switcher; |
680 | - std::shared_ptr<ms::Surface> const surface; |
681 | - ms::Session const* const session; |
682 | - // We need to wait for the second frame before marking the session |
683 | - // as ready. The first frame posted from sessions is a blank frame. |
684 | - // TODO: Solve this issue at its root and remove this workaround |
685 | - int const num_frames_for_session_ready{2}; |
686 | - int num_frames_posted{0}; |
687 | -}; |
688 | - |
689 | -} |
690 | - |
691 | -usc::SurfaceCoordinator::SurfaceCoordinator( |
692 | - std::shared_ptr<ms::SurfaceCoordinator> const& wrapped, |
693 | - std::shared_ptr<SessionSwitcher> const& session_switcher) |
694 | - : msh::SurfaceCoordinatorWrapper{wrapped}, |
695 | - session_switcher{session_switcher} |
696 | -{ |
697 | -} |
698 | - |
699 | -std::shared_ptr<ms::Surface> usc::SurfaceCoordinator::add_surface( |
700 | - ms::SurfaceCreationParameters const& params, |
701 | - ms::Session* session) |
702 | -{ |
703 | - auto const surface = msh::SurfaceCoordinatorWrapper::add_surface(params, session); |
704 | - |
705 | - auto const session_ready_observer = std::make_shared<SessionReadyObserver>( |
706 | - session_switcher, surface, session); |
707 | - |
708 | - surface->add_observer(session_ready_observer); |
709 | - |
710 | - return surface; |
711 | -} |
712 | |
713 | === removed file 'src/surface_coordinator.h' |
714 | --- src/surface_coordinator.h 2014-07-09 06:58:05 +0000 |
715 | +++ src/surface_coordinator.h 1970-01-01 00:00:00 +0000 |
716 | @@ -1,47 +0,0 @@ |
717 | -/* |
718 | - * Copyright © 2014 Canonical Ltd. |
719 | - * |
720 | - * This program is free software: you can redistribute it and/or modify |
721 | - * it under the terms of the GNU General Public License version 3 as |
722 | - * published by the Free Software Foundation. |
723 | - * |
724 | - * This program is distributed in the hope that it will be useful, |
725 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
726 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
727 | - * GNU General Public License for more details. |
728 | - * |
729 | - * You should have received a copy of the GNU General Public License |
730 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
731 | - * |
732 | - * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com> |
733 | - */ |
734 | - |
735 | -#ifndef USC_SURFACE_COORDINATOR_H_ |
736 | -#define USC_SURFACE_COORDINATOR_H_ |
737 | - |
738 | -#include <mir/shell/surface_coordinator_wrapper.h> |
739 | - |
740 | -#include <memory> |
741 | - |
742 | -namespace usc |
743 | -{ |
744 | -class SessionSwitcher; |
745 | - |
746 | -class SurfaceCoordinator : public mir::shell::SurfaceCoordinatorWrapper |
747 | -{ |
748 | -public: |
749 | - SurfaceCoordinator( |
750 | - std::shared_ptr<mir::scene::SurfaceCoordinator> const& wrapped, |
751 | - std::shared_ptr<SessionSwitcher> const& session_switcher); |
752 | - |
753 | -private: |
754 | - std::shared_ptr<mir::scene::Surface> add_surface( |
755 | - mir::scene::SurfaceCreationParameters const& params, |
756 | - mir::scene::Session* session) override; |
757 | - |
758 | - std::shared_ptr<SessionSwitcher> const session_switcher; |
759 | -}; |
760 | - |
761 | -} |
762 | - |
763 | -#endif |
764 | |
765 | === modified file 'src/system_compositor.cpp' |
766 | --- src/system_compositor.cpp 2015-01-05 22:38:04 +0000 |
767 | +++ src/system_compositor.cpp 2015-02-06 12:38:32 +0000 |
768 | @@ -24,6 +24,7 @@ |
769 | #include "spinner.h" |
770 | #include "screen_state_handler.h" |
771 | #include "powerkey_handler.h" |
772 | +#include "cursor_enabler.h" |
773 | |
774 | // Qt headers will introduce a #define of "signals" |
775 | // but some mir headers use "signals" as a variable name in |
776 | @@ -152,6 +153,7 @@ |
777 | std::chrono::seconds inactivity_display_dim_timeout{server->inactivity_display_dim_timeout()}; |
778 | std::chrono::milliseconds power_key_ignore_timeout{server->power_key_ignore_timeout()}; |
779 | std::chrono::milliseconds shutdown_timeout{server->shutdown_timeout()}; |
780 | + std::chrono::milliseconds remove_pointer_timeout{server->remove_pointer_timeout()}; |
781 | |
782 | screen_state_handler = std::make_shared<ScreenStateHandler>(server, |
783 | std::chrono::duration_cast<std::chrono::milliseconds>(inactivity_display_off_timeout), |
784 | @@ -162,9 +164,15 @@ |
785 | shutdown_timeout, |
786 | *screen_state_handler); |
787 | |
788 | + cursor_image_enabler = std::make_shared<CursorEnabler>( |
789 | + server->the_cursor(), |
790 | + remove_pointer_timeout); |
791 | + |
792 | auto composite_filter = server->the_composite_event_filter(); |
793 | composite_filter->append(screen_state_handler); |
794 | composite_filter->append(power_key_handler); |
795 | + if (server->enable_hardware_cursor()) |
796 | + composite_filter->append(cursor_image_enabler); |
797 | } |
798 | |
799 | app.exec(); |
800 | |
801 | === modified file 'src/system_compositor.h' |
802 | --- src/system_compositor.h 2014-11-28 13:19:29 +0000 |
803 | +++ src/system_compositor.h 2015-02-06 12:38:32 +0000 |
804 | @@ -24,6 +24,7 @@ |
805 | |
806 | class ScreenStateHandler; |
807 | class PowerKeyHandler; |
808 | +class CursorEnabler; |
809 | |
810 | namespace usc |
811 | { |
812 | @@ -46,6 +47,7 @@ |
813 | std::shared_ptr<Spinner> const spinner; |
814 | std::shared_ptr<ScreenStateHandler> screen_state_handler; |
815 | std::shared_ptr<PowerKeyHandler> power_key_handler; |
816 | + std::shared_ptr<CursorEnabler> cursor_image_enabler; |
817 | }; |
818 | |
819 | } |
820 | |
821 | === modified file 'tests/unit-tests/CMakeLists.txt' |
822 | --- tests/unit-tests/CMakeLists.txt 2014-07-09 06:58:05 +0000 |
823 | +++ tests/unit-tests/CMakeLists.txt 2015-02-06 12:38:32 +0000 |
824 | @@ -23,6 +23,7 @@ |
825 | usc_unit_tests |
826 | |
827 | test_session_switcher.cpp |
828 | + test_cursor_enabler.cpp |
829 | ) |
830 | |
831 | target_link_libraries( |
832 | |
833 | === added file 'tests/unit-tests/test_cursor_enabler.cpp' |
834 | --- tests/unit-tests/test_cursor_enabler.cpp 1970-01-01 00:00:00 +0000 |
835 | +++ tests/unit-tests/test_cursor_enabler.cpp 2015-02-06 12:38:32 +0000 |
836 | @@ -0,0 +1,110 @@ |
837 | +/* |
838 | + * Copyright © 2015 Canonical Ltd. |
839 | + * |
840 | + * This program is free software: you can redistribute it and/or modify |
841 | + * it under the terms of the GNU General Public License version 3 as |
842 | + * published by the Free Software Foundation. |
843 | + * |
844 | + * This program is distributed in the hope that it will be useful, |
845 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
846 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
847 | + * GNU General Public License for more details. |
848 | + * |
849 | + * You should have received a copy of the GNU General Public License |
850 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
851 | + * |
852 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
853 | + */ |
854 | + |
855 | +#define MIR_INCLUDE_DEPRECATED_EVENT_HEADER |
856 | + |
857 | +#include "src/cursor_enabler.h" |
858 | + |
859 | +#include "mir_toolkit/event.h" |
860 | +#include "mir/graphics/cursor.h" |
861 | +#include "mir/graphics/cursor_image.h" |
862 | + |
863 | +#include <gtest/gtest.h> |
864 | +#include <gmock/gmock.h> |
865 | + |
866 | +#include <memory> |
867 | +#include <vector> |
868 | +#include <tuple> |
869 | +#include <cstring> |
870 | + |
871 | +namespace |
872 | +{ |
873 | +struct MockCursor : mir::graphics::Cursor |
874 | +{ |
875 | + MOCK_METHOD0(show, void()); |
876 | + MOCK_METHOD1(show, void(mir::graphics::CursorImage const&)); |
877 | + MOCK_METHOD0(hide, void()); |
878 | + MOCK_METHOD1(move_to, void(mir::geometry::Point)); |
879 | + MOCK_METHOD2(override_orientation, void(uint32_t, MirOrientation)); |
880 | +}; |
881 | + |
882 | +struct TestCursorEnabler : ::testing::Test |
883 | +{ |
884 | + std::shared_ptr<::testing::NiceMock<MockCursor>> mock_cursor = std::make_shared<::testing::NiceMock<MockCursor>>(); |
885 | + std::chrono::milliseconds never_remove_pointer{0}; |
886 | + std::chrono::milliseconds remove_after_five_seconds_of_non_pointing_events{5000}; |
887 | + |
888 | + MirEvent mouse_event; |
889 | + MirEvent touch_event; |
890 | + MirEvent key_event; |
891 | + TestCursorEnabler() |
892 | + { |
893 | + std::memset(&mouse_event, 0, sizeof mouse_event); |
894 | + std::memset(&touch_event, 0, sizeof touch_event); |
895 | + std::memset(&key_event, 0, sizeof key_event); |
896 | + |
897 | + mouse_event.type = mir_event_type_motion; |
898 | + mouse_event.motion.source_id = 0x02002; // android constant for mouse | pointer |
899 | + mouse_event.motion.pointer_count = 1; |
900 | + mouse_event.motion.event_time = 0; |
901 | + mouse_event.motion.pointer_coordinates[0].tool_type = mir_motion_tool_type_mouse; |
902 | + |
903 | + touch_event.type = mir_event_type_motion; |
904 | + touch_event.motion.source_id = 0x01002; // android constant for touchscreen | pointer |
905 | + touch_event.motion.pointer_count = 1; |
906 | + touch_event.motion.event_time = 6000; |
907 | + touch_event.motion.pointer_coordinates[0].tool_type = mir_motion_tool_type_finger; |
908 | + |
909 | + key_event.type = mir_event_type_key; |
910 | + key_event.key.source_id = 0x0101; // android constant for keyboard | button |
911 | + key_event.key.event_time = 6000; |
912 | + } |
913 | +}; |
914 | +} |
915 | + |
916 | +TEST_F(TestCursorEnabler, diables_cursor_on_start) |
917 | +{ |
918 | + using namespace testing; |
919 | + EXPECT_CALL(*mock_cursor, hide()); |
920 | + |
921 | + CursorEnabler enabler(mock_cursor, never_remove_pointer); |
922 | +} |
923 | + |
924 | +TEST_F(TestCursorEnabler, enable_cursor_on_mouse_event) |
925 | +{ |
926 | + using namespace testing; |
927 | + EXPECT_CALL(*mock_cursor, hide()); |
928 | + EXPECT_CALL(*mock_cursor, show()); |
929 | + |
930 | + CursorEnabler enabler(mock_cursor, never_remove_pointer); |
931 | + enabler.handle(mouse_event); |
932 | +} |
933 | + |
934 | +TEST_F(TestCursorEnabler, disable_cursor_on_touch_event) |
935 | +{ |
936 | + using namespace testing; |
937 | + InSequence seq; |
938 | + EXPECT_CALL(*mock_cursor, hide()); |
939 | + EXPECT_CALL(*mock_cursor, show()); |
940 | + EXPECT_CALL(*mock_cursor, hide()); |
941 | + |
942 | + CursorEnabler enabler(mock_cursor, remove_after_five_seconds_of_non_pointing_events); |
943 | + enabler.handle(mouse_event); |
944 | + enabler.handle(touch_event); |
945 | +} |
946 | + |
947 | |
948 | === modified file 'tests/unit-tests/test_session_switcher.cpp' |
949 | --- tests/unit-tests/test_session_switcher.cpp 2014-08-01 21:58:43 +0000 |
950 | +++ tests/unit-tests/test_session_switcher.cpp 2015-02-06 12:38:32 +0000 |
951 | @@ -1,5 +1,5 @@ |
952 | /* |
953 | - * Copyright © 2014 Canonical Ltd. |
954 | + * Copyright © 2014-2015 Canonical Ltd. |
955 | * |
956 | * This program is free software: you can redistribute it and/or modify |
957 | * it under the terms of the GNU General Public License version 3 as |
958 | @@ -96,13 +96,9 @@ |
959 | : name_{name} |
960 | {} |
961 | |
962 | - mir::frontend::SurfaceId create_surface(mir::scene::SurfaceCreationParameters const&) override { return mir::frontend::SurfaceId{0}; } |
963 | - void destroy_surface(mir::frontend::SurfaceId) override {} |
964 | std::shared_ptr<mir::frontend::Surface> get_surface(mir::frontend::SurfaceId surface) const override { return nullptr; } |
965 | |
966 | std::string name() const override { return name_; } |
967 | - void hide() override {} |
968 | - void show() override {} |
969 | |
970 | private: |
971 | std::string const name_; |