Merge lp:~alan-griffiths/miral/background-intro into lp:miral
- background-intro
- Merge into trunk
Proposed by
Alan Griffiths
Status: | Merged |
---|---|
Approved by: | Gerry Boland |
Approved revision: | 520 |
Merged at revision: | 514 |
Proposed branch: | lp:~alan-griffiths/miral/background-intro |
Merge into: | lp:miral |
Diff against target: |
800 lines (+314/-75) 8 files modified
include/mir/client/display_config.h (+80/-0) miral-shell/CMakeLists.txt (+1/-1) miral-shell/decoration_provider.cpp (+185/-38) miral-shell/decoration_provider.h (+16/-10) miral-shell/titlebar_window_manager.cpp (+19/-21) miral-shell/titlebar_window_manager.h (+3/-3) miral/CMakeLists.txt (+9/-2) miral/mir_features.h.in (+1/-0) |
To merge this branch: | bzr merge lp:~alan-griffiths/miral/background-intro |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gerry Boland (community) | Approve | ||
Review via email: mp+317600@code.launchpad.net |
This proposal supersedes a proposal from 2017-02-13.
Commit message
[miral-shell] Use background to show keyboard shortcuts
Description of the change
To post a comment you must log in.
- 520. By Alan Griffiths
-
Fix Xenial build
Revision history for this message
Alan Griffiths (alan-griffiths) wrote : | # |
> Works ok.
>
> + for (int i = 0; i < region->width; i++)
> + memcpy(pixel + i, pattern, sizeof pixel[i]);
> This can't be a single memcpy?
Only if region->width <= 1 (otherwise we access beyond the end of pattern).
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'include/mir/client/display_config.h' |
2 | --- include/mir/client/display_config.h 1970-01-01 00:00:00 +0000 |
3 | +++ include/mir/client/display_config.h 2017-02-17 15:07:17 +0000 |
4 | @@ -0,0 +1,80 @@ |
5 | +/* |
6 | + * Copyright © 2017 Canonical Ltd. |
7 | + * |
8 | + * This program is free software: you can redistribute it and/or modify it |
9 | + * under the terms of the GNU General Public License version 3, |
10 | + * as published by the Free Software Foundation. |
11 | + * |
12 | + * This program is distributed in the hope that it will be useful, |
13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | + * GNU General Public License for more details. |
16 | + * |
17 | + * You should have received a copy of the GNU General Public License |
18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | + * |
20 | + * Authored by: Alan Griffiths <alan@octopull.co.uk> |
21 | + */ |
22 | + |
23 | +#ifndef MIR_CLIENT_DISPLAY_CONFIG_H |
24 | +#define MIR_CLIENT_DISPLAY_CONFIG_H |
25 | + |
26 | +#include <mir_toolkit/mir_connection.h> |
27 | +#include <mir_toolkit/mir_display_configuration.h> |
28 | +#include <mir/client/detail/mir_features.h> |
29 | + |
30 | +#include <functional> |
31 | +#include <memory> |
32 | + |
33 | +namespace mir |
34 | +{ |
35 | +/// Convenient C++ wrappers around the Mir toolkit API. |
36 | +/// |
37 | +/// These wrappers are intentionally inline adapters: the compiled code depend directly on the Mir toolkit API. |
38 | +namespace client |
39 | +{ |
40 | +class DisplayConfig |
41 | +{ |
42 | +public: |
43 | + DisplayConfig() = default; |
44 | + |
45 | + explicit DisplayConfig(MirDisplayConfig* config) : self{config, deleter} {} |
46 | + |
47 | + explicit DisplayConfig(MirConnection* connection) : |
48 | + self{mir_connection_create_display_configuration(connection), deleter} {} |
49 | + |
50 | + operator MirDisplayConfig*() { return self.get(); } |
51 | + |
52 | + operator MirDisplayConfig const*() const { return self.get(); } |
53 | + |
54 | + void reset() { self.reset(); } |
55 | + |
56 | + void for_each_output(std::function<void(MirOutput const*)> const& enumerator) const |
57 | + { |
58 | + auto const count = mir_display_config_get_num_outputs(*this); |
59 | + |
60 | + for (int i = 0; i != count; ++i) |
61 | + enumerator(mir_display_config_get_output(*this, i)); |
62 | + } |
63 | + |
64 | +#if MIR_DEFINES_DISPLAY_CONFIG_GET_MUTABLE_OUTPUT |
65 | + // Is it worthwhile to emulate this functionality for Mir 0.21? |
66 | + // Too many API gaps I think. |
67 | + void for_each_output(std::function<void(MirOutput*)> const& enumerator) |
68 | + { |
69 | + auto const count = mir_display_config_get_num_outputs(*this); |
70 | + |
71 | + for (int i = 0; i != count; ++i) |
72 | + enumerator(mir_display_config_get_mutable_output(*this, i)); |
73 | + } |
74 | +#endif |
75 | + |
76 | +private: |
77 | + static void deleter(MirDisplayConfig* config) { mir_display_config_release(config); } |
78 | + |
79 | + std::shared_ptr <MirDisplayConfig> self; |
80 | +}; |
81 | +} |
82 | +} |
83 | + |
84 | +#endif //MIR_CLIENT_DISPLAY_CONFIG_H |
85 | |
86 | === modified file 'miral-shell/CMakeLists.txt' |
87 | --- miral-shell/CMakeLists.txt 2016-12-14 11:22:57 +0000 |
88 | +++ miral-shell/CMakeLists.txt 2017-02-17 15:07:17 +0000 |
89 | @@ -45,7 +45,7 @@ |
90 | shell_main.cpp |
91 | tiling_window_manager.cpp tiling_window_manager.h |
92 | titlebar_window_manager.cpp titlebar_window_manager.h |
93 | - titlebar_provider.cpp titlebar_provider.h |
94 | + decoration_provider.cpp decoration_provider.h |
95 | titlebar_config.cpp titlebar_config.h |
96 | ) |
97 | |
98 | |
99 | === renamed file 'miral-shell/titlebar_provider.cpp' => 'miral-shell/decoration_provider.cpp' |
100 | --- miral-shell/titlebar_provider.cpp 2017-02-14 11:49:59 +0000 |
101 | +++ miral-shell/decoration_provider.cpp 2017-02-17 15:07:17 +0000 |
102 | @@ -1,5 +1,5 @@ |
103 | /* |
104 | - * Copyright © 2016 Canonical Ltd. |
105 | + * Copyright © 2016-2017 Canonical Ltd. |
106 | * |
107 | * This program is free software: you can redistribute it and/or modify it |
108 | * under the terms of the GNU General Public License version 3, |
109 | @@ -16,9 +16,10 @@ |
110 | * Authored by: Alan Griffiths <alan@octopull.co.uk> |
111 | */ |
112 | |
113 | -#include "titlebar_provider.h" |
114 | +#include "decoration_provider.h" |
115 | #include "titlebar_config.h" |
116 | |
117 | +#include <mir/client/display_config.h> |
118 | #include <mir/client/window_spec.h> |
119 | |
120 | #include <mir_toolkit/mir_buffer_stream.h> |
121 | @@ -37,8 +38,9 @@ |
122 | namespace |
123 | { |
124 | int const title_bar_height = 12; |
125 | +char const* const wallpaper_name = "wallpaper"; |
126 | |
127 | -void null_surface_callback(MirWindow*, void*) {} |
128 | +void null_window_callback(MirWindow*, void*) {} |
129 | |
130 | struct Printer |
131 | { |
132 | @@ -48,6 +50,7 @@ |
133 | Printer& operator=(Printer const&) = delete; |
134 | |
135 | void print(MirGraphicsRegion const& region, std::string const& title, int const intensity); |
136 | + void printhelp(MirGraphicsRegion const& region); |
137 | |
138 | private: |
139 | std::wstring_convert<std::codecvt_utf16<wchar_t>> converter; |
140 | @@ -59,11 +62,7 @@ |
141 | |
142 | void paint_surface(MirWindow* surface, std::string const& title, int const intensity) |
143 | { |
144 | -#if MIR_CLIENT_VERSION <= MIR_VERSION_NUMBER(3, 4, 0) |
145 | - MirBufferStream* buffer_stream = mir_surface_get_buffer_stream(surface); |
146 | -#else |
147 | MirBufferStream* buffer_stream = mir_window_get_buffer_stream(surface); |
148 | -#endif |
149 | |
150 | // TODO sometimes buffer_stream is nullptr - find out why (and fix). |
151 | // (Only observed when creating a lot of clients at once) |
152 | @@ -152,22 +151,117 @@ |
153 | base_y += glyph->advance.y >> 6; |
154 | } |
155 | } |
156 | + |
157 | +void Printer::printhelp(MirGraphicsRegion const& region) |
158 | +{ |
159 | + static char const* const helptext[] = |
160 | + { |
161 | + "Welcome to miral-shell", |
162 | + "", |
163 | + "Keyboard shortcuts:", |
164 | + "", |
165 | + " o Switch apps: Alt-Tab, tap or click on the corresponding window", |
166 | + " o Switch window: Alt-`, tap or click on the corresponding window", |
167 | + "", |
168 | + " o Move window: Alt-leftmousebutton drag (three finger drag)", |
169 | + " o Resize window: Alt-middle_button drag (three finger pinch)", |
170 | + "", |
171 | + " o Maximize/restore current window (to display size). : Alt-F11", |
172 | + " o Maximize/restore current window (to display height): Shift-F11", |
173 | + " o Maximize/restore current window (to display width) : Ctrl-F11", |
174 | +// "", |
175 | +// " o Switch workspace: Meta-Alt-[F1|F2|F3|F4]", |
176 | +// " o Switch workspace taking active window: Meta-Ctrl-[F1|F2|F3|F4]", |
177 | + "", |
178 | + " o To exit: Ctrl-Alt-BkSp", |
179 | + }; |
180 | + |
181 | + int help_width = 0; |
182 | + unsigned int help_height = 0; |
183 | + unsigned int line_height = 0; |
184 | + |
185 | + for (auto const* rawline : helptext) |
186 | + { |
187 | + int line_width = 0; |
188 | + |
189 | + auto const line = converter.from_bytes(rawline); |
190 | + |
191 | + auto const fwidth = std::min(region.width / 60, 20); |
192 | + |
193 | + FT_Set_Pixel_Sizes(face, fwidth, 0); |
194 | + |
195 | + for (auto const& ch : line) |
196 | + { |
197 | + FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT); |
198 | + auto const glyph = face->glyph; |
199 | + FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL); |
200 | + |
201 | + line_width += glyph->advance.x >> 6; |
202 | + line_height = std::max(line_height, glyph->bitmap.rows + glyph->bitmap.rows/2); |
203 | + } |
204 | + |
205 | + if (help_width < line_width) help_width = line_width; |
206 | + help_height += line_height; |
207 | + } |
208 | + |
209 | + int base_y = (region.height - help_height)/2; |
210 | + |
211 | + for (auto const* rawline : helptext) |
212 | + { |
213 | + int base_x = (region.width - help_width)/2; |
214 | + |
215 | + auto const line = converter.from_bytes(rawline); |
216 | + |
217 | + for (auto const& ch : line) |
218 | + { |
219 | + FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT); |
220 | + auto const glyph = face->glyph; |
221 | + FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL); |
222 | + |
223 | + auto const& bitmap = glyph->bitmap; |
224 | + auto const x = base_x + glyph->bitmap_left; |
225 | + |
226 | + if (static_cast<int>(x + bitmap.width) <= region.width) |
227 | + { |
228 | + unsigned char* src = bitmap.buffer; |
229 | + |
230 | + auto const y = base_y - glyph->bitmap_top; |
231 | + char* dest = region.vaddr + y * region.stride + 4 * x; |
232 | + |
233 | + for (auto row = 0u; row != bitmap.rows; ++row) |
234 | + { |
235 | + for (auto col = 0u; col != 4 * bitmap.width; ++col) |
236 | + dest[col] |= src[col / 4]/2; |
237 | + |
238 | + src += bitmap.pitch; |
239 | + dest += region.stride; |
240 | + |
241 | + if (dest > region.vaddr + region.height * region.stride) |
242 | + break; |
243 | + } |
244 | + } |
245 | + |
246 | + base_x += glyph->advance.x >> 6; |
247 | + } |
248 | + base_y += line_height; |
249 | + } |
250 | +} |
251 | } |
252 | |
253 | using namespace mir::client; |
254 | using namespace mir::geometry; |
255 | |
256 | -TitlebarProvider::TitlebarProvider(miral::WindowManagerTools const& tools) : tools{tools} |
257 | +DecorationProvider::DecorationProvider(miral::WindowManagerTools const& tools) : tools{tools} |
258 | { |
259 | |
260 | } |
261 | |
262 | -TitlebarProvider::~TitlebarProvider() |
263 | +DecorationProvider::~DecorationProvider() |
264 | { |
265 | stop(); |
266 | } |
267 | |
268 | -void TitlebarProvider::stop() |
269 | +void DecorationProvider::stop() |
270 | { |
271 | enqueue_work([this] |
272 | { |
273 | @@ -177,30 +271,75 @@ |
274 | |
275 | enqueue_work([this] |
276 | { |
277 | + wallpaper.erase(begin(wallpaper), end(wallpaper)); |
278 | connection.reset(); |
279 | stop_work(); |
280 | }); |
281 | } |
282 | |
283 | -void TitlebarProvider::operator()(mir::client::Connection connection) |
284 | +namespace |
285 | +{ |
286 | +void render_pattern(MirGraphicsRegion* region, uint8_t const pattern[]) |
287 | +{ |
288 | + char* row = region->vaddr; |
289 | + |
290 | + for (int j = 0; j < region->height; j++) |
291 | + { |
292 | + uint32_t* pixel = (uint32_t*)row; |
293 | + |
294 | + for (int i = 0; i < region->width; i++) |
295 | + memcpy(pixel + i, pattern, sizeof pixel[i]); |
296 | + |
297 | + row += region->stride; |
298 | + } |
299 | + |
300 | + static Printer printer; |
301 | + printer.printhelp(*region); |
302 | +} |
303 | +} |
304 | + |
305 | +void DecorationProvider::operator()(Connection connection) |
306 | { |
307 | this->connection = connection; |
308 | + |
309 | + DisplayConfig const display_conf{this->connection}; |
310 | + |
311 | + display_conf.for_each_output([this](MirOutput const* output) |
312 | + { |
313 | + wallpaper.push_back( |
314 | + WindowSpec::for_gloss(this->connection, 100, 100) |
315 | + .set_pixel_format(mir_pixel_format_xrgb_8888) |
316 | + .set_buffer_usage(mir_buffer_usage_software) |
317 | + .set_fullscreen_on_output(mir_output_get_id(output)) |
318 | + .set_name(wallpaper_name).create_window()); |
319 | + |
320 | + MirGraphicsRegion graphics_region; |
321 | + MirBufferStream* buffer_stream = mir_window_get_buffer_stream(wallpaper.back()); |
322 | + |
323 | + mir_buffer_stream_get_graphics_region(buffer_stream, &graphics_region); |
324 | + |
325 | + static uint8_t const pattern[4] = { 0x00, 0x00, 0x00, 0x00 }; |
326 | + |
327 | + render_pattern(&graphics_region, pattern); |
328 | + mir_buffer_stream_swap_buffers_sync(buffer_stream); |
329 | + }); |
330 | + |
331 | start_work(); |
332 | } |
333 | |
334 | -void TitlebarProvider::operator()(std::weak_ptr<mir::scene::Session> const& session) |
335 | +void DecorationProvider::operator()(std::weak_ptr<mir::scene::Session> const& session) |
336 | { |
337 | std::lock_guard<decltype(mutex)> lock{mutex}; |
338 | this->weak_session = session; |
339 | } |
340 | |
341 | -auto TitlebarProvider::session() const -> std::shared_ptr<mir::scene::Session> |
342 | +auto DecorationProvider::session() const -> std::shared_ptr<mir::scene::Session> |
343 | { |
344 | std::lock_guard<decltype(mutex)> lock{mutex}; |
345 | return weak_session.lock(); |
346 | } |
347 | |
348 | -void TitlebarProvider::create_titlebar_for(miral::Window const& window) |
349 | +void DecorationProvider::create_titlebar_for(miral::Window const& window) |
350 | { |
351 | enqueue_work([this, window] |
352 | { |
353 | @@ -220,12 +359,12 @@ |
354 | }); |
355 | } |
356 | |
357 | -void TitlebarProvider::paint_titlebar_for(miral::WindowInfo const& info, int intensity) |
358 | +void DecorationProvider::paint_titlebar_for(miral::WindowInfo const& info, int intensity) |
359 | { |
360 | - this->intensity = intensity; |
361 | - |
362 | if (auto data = find_titlebar_data(info.window())) |
363 | { |
364 | + data->intensity = intensity; |
365 | + |
366 | auto const title = info.name(); |
367 | |
368 | if (auto surface = data->titlebar.load()) |
369 | @@ -240,7 +379,7 @@ |
370 | } |
371 | } |
372 | |
373 | -void TitlebarProvider::destroy_titlebar_for(miral::Window const& window) |
374 | +void DecorationProvider::destroy_titlebar_for(miral::Window const& window) |
375 | { |
376 | if (auto data = find_titlebar_data(window)) |
377 | { |
378 | @@ -248,11 +387,7 @@ |
379 | { |
380 | enqueue_work([surface] |
381 | { |
382 | -#if MIR_CLIENT_VERSION <= MIR_VERSION_NUMBER(3, 4, 0) |
383 | - mir_surface_release(surface, &null_surface_callback, nullptr); |
384 | -#else |
385 | - mir_window_release(surface, &null_surface_callback, nullptr); |
386 | -#endif |
387 | + mir_window_release(surface, &null_window_callback, nullptr); |
388 | }); |
389 | } |
390 | |
391 | @@ -264,7 +399,7 @@ |
392 | } |
393 | } |
394 | |
395 | -void TitlebarProvider::resize_titlebar_for(miral::WindowInfo const& window_info, Size const& size) |
396 | +void DecorationProvider::resize_titlebar_for(miral::WindowInfo const& window_info, Size const& size) |
397 | { |
398 | auto const window = window_info.window(); |
399 | |
400 | @@ -279,9 +414,10 @@ |
401 | } |
402 | } |
403 | |
404 | -void TitlebarProvider::place_new_titlebar(miral::WindowSpecification& window_spec) |
405 | +void DecorationProvider::place_new_decoration(miral::WindowSpecification& window_spec) |
406 | { |
407 | auto const name = window_spec.name().value(); |
408 | + if (name == "wallpaper") return; |
409 | |
410 | std::lock_guard<decltype(mutex)> lock{mutex}; |
411 | |
412 | @@ -296,8 +432,10 @@ |
413 | window_spec.top_left() = parent_window.top_left() - Displacement{0, title_bar_height}; |
414 | } |
415 | |
416 | -void TitlebarProvider::advise_new_titlebar(miral::WindowInfo const& window_info) |
417 | +void DecorationProvider::advise_new_titlebar(miral::WindowInfo const& window_info) |
418 | { |
419 | + if (window_info.name() == wallpaper_name) return; |
420 | + |
421 | { |
422 | std::lock_guard<decltype(mutex)> lock{mutex}; |
423 | |
424 | @@ -307,7 +445,7 @@ |
425 | tools.raise_tree(window_info.parent()); |
426 | } |
427 | |
428 | -void TitlebarProvider::advise_state_change(miral::WindowInfo const& window_info, MirWindowState state) |
429 | +void DecorationProvider::advise_state_change(miral::WindowInfo const& window_info, MirWindowState state) |
430 | { |
431 | if (auto titlebar = find_titlebar_window(window_info.window())) |
432 | { |
433 | @@ -332,34 +470,33 @@ |
434 | } |
435 | } |
436 | |
437 | -void TitlebarProvider::repaint_titlebar_for(miral::WindowInfo const& window_info) |
438 | +void DecorationProvider::repaint_titlebar_for(miral::WindowInfo const& window_info) |
439 | { |
440 | if (auto data = find_titlebar_data(window_info.window())) |
441 | { |
442 | auto const title = window_info.name(); |
443 | |
444 | if (auto surface = data->titlebar.load()) |
445 | - enqueue_work([this, surface, title]{ paint_surface(surface, title, intensity); }); |
446 | + { |
447 | + enqueue_work([this, surface, title, intensity=data->intensity.load()] |
448 | + { paint_surface(surface, title, intensity); }); |
449 | + } |
450 | } |
451 | } |
452 | |
453 | -TitlebarProvider::Data::~Data() |
454 | +DecorationProvider::Data::~Data() |
455 | { |
456 | if (auto surface = titlebar.exchange(nullptr)) |
457 | -#if MIR_CLIENT_VERSION <= MIR_VERSION_NUMBER(3, 4, 0) |
458 | - mir_surface_release(surface, &null_surface_callback, nullptr); |
459 | -#else |
460 | - mir_window_release(surface, &null_surface_callback, nullptr); |
461 | -#endif |
462 | + mir_window_release(surface, &null_window_callback, nullptr); |
463 | } |
464 | |
465 | -void TitlebarProvider::insert(MirWindow* surface, Data* data) |
466 | +void DecorationProvider::insert(MirWindow* surface, Data* data) |
467 | { |
468 | data->on_create(surface); |
469 | data->titlebar = surface; |
470 | } |
471 | |
472 | -TitlebarProvider::Data* TitlebarProvider::find_titlebar_data(miral::Window const& window) |
473 | +DecorationProvider::Data* DecorationProvider::find_titlebar_data(miral::Window const& window) |
474 | { |
475 | std::lock_guard<decltype(mutex)> lock{mutex}; |
476 | |
477 | @@ -368,7 +505,7 @@ |
478 | return (find != window_to_titlebar.end()) ? &find->second : nullptr; |
479 | } |
480 | |
481 | -miral::Window TitlebarProvider::find_titlebar_window(miral::Window const& window) const |
482 | +miral::Window DecorationProvider::find_titlebar_window(miral::Window const& window) const |
483 | { |
484 | std::lock_guard<decltype(mutex)> lock{mutex}; |
485 | |
486 | @@ -377,6 +514,16 @@ |
487 | return (find != window_to_titlebar.end()) ? find->second.window : miral::Window{}; |
488 | } |
489 | |
490 | +bool DecorationProvider::is_decoration(miral::Window const& window) const |
491 | +{ |
492 | + return window.application() == session(); |
493 | +} |
494 | + |
495 | +bool DecorationProvider::is_titlebar(miral::WindowInfo const& window_info) const |
496 | +{ |
497 | + return window_info.window().application() == session() && window_info.name() != wallpaper_name; |
498 | +} |
499 | + |
500 | Worker::~Worker() |
501 | { |
502 | if (worker.joinable()) worker.join(); |
503 | |
504 | === renamed file 'miral-shell/titlebar_provider.h' => 'miral-shell/decoration_provider.h' |
505 | --- miral-shell/titlebar_provider.h 2017-02-14 11:49:59 +0000 |
506 | +++ miral-shell/decoration_provider.h 2017-02-17 15:07:17 +0000 |
507 | @@ -1,5 +1,5 @@ |
508 | /* |
509 | - * Copyright © 2016 Canonical Ltd. |
510 | + * Copyright © 2016-2017 Canonical Ltd. |
511 | * |
512 | * This program is free software: you can redistribute it and/or modify it |
513 | * under the terms of the GNU General Public License version 3, |
514 | @@ -16,19 +16,21 @@ |
515 | * Authored by: Alan Griffiths <alan@octopull.co.uk> |
516 | */ |
517 | |
518 | -#ifndef MIRAL_SHELL_TITLEBAR_PROVIDER_H |
519 | -#define MIRAL_SHELL_TITLEBAR_PROVIDER_H |
520 | +#ifndef MIRAL_SHELL_DECORATION_PROVIDER_H |
521 | +#define MIRAL_SHELL_DECORATION_PROVIDER_H |
522 | |
523 | |
524 | #include <miral/window_manager_tools.h> |
525 | |
526 | +#include <mir/client/connection.h> |
527 | +#include <mir/client/window.h> |
528 | + |
529 | #include <mir/geometry/rectangle.h> |
530 | #include <mir_toolkit/client_types.h> |
531 | |
532 | #include <atomic> |
533 | #include <map> |
534 | #include <mutex> |
535 | -#include <mir/client/connection.h> |
536 | #include <thread> |
537 | #include <condition_variable> |
538 | #include <queue> |
539 | @@ -54,11 +56,11 @@ |
540 | void do_work(); |
541 | }; |
542 | |
543 | -class TitlebarProvider : Worker |
544 | +class DecorationProvider : Worker |
545 | { |
546 | public: |
547 | - TitlebarProvider(miral::WindowManagerTools const& tools); |
548 | - ~TitlebarProvider(); |
549 | + DecorationProvider(miral::WindowManagerTools const& tools); |
550 | + ~DecorationProvider(); |
551 | |
552 | void operator()(mir::client::Connection connection); |
553 | void operator()(std::weak_ptr<mir::scene::Session> const& session); |
554 | @@ -66,7 +68,7 @@ |
555 | auto session() const -> std::shared_ptr<mir::scene::Session>; |
556 | |
557 | void create_titlebar_for(miral::Window const& window); |
558 | - void place_new_titlebar(miral::WindowSpecification& window_spec); |
559 | + void place_new_decoration(miral::WindowSpecification& window_spec); |
560 | void paint_titlebar_for(miral::WindowInfo const& window, int intensity); |
561 | void destroy_titlebar_for(miral::Window const& window); |
562 | void resize_titlebar_for(miral::WindowInfo const& window_info, mir::geometry::Size const& size); |
563 | @@ -75,10 +77,14 @@ |
564 | |
565 | void stop(); |
566 | |
567 | + bool is_decoration(miral::Window const& window) const; |
568 | + bool is_titlebar(miral::WindowInfo const& window_info) const; |
569 | + |
570 | private: |
571 | struct Data |
572 | { |
573 | std::atomic<MirWindow*> titlebar{nullptr}; |
574 | + std::atomic<int> intensity{0xff}; |
575 | std::function<void(MirWindow* surface)> on_create{[](MirWindow*){}}; |
576 | miral::Window window; |
577 | |
578 | @@ -91,8 +97,8 @@ |
579 | miral::WindowManagerTools tools; |
580 | std::mutex mutable mutex; |
581 | mir::client::Connection connection; |
582 | + std::vector<mir::client::Window> wallpaper; |
583 | std::weak_ptr<mir::scene::Session> weak_session; |
584 | - std::atomic<int> intensity{0xff}; |
585 | |
586 | SurfaceMap window_to_titlebar; |
587 | TitleMap windows_awaiting_titlebar; |
588 | @@ -104,4 +110,4 @@ |
589 | }; |
590 | |
591 | |
592 | -#endif //MIRAL_SHELL_TITLEBAR_PROVIDER_H |
593 | +#endif //MIRAL_SHELL_DECORATION_PROVIDER_H |
594 | |
595 | === modified file 'miral-shell/titlebar_window_manager.cpp' |
596 | --- miral-shell/titlebar_window_manager.cpp 2017-02-15 16:54:12 +0000 |
597 | +++ miral-shell/titlebar_window_manager.cpp 2017-02-17 15:07:17 +0000 |
598 | @@ -1,5 +1,5 @@ |
599 | /* |
600 | - * Copyright © 2016 Canonical Ltd. |
601 | + * Copyright © 2016-2017 Canonical Ltd. |
602 | * |
603 | * This program is free software: you can redistribute it and/or modify it |
604 | * under the terms of the GNU General Public License version 3, |
605 | @@ -17,7 +17,7 @@ |
606 | */ |
607 | |
608 | #include "titlebar_window_manager.h" |
609 | -#include "titlebar_provider.h" |
610 | +#include "decoration_provider.h" |
611 | |
612 | #include <miral/application_info.h> |
613 | #include <miral/internal_client.h> |
614 | @@ -40,9 +40,9 @@ |
615 | miral::InternalClientLauncher const& launcher) : |
616 | CanonicalWindowManagerPolicy(tools), |
617 | spinner{spinner}, |
618 | - titlebar_provider{std::make_unique<TitlebarProvider>(tools)} |
619 | + decoration_provider{std::make_unique<DecorationProvider>(tools)} |
620 | { |
621 | - launcher.launch("decorations", *titlebar_provider); |
622 | + launcher.launch("decorations", *decoration_provider); |
623 | } |
624 | |
625 | TitlebarWindowManagerPolicy::~TitlebarWindowManagerPolicy() = default; |
626 | @@ -99,9 +99,9 @@ |
627 | { |
628 | if (auto const possible_titlebar = tools.window_at(old_cursor)) |
629 | { |
630 | - if (possible_titlebar.application() == titlebar_provider->session()) |
631 | + auto const& info = tools.info_for(possible_titlebar); |
632 | + if (decoration_provider->is_titlebar(info)) |
633 | { |
634 | - auto const& info = tools.info_for(possible_titlebar); |
635 | if (tools.select_active_window(info.parent()) == info.parent()) |
636 | tools.drag_active_window(cursor - old_cursor); |
637 | consumes_event = true; |
638 | @@ -266,25 +266,23 @@ |
639 | { |
640 | CanonicalWindowManagerPolicy::advise_new_window(window_info); |
641 | |
642 | - auto const application = window_info.window().application(); |
643 | - |
644 | - if (application == titlebar_provider->session()) |
645 | + if (decoration_provider->is_titlebar(window_info)) |
646 | { |
647 | - titlebar_provider->advise_new_titlebar(window_info); |
648 | + decoration_provider->advise_new_titlebar(window_info); |
649 | |
650 | auto const parent = window_info.parent(); |
651 | |
652 | if (tools.active_window() == parent) |
653 | - titlebar_provider->paint_titlebar_for(tools.info_for(parent), 0xFF); |
654 | + decoration_provider->paint_titlebar_for(tools.info_for(parent), 0xFF); |
655 | else |
656 | - titlebar_provider->paint_titlebar_for(tools.info_for(parent), 0x3F); |
657 | + decoration_provider->paint_titlebar_for(tools.info_for(parent), 0x3F); |
658 | } |
659 | } |
660 | |
661 | void TitlebarWindowManagerPolicy::handle_window_ready(WindowInfo& window_info) |
662 | { |
663 | if (window_info.window().application() != spinner.session() && window_info.needs_titlebar(window_info.type())) |
664 | - titlebar_provider->create_titlebar_for(window_info.window()); |
665 | + decoration_provider->create_titlebar_for(window_info.window()); |
666 | |
667 | CanonicalWindowManagerPolicy::handle_window_ready(window_info); |
668 | } |
669 | @@ -293,14 +291,14 @@ |
670 | { |
671 | CanonicalWindowManagerPolicy::advise_focus_lost(info); |
672 | |
673 | - titlebar_provider->paint_titlebar_for(info, 0x3F); |
674 | + decoration_provider->paint_titlebar_for(info, 0x3F); |
675 | } |
676 | |
677 | void TitlebarWindowManagerPolicy::advise_focus_gained(WindowInfo const& info) |
678 | { |
679 | CanonicalWindowManagerPolicy::advise_focus_gained(info); |
680 | |
681 | - titlebar_provider->paint_titlebar_for(info, 0xFF); |
682 | + decoration_provider->paint_titlebar_for(info, 0xFF); |
683 | |
684 | // Frig to force the spinner to the top |
685 | if (auto const spinner_session = spinner.session()) |
686 | @@ -316,21 +314,21 @@ |
687 | { |
688 | CanonicalWindowManagerPolicy::advise_state_change(window_info, state); |
689 | |
690 | - titlebar_provider->advise_state_change(window_info, state); |
691 | + decoration_provider->advise_state_change(window_info, state); |
692 | } |
693 | |
694 | void TitlebarWindowManagerPolicy::advise_resize(WindowInfo const& window_info, Size const& new_size) |
695 | { |
696 | CanonicalWindowManagerPolicy::advise_resize(window_info, new_size); |
697 | |
698 | - titlebar_provider->resize_titlebar_for(window_info, new_size); |
699 | + decoration_provider->resize_titlebar_for(window_info, new_size); |
700 | } |
701 | |
702 | void TitlebarWindowManagerPolicy::advise_delete_window(WindowInfo const& window_info) |
703 | { |
704 | CanonicalWindowManagerPolicy::advise_delete_window(window_info); |
705 | |
706 | - titlebar_provider->destroy_titlebar_for(window_info.window()); |
707 | + decoration_provider->destroy_titlebar_for(window_info.window()); |
708 | } |
709 | |
710 | bool TitlebarWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event) |
711 | @@ -449,7 +447,7 @@ |
712 | if (action == mir_keyboard_action_down && scan_code == KEY_BACKSPACE && |
713 | (modifiers == (mir_input_event_modifier_alt | mir_input_event_modifier_ctrl))) |
714 | { |
715 | - titlebar_provider->stop(); |
716 | + decoration_provider->stop(); |
717 | } |
718 | |
719 | return false; |
720 | @@ -568,8 +566,8 @@ |
721 | if (parameters.state().value() != mir_window_state_fullscreen && needs_titlebar) |
722 | parameters.top_left() = Point{parameters.top_left().value().x, parameters.top_left().value().y + DeltaY{title_bar_height}}; |
723 | |
724 | - if (app_info.application() == titlebar_provider->session()) |
725 | - titlebar_provider->place_new_titlebar(parameters); |
726 | + if (app_info.application() == decoration_provider->session()) |
727 | + decoration_provider->place_new_decoration(parameters); |
728 | |
729 | return parameters; |
730 | } |
731 | |
732 | === modified file 'miral-shell/titlebar_window_manager.h' |
733 | --- miral-shell/titlebar_window_manager.h 2017-02-15 16:54:12 +0000 |
734 | +++ miral-shell/titlebar_window_manager.h 2017-02-17 15:07:17 +0000 |
735 | @@ -1,5 +1,5 @@ |
736 | /* |
737 | - * Copyright © 2016 Canonical Ltd. |
738 | + * Copyright © 2016-2017 Canonical Ltd. |
739 | * |
740 | * This program is free software: you can redistribute it and/or modify it |
741 | * under the terms of the GNU General Public License version 3, |
742 | @@ -29,7 +29,7 @@ |
743 | |
744 | using namespace mir::geometry; |
745 | |
746 | -class TitlebarProvider; |
747 | +class DecorationProvider; |
748 | |
749 | class TitlebarWindowManagerPolicy : public miral::CanonicalWindowManagerPolicy |
750 | { |
751 | @@ -92,7 +92,7 @@ |
752 | |
753 | SpinnerSplash const spinner; |
754 | |
755 | - std::unique_ptr<TitlebarProvider> const titlebar_provider; |
756 | + std::unique_ptr<DecorationProvider> const decoration_provider; |
757 | |
758 | void end_resize(); |
759 | |
760 | |
761 | === modified file 'miral/CMakeLists.txt' |
762 | --- miral/CMakeLists.txt 2017-02-14 17:31:52 +0000 |
763 | +++ miral/CMakeLists.txt 2017-02-17 15:07:17 +0000 |
764 | @@ -55,6 +55,7 @@ |
765 | ${CMAKE_SOURCE_DIR}/include/mir/client/window_spec.h |
766 | ${CMAKE_SOURCE_DIR}/include/mir/client/window_id.h |
767 | ${CMAKE_SOURCE_DIR}/include/mir/client/connection.h |
768 | + ${CMAKE_SOURCE_DIR}/include/mir/client/display_config.h |
769 | ${CMAKE_SOURCE_DIR}/include/mir/client/window.h |
770 | ${CMAKE_SOURCE_DIR}/include/mir/client/detail/mir_forward_compatibility.h |
771 | ) |
772 | @@ -101,9 +102,15 @@ |
773 | set(MIR_POINTER_CONFINEMENT 1) |
774 | endif() |
775 | |
776 | +if (MIRSERVER_VERSION VERSION_LESS 0.22) |
777 | + set(MIR_DISPLAY_CONFIG_GET_MUTABLE 0) |
778 | +else() |
779 | + set(MIR_DISPLAY_CONFIG_GET_MUTABLE 1) |
780 | +endif() |
781 | + |
782 | configure_file( |
783 | - ${CMAKE_CURRENT_SOURCE_DIR}/mir_features.h.in |
784 | - ${PROJECT_SOURCE_DIR}/include/mir/client/detail/mir_features.h |
785 | + ${CMAKE_CURRENT_SOURCE_DIR}/mir_features.h.in |
786 | + ${PROJECT_SOURCE_DIR}/include/mir/client/detail/mir_features.h |
787 | ) |
788 | |
789 | configure_file( |
790 | |
791 | === modified file 'miral/mir_features.h.in' |
792 | --- miral/mir_features.h.in 2016-09-23 13:59:34 +0000 |
793 | +++ miral/mir_features.h.in 2017-02-17 15:07:17 +0000 |
794 | @@ -24,5 +24,6 @@ |
795 | // ============================================================ |
796 | |
797 | #define MIRAL_MIR_DEFINES_POINTER_CONFINEMENT (@MIR_POINTER_CONFINEMENT@) |
798 | +#define MIR_DEFINES_DISPLAY_CONFIG_GET_MUTABLE_OUTPUT (@MIR_DISPLAY_CONFIG_GET_MUTABLE@) |
799 | |
800 | #endif // MIRAL_MIR_FEATURES_H |
Works ok.
+ for (int i = 0; i < region->width; i++)
+ memcpy(pixel + i, pattern, sizeof pixel[i]);
This can't be a single memcpy?