Merge lp:~alan-griffiths/miral/0.4 into lp:miral/release

Proposed by Alan Griffiths
Status: Merged
Approved by: Alan Griffiths
Approved revision: 334
Merged at revision: 339
Proposed branch: lp:~alan-griffiths/miral/0.4
Merge into: lp:miral/release
Diff against target: 1590 lines (+853/-178)
32 files modified
CMakeLists.txt (+1/-1)
debian/changelog (+17/-0)
debian/control (+1/-0)
debian/libmiral1.symbols (+30/-0)
include/miral/application.h (+6/-0)
include/miral/application_info.h (+2/-1)
include/miral/command_line_option.h (+100/-0)
include/miral/keymap.h (+2/-1)
include/miral/window_manager_tools.h (+4/-0)
miral-shell/CMakeLists.txt (+6/-0)
miral-shell/shell_main.cpp (+5/-1)
miral-shell/titlebar_config.cpp (+38/-0)
miral-shell/titlebar_config.h (+30/-0)
miral-shell/titlebar_provider.cpp (+123/-8)
miral-shell/titlebar_provider.h (+4/-2)
miral-shell/titlebar_window_manager.cpp (+6/-6)
miral/CMakeLists.txt (+9/-0)
miral/application.cpp (+15/-0)
miral/application_info.cpp (+7/-0)
miral/basic_window_manager.cpp (+9/-1)
miral/basic_window_manager.h (+2/-0)
miral/command_line_option.cpp (+199/-0)
miral/display_configuration_option.cpp (+2/-2)
miral/keymap.cpp (+17/-8)
miral/symbols.map (+16/-0)
miral/window_management_trace.cpp (+8/-0)
miral/window_management_trace.h (+1/-0)
miral/window_manager_tools.cpp (+3/-0)
miral/window_manager_tools_implementation.h (+1/-0)
scripts/filter_symbols_diff.sh (+2/-0)
scripts/process_doxygen_xml.py (+187/-141)
tasks_for_the_interested_reader.md (+0/-6)
To merge this branch: bzr merge lp:~alan-griffiths/miral/0.4
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
Review via email: mp+310083@code.launchpad.net

Commit message

Release 0.4.0

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :
review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> lp:1639567

Weird can't reproduce

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-10-16 16:14:18 +0000
3+++ CMakeLists.txt 2016-11-04 16:34:03 +0000
4@@ -37,7 +37,7 @@
5 include_directories(include SYSTEM ${MIRCLIENT_INCLUDE_DIRS})
6
7 set(MIRAL_VERSION_MAJOR 0)
8-set(MIRAL_VERSION_MINOR 3)
9+set(MIRAL_VERSION_MINOR 4)
10 set(MIRAL_VERSION_PATCH 0)
11
12 set(MIRAL_VERSION ${MIRAL_VERSION_MAJOR}.${MIRAL_VERSION_MINOR}.${MIRAL_VERSION_PATCH})
13
14=== modified file 'debian/changelog'
15--- debian/changelog 2016-10-28 16:03:16 +0000
16+++ debian/changelog 2016-11-04 16:34:03 +0000
17@@ -1,3 +1,20 @@
18+miral (0.4.0) UNRELEASED; urgency=medium
19+
20+ * New upstream release 0.4.0 (https://launchpad.net/miral/+milestone/0.4)
21+ - ABI summary:
22+ . miral ABI unchanged at 1
23+ - Enhancements:
24+ . Add miral::WindowManagerTools::force_close(window) to forcefully close
25+ a window (i.e. without a close request to the client)
26+ . Add functions to manage Applications
27+ . Add miral::CommandLineOption - enables the setting and processing of
28+ configuration options. These may be supplied on the commandline, as
29+ MIR_SERVER_XXX environment variables or in a config file.
30+ . Add +options to the keymap configuration
31+ . [miral-shell] Add window name to titlebars
32+
33+ -- Alan Griffiths <alan.griffiths@canonical.com> Fri, 28 Oct 2016 12:14:59 +0100
34+
35 miral (0.3.0+17.04.20161028-0ubuntu1) zesty; urgency=medium
36
37 * No change rebuild to target Xenial+Overlay
38
39=== modified file 'debian/control'
40--- debian/control 2016-09-19 13:27:49 +0000
41+++ debian/control 2016-11-04 16:34:03 +0000
42@@ -19,6 +19,7 @@
43 mirtest-dev,
44 libglib2.0-dev,
45 libgles2-mesa-dev,
46+ libfreetype6-dev,
47 # The following workaround missing dependencies in Mir packages
48 uuid-dev,
49 libboost-system-dev,
50
51=== modified file 'debian/libmiral1.symbols'
52--- debian/libmiral1.symbols 2016-10-11 13:28:07 +0000
53+++ debian/libmiral1.symbols 2016-11-04 16:34:03 +0000
54@@ -2,6 +2,7 @@
55 MIRAL_0.1@MIRAL_0.1 0.1.0
56 MIRAL_0.2@MIRAL_0.2 0.2.0
57 MIRAL_0.3@MIRAL_0.3 0.3.0
58+ MIRAL_0.4@MIRAL_0.4 0.3.0
59 (c++)"miral::ActiveOutputsListener::advise_output_begin()@MIRAL_0.1" 0.1.0
60 (c++)"miral::ActiveOutputsListener::advise_output_create(miral::Output const&)@MIRAL_0.1" 0.1.0
61 (c++)"miral::ActiveOutputsListener::advise_output_delete(miral::Output const&)@MIRAL_0.1" 0.1.0
62@@ -275,3 +276,32 @@
63 (c++)"miral::Keymap::~Keymap()@MIRAL_0.3" 0.3.0
64 (c++)"miral::Keymap::operator=(miral::Keymap const&)@MIRAL_0.3" 0.3.0
65 (c++)"miral::Keymap::operator()(mir::Server&) const@MIRAL_0.3" 0.3.0
66+ (c++)"miral::ApplicationInfo::name[abi:cxx11]() const@MIRAL_0.4" 0.4.0
67+ (c++)"miral::CommandLineOption::CommandLineOption(miral::CommandLineOption const&)@MIRAL_0.4" 0.4.0
68+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.4" 0.4.0
69+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<bool> const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.4" 0.4.0
70+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<int> const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.4" 0.4.0
71+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*)@MIRAL_0.4" 0.4.0
72+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.4" 0.4.0
73+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (bool)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.4" 0.4.0
74+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (bool)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)@MIRAL_0.4" 0.4.0
75+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (double)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, double)@MIRAL_0.4" 0.4.0
76+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (int)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)@MIRAL_0.4" 0.4.0
77+ (c++)"miral::CommandLineOption::CommandLineOption(miral::CommandLineOption const&)@MIRAL_0.4" 0.4.0
78+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.4" 0.4.0
79+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<bool> const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.4" 0.4.0
80+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (mir::optional_value<int> const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.4" 0.4.0
81+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*)@MIRAL_0.4" 0.4.0
82+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.4" 0.4.0
83+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (bool)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.4" 0.4.0
84+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (bool)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)@MIRAL_0.4" 0.4.0
85+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (double)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, double)@MIRAL_0.4" 0.4.0
86+ (c++)"miral::CommandLineOption::CommandLineOption(std::function<void (int)>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)@MIRAL_0.4" 0.4.0
87+ (c++)"miral::CommandLineOption::~CommandLineOption()@MIRAL_0.4" 0.4.0
88+ (c++)"miral::CommandLineOption::~CommandLineOption()@MIRAL_0.4" 0.4.0
89+ (c++)"miral::CommandLineOption::operator=(miral::CommandLineOption const&)@MIRAL_0.4" 0.4.0
90+ (c++)"miral::CommandLineOption::operator()(mir::Server&) const@MIRAL_0.4" 0.4.0
91+ (c++)"miral::WindowManagerTools::force_close(miral::Window const&)@MIRAL_0.4" 0.4.0
92+ (c++)"miral::apply_lifecycle_state_to(std::shared_ptr<mir::scene::Session> const&, MirLifecycleState)@MIRAL_0.4" 0.4.0
93+ (c++)"miral::pid_of(std::shared_ptr<mir::scene::Session> const&)@MIRAL_0.4" 0.4.0
94+ (c++)"miral::name_of[abi:cxx11](std::shared_ptr<mir::scene::Session> const&)@MIRAL_0.4" 0.4.0
95
96=== added directory 'debian/tmp'
97=== modified file 'include/miral/application.h'
98--- include/miral/application.h 2016-04-22 09:24:24 +0000
99+++ include/miral/application.h 2016-11-04 16:34:03 +0000
100@@ -19,7 +19,10 @@
101 #ifndef MIRAL_APPLICATION_H
102 #define MIRAL_APPLICATION_H
103
104+#include <mir_toolkit/common.h>
105+
106 #include <memory>
107+#include <string>
108
109 namespace mir
110 {
111@@ -30,7 +33,10 @@
112 {
113 using Application = std::shared_ptr<mir::scene::Session>;
114
115+void apply_lifecycle_state_to(Application const& application, MirLifecycleState state);
116 void kill(Application const& application, int sig);
117+auto name_of(Application const& application) -> std::string;
118+auto pid_of(Application const& application) -> pid_t;
119 }
120
121 #endif //MIRAL_APPLICATION_H
122
123=== modified file 'include/miral/application_info.h'
124--- include/miral/application_info.h 2016-06-07 16:26:40 +0000
125+++ include/miral/application_info.h 2016-11-04 16:34:03 +0000
126@@ -21,9 +21,9 @@
127
128 #include "miral/application.h"
129
130+#include <string>
131 #include <vector>
132
133-
134 namespace miral
135 {
136 class Window;
137@@ -36,6 +36,7 @@
138 ApplicationInfo(ApplicationInfo const& that);
139 auto operator=(ApplicationInfo const& that) -> miral::ApplicationInfo&;
140
141+ auto name() const -> std::string;
142 auto application() const -> Application;
143 auto windows() const -> std::vector <Window>&;
144 void add_window(Window const& window);
145
146=== added file 'include/miral/command_line_option.h'
147--- include/miral/command_line_option.h 1970-01-01 00:00:00 +0000
148+++ include/miral/command_line_option.h 2016-11-04 16:34:03 +0000
149@@ -0,0 +1,100 @@
150+/*
151+ * Copyright © 2016 Canonical Ltd.
152+ *
153+ * This program is free software: you can redistribute it and/or modify it
154+ * under the terms of the GNU General Public License version 3,
155+ * as published by the Free Software Foundation.
156+ *
157+ * This program is distributed in the hope that it will be useful,
158+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
159+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
160+ * GNU General Public License for more details.
161+ *
162+ * You should have received a copy of the GNU General Public License
163+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
164+ *
165+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
166+ */
167+
168+#ifndef MIRAL_COMMAND_LINE_OPTION_H
169+#define MIRAL_COMMAND_LINE_OPTION_H
170+
171+#include <mir/optional_value.h>
172+
173+#include <functional>
174+#include <memory>
175+#include <string>
176+
177+namespace mir { class Server; }
178+
179+namespace miral
180+{
181+/// Add a user configuration option to Mir's option handling.
182+/// The callback will be invoked during initialisation with a value supplied
183+/// from the command line, environment variable, config file or the default.
184+class CommandLineOption
185+{
186+public:
187+ CommandLineOption(
188+ std::function<void(int value)> callback,
189+ std::string const& option,
190+ std::string const& description,
191+ int default_value);
192+
193+ CommandLineOption(
194+ std::function<void(double value)> callback,
195+ std::string const& option,
196+ std::string const& description,
197+ double default_value);
198+
199+ CommandLineOption(
200+ std::function<void(std::string const& value)> callback,
201+ std::string const& option,
202+ std::string const& description,
203+ std::string const& default_value);
204+
205+ CommandLineOption(
206+ std::function<void(std::string const& value)> callback,
207+ std::string const& option,
208+ std::string const& description,
209+ char const* default_value);
210+
211+ CommandLineOption(
212+ std::function<void(bool value)> callback,
213+ std::string const& option,
214+ std::string const& description,
215+ bool default_value);
216+
217+ CommandLineOption(
218+ std::function<void(mir::optional_value<int> const& value)> callback,
219+ std::string const& option,
220+ std::string const& description);
221+
222+ CommandLineOption(
223+ std::function<void(mir::optional_value<std::string> const& value)> callback,
224+ std::string const& option,
225+ std::string const& description);
226+
227+ CommandLineOption(
228+ std::function<void(mir::optional_value<bool> const& value)> callback,
229+ std::string const& option,
230+ std::string const& description);
231+
232+ CommandLineOption(
233+ std::function<void(bool is_set)> callback,
234+ std::string const& option,
235+ std::string const& description);
236+
237+ void operator()(mir::Server& server) const;
238+
239+ ~CommandLineOption();
240+ CommandLineOption(CommandLineOption const&);
241+ auto operator=(CommandLineOption const&) -> CommandLineOption&;
242+
243+private:
244+ struct Self;
245+ std::shared_ptr<Self> self;
246+};
247+}
248+
249+#endif //MIRAL_COMMAND_LINE_OPTION_H
250
251=== modified file 'include/miral/keymap.h'
252--- include/miral/keymap.h 2016-10-11 13:09:35 +0000
253+++ include/miral/keymap.h 2016-11-04 16:34:03 +0000
254@@ -35,7 +35,8 @@
255 Keymap();
256
257 /// Specify a keymap.
258- /// Format is <language>[+<variant>]
259+ /// Format is <language>[+<variant>[+<options>]]
260+ /// Options is a comma separated list.
261 /// e.g. "uk" or "us+dvorak"
262 explicit Keymap(std::string const& keymap);
263 ~Keymap();
264
265=== modified file 'include/miral/window_manager_tools.h'
266--- include/miral/window_manager_tools.h 2016-10-05 16:54:07 +0000
267+++ include/miral/window_manager_tools.h 2016-11-04 16:34:03 +0000
268@@ -115,6 +115,10 @@
269 /// Send close request to the window
270 void ask_client_to_close(Window const& window);
271
272+ /// Close the window by force
273+ /// \note ask_client_to_close() is the polite way
274+ void force_close(Window const& window);
275+
276 /// retrieve the active window
277 auto active_window() const -> Window;
278
279
280=== modified file 'miral-shell/CMakeLists.txt'
281--- miral-shell/CMakeLists.txt 2016-10-06 15:36:15 +0000
282+++ miral-shell/CMakeLists.txt 2016-11-04 16:34:03 +0000
283@@ -22,8 +22,14 @@
284 tiling_window_manager.cpp tiling_window_manager.h
285 titlebar_window_manager.cpp titlebar_window_manager.h
286 titlebar_provider.cpp titlebar_provider.h
287+ titlebar_config.cpp titlebar_config.h
288 )
289
290+pkg_check_modules(FREETYPE freetype2 REQUIRED)
291+target_include_directories(miral-shell PUBLIC ${FREETYPE_INCLUDE_DIRS})
292+target_compile_definitions(miral-shell PUBLIC -DTYPO_SUPPORTS_FREETYPE)
293+target_link_libraries(miral-shell ${FREETYPE_LIBRARIES})
294+
295 target_link_libraries(miral-shell
296 miral-spinner
297 miral
298
299=== modified file 'miral-shell/shell_main.cpp'
300--- miral-shell/shell_main.cpp 2016-10-11 13:09:35 +0000
301+++ miral-shell/shell_main.cpp 2016-11-04 16:34:03 +0000
302@@ -18,6 +18,7 @@
303
304 #include "tiling_window_manager.h"
305 #include "titlebar_window_manager.h"
306+#include "titlebar_config.h"
307 #include "spinner/splash.h"
308
309 #include <miral/display_configuration_option.h>
310@@ -25,6 +26,7 @@
311 #include <miral/window_management_options.h>
312 #include <miral/append_event_filter.h>
313 #include <miral/internal_client.h>
314+#include <miral/command_line_option.h>
315 #include <miral/cursor_theme.h>
316 #include <miral/keymap.h>
317
318@@ -80,6 +82,8 @@
319 outputs_monitor,
320 config_keymap,
321 AppendEventFilter{quit_on_ctrl_alt_bksp},
322- StartupInternalClient{"Intro", spinner}
323+ StartupInternalClient{"Intro", spinner},
324+ CommandLineOption{[&](std::string const& typeface) { ::titlebar::font_file(typeface); },
325+ "shell-titlebar-font", "font file to use for titlebars", ::titlebar::font_file()}
326 });
327 }
328
329=== added file 'miral-shell/titlebar_config.cpp'
330--- miral-shell/titlebar_config.cpp 1970-01-01 00:00:00 +0000
331+++ miral-shell/titlebar_config.cpp 2016-11-04 16:34:03 +0000
332@@ -0,0 +1,38 @@
333+/*
334+ * Copyright © 2016 Canonical Ltd.
335+ *
336+ * This program is free software: you can redistribute it and/or modify it
337+ * under the terms of the GNU General Public License version 3,
338+ * as published by the Free Software Foundation.
339+ *
340+ * This program is distributed in the hope that it will be useful,
341+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
342+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
343+ * GNU General Public License for more details.
344+ *
345+ * You should have received a copy of the GNU General Public License
346+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
347+ *
348+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
349+ */
350+
351+#include "titlebar_config.h"
352+#include <mutex>
353+
354+namespace
355+{
356+std::mutex mutex;
357+std::string font_file{"/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-B.ttf"};
358+}
359+
360+void titlebar::font_file(std::string const& font_file)
361+{
362+ std::lock_guard<decltype(mutex)> lock{mutex};
363+ ::font_file = font_file;
364+}
365+
366+auto titlebar::font_file() -> std::string
367+{
368+ std::lock_guard<decltype(mutex)> lock{mutex};
369+ return ::font_file;
370+}
371
372=== added file 'miral-shell/titlebar_config.h'
373--- miral-shell/titlebar_config.h 1970-01-01 00:00:00 +0000
374+++ miral-shell/titlebar_config.h 2016-11-04 16:34:03 +0000
375@@ -0,0 +1,30 @@
376+/*
377+ * Copyright © 2016 Canonical Ltd.
378+ *
379+ * This program is free software: you can redistribute it and/or modify it
380+ * under the terms of the GNU General Public License version 3,
381+ * as published by the Free Software Foundation.
382+ *
383+ * This program is distributed in the hope that it will be useful,
384+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
385+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
386+ * GNU General Public License for more details.
387+ *
388+ * You should have received a copy of the GNU General Public License
389+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
390+ *
391+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
392+ */
393+
394+#ifndef MIRAL_TITLEBAR_CONFIG_H
395+#define MIRAL_TITLEBAR_CONFIG_H
396+
397+#include <string>
398+
399+namespace titlebar
400+{
401+void font_file(std::string const& font_file);
402+auto font_file() -> std::string;
403+}
404+
405+#endif //MIRAL_TITLEBAR_CONFIG_H
406
407=== modified file 'miral-shell/titlebar_provider.cpp'
408--- miral-shell/titlebar_provider.cpp 2016-10-05 16:54:07 +0000
409+++ miral-shell/titlebar_provider.cpp 2016-11-04 16:34:03 +0000
410@@ -17,21 +17,47 @@
411 */
412
413 #include "titlebar_provider.h"
414+#include "titlebar_config.h"
415
416 #include <miral/toolkit/surface_spec.h>
417
418 #include <mir_toolkit/mir_buffer_stream.h>
419
420+#include <ft2build.h>
421+#include FT_FREETYPE_H
422+
423+#include <locale>
424+#include <codecvt>
425+#include <string>
426 #include <cstring>
427 #include <sstream>
428
429+#include <iostream>
430+
431 namespace
432 {
433-int const title_bar_height = 10;
434+int const title_bar_height = 12;
435
436 void null_surface_callback(MirSurface*, void*) {}
437
438-void paint_surface(MirSurface* surface, int const intensity)
439+struct Printer
440+{
441+ Printer();
442+ ~Printer();
443+ Printer(Printer const&) = delete;
444+ Printer& operator=(Printer const&) = delete;
445+
446+ void print(MirGraphicsRegion const& region, std::string const& title, int const intensity);
447+
448+private:
449+ std::wstring_convert<std::codecvt_utf16<wchar_t>> converter;
450+
451+ bool working = false;
452+ FT_Library lib;
453+ FT_Face face;
454+};
455+
456+void paint_surface(MirSurface* surface, std::string const& title, int const intensity)
457 {
458 MirBufferStream* buffer_stream = mir_surface_get_buffer_stream(surface);
459
460@@ -51,8 +77,77 @@
461 row += region.stride;
462 }
463
464+ static Printer printer;
465+ printer.print(region, title, intensity);
466+
467 mir_buffer_stream_swap_buffers_sync(buffer_stream);
468 }
469+
470+Printer::Printer()
471+{
472+ if (FT_Init_FreeType(&lib))
473+ return;
474+
475+ if (FT_New_Face(lib, titlebar::font_file().c_str(), 0, &face))
476+ {
477+ std::cerr << "WARNING: failed to load titlebar font: \"" << titlebar::font_file() << "\"\n";
478+ FT_Done_FreeType(lib);
479+ return;
480+ }
481+
482+ FT_Set_Pixel_Sizes(face, 0, 10);
483+ working = true;
484+}
485+
486+Printer::~Printer()
487+{
488+ if (working)
489+ {
490+ FT_Done_Face(face);
491+ FT_Done_FreeType(lib);
492+ }
493+}
494+
495+void Printer::print(MirGraphicsRegion const& region, std::string const& title_, int const intensity)
496+{
497+ if (!working)
498+ return;
499+
500+ auto title = converter.from_bytes(title_);
501+
502+ int base_x = 2;
503+ int base_y = region.height-2;
504+
505+ for (auto const& ch : title)
506+ {
507+ FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT);
508+ auto const glyph = face->glyph;
509+ FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL);
510+
511+ auto const& bitmap = glyph->bitmap;
512+ auto const x = base_x + glyph->bitmap_left;
513+
514+ if (static_cast<int>(x + bitmap.width) <= region.width)
515+ {
516+ unsigned char* src = bitmap.buffer;
517+
518+ auto const y = base_y - glyph->bitmap_top;
519+ char* dest = region.vaddr + y*region.stride + 4*x;
520+
521+ for (auto row = 0u; row != std::min(bitmap.rows, glyph->bitmap_top+2u); ++row)
522+ {
523+ for (auto col = 0u; col != bitmap.width; ++col)
524+ memset(dest+ 4*col, (intensity*(0xff^src[col]))/0xff, 4);
525+
526+ src += bitmap.pitch;
527+ dest += region.stride;
528+ }
529+ }
530+
531+ base_x += glyph->advance.x >> 6;
532+ base_y += glyph->advance.y >> 6;
533+ }
534+}
535 }
536
537 using namespace miral::toolkit;
538@@ -121,18 +216,22 @@
539 });
540 }
541
542-void TitlebarProvider::paint_titlebar_for(miral::Window const& window, int intensity)
543+void TitlebarProvider::paint_titlebar_for(miral::WindowInfo const& info, int intensity)
544 {
545- if (auto data = find_titlebar_data(window))
546+ this->intensity = intensity;
547+
548+ if (auto data = find_titlebar_data(info.window()))
549 {
550+ auto const title = info.name();
551+
552 if (auto surface = data->titlebar.load())
553 {
554- enqueue_work([this, surface, intensity]{ paint_surface(surface, intensity); });
555+ enqueue_work([this, surface, title, intensity]{ paint_surface(surface, title, intensity); });
556 }
557 else
558 {
559- data->on_create = [this, intensity](MirSurface* surface)
560- { enqueue_work([this, surface, intensity]{ paint_surface(surface, intensity); }); };
561+ data->on_create = [this, title, intensity](MirSurface* surface)
562+ { enqueue_work([this, surface, title, intensity]{ paint_surface(surface, title, intensity); }); };
563 }
564 }
565 }
566@@ -157,14 +256,18 @@
567 }
568 }
569
570-void TitlebarProvider::resize_titlebar_for(miral::Window const& window, Size const& size)
571+void TitlebarProvider::resize_titlebar_for(miral::WindowInfo const& window_info, Size const& size)
572 {
573+ auto const window = window_info.window();
574+
575 if (window.size().width == size.width)
576 return;
577
578 if (auto titlebar_window = find_titlebar_window(window))
579 {
580 titlebar_window.resize({size.width, title_bar_height});
581+
582+ repaint_titlebar_for(window_info);
583 }
584 }
585
586@@ -217,6 +320,18 @@
587 }
588
589 tools.modify_window(titlebar, modifications);
590+ repaint_titlebar_for(window_info);
591+ }
592+}
593+
594+void TitlebarProvider::repaint_titlebar_for(miral::WindowInfo const& window_info)
595+{
596+ if (auto data = find_titlebar_data(window_info.window()))
597+ {
598+ auto const title = window_info.name();
599+
600+ if (auto surface = data->titlebar.load())
601+ enqueue_work([this, surface, title]{ paint_surface(surface, title, intensity); });
602 }
603 }
604
605
606=== modified file 'miral-shell/titlebar_provider.h'
607--- miral-shell/titlebar_provider.h 2016-08-10 11:48:02 +0000
608+++ miral-shell/titlebar_provider.h 2016-11-04 16:34:03 +0000
609@@ -67,9 +67,9 @@
610
611 void create_titlebar_for(miral::Window const& window);
612 void place_new_titlebar(miral::WindowSpecification& window_spec);
613- void paint_titlebar_for(miral::Window const& window, int intensity);
614+ void paint_titlebar_for(miral::WindowInfo const& window, int intensity);
615 void destroy_titlebar_for(miral::Window const& window);
616- void resize_titlebar_for(miral::Window const& window, mir::geometry::Size const& size);
617+ void resize_titlebar_for(miral::WindowInfo const& window_info, mir::geometry::Size const& size);
618 void advise_new_titlebar(miral::WindowInfo const& window_info);
619 void advise_state_change(miral::WindowInfo const& window_info, MirSurfaceState state);
620
621@@ -92,6 +92,7 @@
622 std::mutex mutable mutex;
623 miral::toolkit::Connection connection;
624 std::weak_ptr<mir::scene::Session> weak_session;
625+ std::atomic<int> intensity{0xff};
626
627 SurfaceMap window_to_titlebar;
628 TitleMap windows_awaiting_titlebar;
629@@ -99,6 +100,7 @@
630 static void insert(MirSurface* surface, Data* data);
631 Data* find_titlebar_data(miral::Window const& window);
632 miral::Window find_titlebar_window(miral::Window const& window) const;
633+ void repaint_titlebar_for(miral::WindowInfo const& window_info);
634 };
635
636
637
638=== modified file 'miral-shell/titlebar_window_manager.cpp'
639--- miral-shell/titlebar_window_manager.cpp 2016-10-06 08:31:39 +0000
640+++ miral-shell/titlebar_window_manager.cpp 2016-11-04 16:34:03 +0000
641@@ -31,7 +31,7 @@
642
643 namespace
644 {
645-int const title_bar_height = 10;
646+int const title_bar_height = 12;
647 }
648
649 TitlebarWindowManagerPolicy::TitlebarWindowManagerPolicy(
650@@ -275,9 +275,9 @@
651 auto const parent = window_info.parent();
652
653 if (tools.active_window() == parent)
654- titlebar_provider->paint_titlebar_for(parent, 0xFF);
655+ titlebar_provider->paint_titlebar_for(tools.info_for(parent), 0xFF);
656 else
657- titlebar_provider->paint_titlebar_for(parent, 0x3F);
658+ titlebar_provider->paint_titlebar_for(tools.info_for(parent), 0x3F);
659 }
660 }
661
662@@ -293,14 +293,14 @@
663 {
664 CanonicalWindowManagerPolicy::advise_focus_lost(info);
665
666- titlebar_provider->paint_titlebar_for(info.window(), 0x3F);
667+ titlebar_provider->paint_titlebar_for(info, 0x3F);
668 }
669
670 void TitlebarWindowManagerPolicy::advise_focus_gained(WindowInfo const& info)
671 {
672 CanonicalWindowManagerPolicy::advise_focus_gained(info);
673
674- titlebar_provider->paint_titlebar_for(info.window(), 0xFF);
675+ titlebar_provider->paint_titlebar_for(info, 0xFF);
676
677 // Frig to force the spinner to the top
678 if (auto const spinner_session = spinner.session())
679@@ -323,7 +323,7 @@
680 {
681 CanonicalWindowManagerPolicy::advise_resize(window_info, new_size);
682
683- titlebar_provider->resize_titlebar_for(window_info.window(), new_size);
684+ titlebar_provider->resize_titlebar_for(window_info, new_size);
685 }
686
687 void TitlebarWindowManagerPolicy::advise_delete_window(WindowInfo const& window_info)
688
689=== modified file 'miral/CMakeLists.txt'
690--- miral/CMakeLists.txt 2016-10-16 16:14:18 +0000
691+++ miral/CMakeLists.txt 2016-11-04 16:34:03 +0000
692@@ -31,6 +31,7 @@
693 application_authorizer.cpp ${CMAKE_SOURCE_DIR}/include/miral/application_authorizer.h
694 application_info.cpp ${CMAKE_SOURCE_DIR}/include/miral/application_info.h
695 canonical_window_manager.cpp ${CMAKE_SOURCE_DIR}/include/miral/canonical_window_manager.h
696+ command_line_option.cpp ${CMAKE_SOURCE_DIR}/include/miral/command_line_option.h
697 cursor_theme.cpp ${CMAKE_SOURCE_DIR}/include/miral/cursor_theme.h
698 keymap.cpp ${CMAKE_SOURCE_DIR}/include/miral/keymap.h
699 runner.cpp ${CMAKE_SOURCE_DIR}/include/miral/runner.h
700@@ -70,6 +71,14 @@
701 LINK_DEPENDS ${symbol_map}
702 )
703
704+
705+add_custom_target(check-symbols ALL
706+ DEPENDS miral ${PROJECT_SOURCE_DIR}/debian/libmiral1.symbols
707+ COMMAND dpkg-gensymbols -e${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libmiral.so.1 -plibmiral1 | scripts/filter_symbols_diff.sh
708+ WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
709+ VERBATIM
710+)
711+
712 set(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}")
713 set(INCLUDEDIR "${CMAKE_INSTALL_PREFIX}/include/miral")
714
715
716=== modified file 'miral/application.cpp'
717--- miral/application.cpp 2016-07-07 14:24:32 +0000
718+++ miral/application.cpp 2016-11-04 16:34:03 +0000
719@@ -34,3 +34,18 @@
720 ::kill(pid, sig);
721 }
722 }
723+
724+auto miral::name_of(Application const& application) -> std::string
725+{
726+ return application->name();
727+}
728+
729+auto miral::pid_of(Application const& application) -> pid_t
730+{
731+ return application->process_id();
732+}
733+
734+void miral::apply_lifecycle_state_to(Application const& application, MirLifecycleState state)
735+{
736+ application->set_lifecycle_state(state);
737+}
738
739=== modified file 'miral/application_info.cpp'
740--- miral/application_info.cpp 2016-06-08 21:20:40 +0000
741+++ miral/application_info.cpp 2016-11-04 16:34:03 +0000
742@@ -19,6 +19,8 @@
743 #include "miral/application_info.h"
744 #include "miral/window.h"
745
746+#include <mir/scene/session.h>
747+
748 struct miral::ApplicationInfo::Self
749 {
750 Self() = default;
751@@ -52,6 +54,11 @@
752 return *this;
753 }
754
755+auto miral::ApplicationInfo::name() const -> std::string
756+{
757+ return self->app ? self->app->name() : std::string{};
758+}
759+
760 auto miral::ApplicationInfo::application() const -> Application
761 {
762 return self->app;
763
764=== modified file 'miral/basic_window_manager.cpp'
765--- miral/basic_window_manager.cpp 2016-10-10 14:53:39 +0000
766+++ miral/basic_window_manager.cpp 2016-11-04 16:34:03 +0000
767@@ -36,7 +36,7 @@
768
769 namespace
770 {
771-int const title_bar_height = 10;
772+int const title_bar_height = 12;
773
774 struct Locker
775 {
776@@ -400,6 +400,14 @@
777 mir_surface->request_client_surface_close();
778 }
779
780+void miral::BasicWindowManager::force_close(Window const& window)
781+{
782+ auto application = window.application();
783+
784+ if (application && window)
785+ remove_surface(application, window);
786+}
787+
788 auto miral::BasicWindowManager::active_window() const -> Window
789 {
790 return mru_active_windows.top();
791
792=== modified file 'miral/basic_window_manager.h'
793--- miral/basic_window_manager.h 2016-09-29 14:41:11 +0000
794+++ miral/basic_window_manager.h 2016-11-04 16:34:03 +0000
795@@ -112,6 +112,8 @@
796
797 void ask_client_to_close(Window const& window) override;
798
799+ void force_close(Window const& window) override;
800+
801 auto active_window() const -> Window override;
802
803 auto select_active_window(Window const& hint) -> Window override;
804
805=== added file 'miral/command_line_option.cpp'
806--- miral/command_line_option.cpp 1970-01-01 00:00:00 +0000
807+++ miral/command_line_option.cpp 2016-11-04 16:34:03 +0000
808@@ -0,0 +1,199 @@
809+/*
810+ * Copyright © 2016 Canonical Ltd.
811+ *
812+ * This program is free software: you can redistribute it and/or modify it
813+ * under the terms of the GNU General Public License version 3,
814+ * as published by the Free Software Foundation.
815+ *
816+ * This program is distributed in the hope that it will be useful,
817+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
818+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
819+ * GNU General Public License for more details.
820+ *
821+ * You should have received a copy of the GNU General Public License
822+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
823+ *
824+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
825+ */
826+
827+#include "miral/command_line_option.h"
828+
829+#include <mir/server.h>
830+#include <mir/options/option.h>
831+
832+namespace
833+{
834+template<typename Type>
835+struct OptionType;
836+
837+template<>
838+struct OptionType<bool>
839+{
840+ auto static constexpr value = mir::OptionType::boolean;
841+};
842+
843+template<>
844+struct OptionType<void>
845+{
846+ auto static constexpr value = mir::OptionType::null;
847+};
848+
849+template<>
850+struct OptionType<std::string>
851+{
852+ auto static constexpr value = mir::OptionType::string;
853+};
854+
855+template<>
856+struct OptionType<int>
857+{
858+ auto static constexpr value = mir::OptionType::integer;
859+};
860+}
861+
862+struct miral::CommandLineOption::Self
863+{
864+ template<typename Value_t>
865+ Self(std::function<void(Value_t value)> callback,
866+ std::string const& option,
867+ std::string const& description,
868+ Value_t default_value) :
869+ setup{[=](mir::Server& server)
870+ { server.add_configuration_option(option, description, default_value); }},
871+ callback{[=](mir::Server& server)
872+ { callback(server.get_options()->get<Value_t>(option.c_str())); }}
873+ {
874+ }
875+
876+ template<typename Value_t>
877+ Self(std::function<void(Value_t const& value)> callback,
878+ std::string const& option,
879+ std::string const& description,
880+ Value_t const& default_value) :
881+ setup{[=](mir::Server& server)
882+ { server.add_configuration_option(option, description, default_value); }},
883+ callback{[=](mir::Server& server)
884+ { callback(server.get_options()->get<Value_t>(option.c_str())); }}
885+ {
886+ }
887+
888+ template<typename Value_t>
889+ Self(std::function<void(mir::optional_value<Value_t> const& value)> callback,
890+ std::string const& option,
891+ std::string const& description) :
892+ setup{[=](mir::Server& server)
893+ { server.add_configuration_option(option, description, OptionType<Value_t>::value); }},
894+ callback{[=](mir::Server& server)
895+ {
896+ mir::optional_value<Value_t> optional_value;
897+ auto const options = server.get_options();
898+ if (options->is_set(option.c_str()))
899+ optional_value = server.get_options()->get<Value_t>(option.c_str());
900+ callback(optional_value);
901+ }}
902+ {
903+ }
904+
905+ Self(std::function<void(bool is_set)> callback,
906+ std::string const& option,
907+ std::string const& description) :
908+ setup{[=](mir::Server& server)
909+ { server.add_configuration_option(option, description, OptionType<void>::value); }},
910+ callback{[=](mir::Server& server)
911+ {
912+ auto const options = server.get_options();
913+ callback(options->is_set(option.c_str()));
914+ }}
915+ {
916+ }
917+
918+ std::function<void(mir::Server& server)> setup;
919+ std::function<void(mir::Server& server)> callback;
920+};
921+
922+miral::CommandLineOption::CommandLineOption(
923+ std::function<void(int value)> callback,
924+ std::string const& option,
925+ std::string const& description,
926+ int default_value) :
927+ self{std::make_shared<Self>(callback, option, description, default_value)}
928+{
929+}
930+
931+miral::CommandLineOption::CommandLineOption(
932+ std::function<void(double value)> callback,
933+ std::string const& option,
934+ std::string const& description,
935+ double default_value) :
936+ self{std::make_shared<Self>(callback, option, description, default_value)}
937+{
938+}
939+
940+miral::CommandLineOption::CommandLineOption(
941+ std::function<void(std::string const& value)> callback,
942+ std::string const& option,
943+ std::string const& description,
944+ std::string const& default_value) :
945+ self{std::make_shared<Self>(callback, option, description, default_value)}
946+{
947+}
948+
949+miral::CommandLineOption::CommandLineOption(
950+ std::function<void(std::string const& value)> callback,
951+ std::string const& option,
952+ std::string const& description,
953+ char const* default_value) :
954+ self{std::make_shared<Self>(callback, option, description, std::string{default_value})}
955+{
956+}
957+
958+miral::CommandLineOption::CommandLineOption(
959+ std::function<void(bool value)> callback,
960+ std::string const& option,
961+ std::string const& description,
962+ bool default_value) :
963+ self{std::make_shared<Self>(callback, option, description, default_value)}
964+{
965+}
966+
967+miral::CommandLineOption::CommandLineOption(
968+ std::function<void(mir::optional_value<int> const& value)> callback,
969+ std::string const& option,
970+ std::string const& description) :
971+ self{std::make_shared<Self>(callback, option, description)}
972+{
973+}
974+
975+miral::CommandLineOption::CommandLineOption(
976+ std::function<void(mir::optional_value<std::string> const& value)> callback,
977+ std::string const& option,
978+ std::string const& description) :
979+ self{std::make_shared<Self>(callback, option, description)}
980+{
981+}
982+
983+miral::CommandLineOption::CommandLineOption(
984+ std::function<void(mir::optional_value<bool> const& value)> callback,
985+ std::string const& option,
986+ std::string const& description) :
987+ self{std::make_shared<Self>(callback, option, description)}
988+{
989+}
990+
991+miral::CommandLineOption::CommandLineOption(
992+ std::function<void(bool is_set)> callback,
993+ std::string const& option,
994+ std::string const& description) :
995+ self{std::make_shared<Self>(callback, option, description)}
996+{
997+}
998+
999+void miral::CommandLineOption::operator()(mir::Server& server) const
1000+{
1001+ self->setup(server);
1002+ server.add_init_callback([&]{ self->callback(server); });
1003+}
1004+
1005+miral::CommandLineOption::~CommandLineOption() = default;
1006+miral::CommandLineOption::CommandLineOption(CommandLineOption const&) = default;
1007+auto miral::CommandLineOption::operator=(CommandLineOption const&) -> CommandLineOption& = default;
1008
1009=== modified file 'miral/display_configuration_option.cpp'
1010--- miral/display_configuration_option.cpp 2016-04-05 11:10:11 +0000
1011+++ miral/display_configuration_option.cpp 2016-11-04 16:34:03 +0000
1012@@ -58,13 +58,13 @@
1013 }
1014
1015 PixelFormatSelector::PixelFormatSelector(
1016- std::shared_ptr<DisplayConfigurationPolicy> const& base_policy,
1017+ std::shared_ptr<mg::DisplayConfigurationPolicy> const& base_policy,
1018 bool with_alpha) :
1019 base_policy{base_policy},
1020 with_alpha{with_alpha}
1021 {}
1022
1023-void PixelFormatSelector::apply_to(mg::DisplayConfiguration & conf)
1024+void PixelFormatSelector::apply_to(mg::DisplayConfiguration& conf)
1025 {
1026 base_policy->apply_to(conf);
1027 conf.for_each_output(
1028
1029=== modified file 'miral/keymap.cpp'
1030--- miral/keymap.cpp 2016-10-12 10:30:01 +0000
1031+++ miral/keymap.cpp 2016-11-04 16:34:03 +0000
1032@@ -53,13 +53,20 @@
1033 void set_keymap(std::string const& keymap)
1034 {
1035 std::lock_guard<decltype(mutex)> lock{mutex};
1036-
1037- auto const i = keymap.find('+');
1038-
1039- layout = keymap.substr(0, i);
1040-
1041- if (i != std::string::npos)
1042- variant = keymap.substr(i + 1);
1043+ auto get_next_token = [km = keymap]() mutable
1044+ {
1045+ auto const i = km.find('+');
1046+ auto ret = km.substr(0,i);
1047+ if (i != std::string::npos)
1048+ km = km.substr(i+1, std::string::npos);
1049+ else
1050+ km = "";
1051+ return ret;
1052+ };
1053+
1054+ layout = get_next_token();
1055+ variant = get_next_token();
1056+ options = get_next_token();
1057
1058 for (auto const& keyboard : keyboards)
1059 apply_keymap(keyboard);
1060@@ -110,6 +117,7 @@
1061
1062 keymap.layout = layout;
1063 keymap.variant = variant;
1064+ keymap.options = options;
1065 keyboard->apply_keyboard_configuration(std::move(keymap));
1066 }
1067 #else
1068@@ -134,6 +142,7 @@
1069 std::mutex mutable mutex;
1070 std::string layout;
1071 std::string variant;
1072+ std::string options;
1073 std::vector<std::shared_ptr<mir::input::Device>> keyboards;
1074 };
1075
1076@@ -156,7 +165,7 @@
1077 void miral::Keymap::operator()(mir::Server& server) const
1078 {
1079 if (self->layout.empty())
1080- server.add_configuration_option(keymap_option, "keymap <layout>[+<variant>], e,g, \"gb\" or \"cz+qwerty\"", keymap_default);
1081+ server.add_configuration_option(keymap_option, "keymap <layout>[+<variant>[+<options>]], e,g, \"gb\" or \"cz+qwerty\" or \"de++compose:caps\"", keymap_default);
1082
1083 server.add_init_callback([this, &server]
1084 {
1085
1086=== modified file 'miral/symbols.map'
1087--- miral/symbols.map 2016-10-11 11:51:49 +0000
1088+++ miral/symbols.map 2016-11-04 16:34:03 +0000
1089@@ -313,3 +313,19 @@
1090 vtable?for?miral::Keymap;
1091 };
1092 } MIRAL_0.2;
1093+
1094+MIRAL_0.4 {
1095+global:
1096+ extern "C++" {
1097+ miral::ApplicationInfo::name*;
1098+ miral::CommandLineOption::?CommandLineOption*;
1099+ miral::CommandLineOption::CommandLineOption*;
1100+ miral::CommandLineOption::operator*;
1101+ miral::WindowManagerTools::force_close*;
1102+ miral::apply_lifecycle_state_to*;
1103+ miral::name_of*;
1104+ miral::pid_of*;
1105+ typeinfo?for?miral::CommandLineOption;
1106+ vtable?for?miral::CommandLineOption;
1107+ };
1108+} MIRAL_0.3;
1109
1110=== modified file 'miral/window_management_trace.cpp'
1111--- miral/window_management_trace.cpp 2016-10-04 13:58:00 +0000
1112+++ miral/window_management_trace.cpp 2016-11-04 16:34:03 +0000
1113@@ -363,6 +363,14 @@
1114 wrapped.ask_client_to_close(window);
1115 }
1116
1117+void miral::WindowManagementTrace::force_close(miral::Window const& window)
1118+{
1119+ log_input();
1120+ mir::log_info("%s -> %s", __func__, dump_of(window).c_str());
1121+ trace_count++;
1122+ wrapped.force_close(window);
1123+}
1124+
1125 auto miral::WindowManagementTrace::active_window() const -> Window
1126 {
1127 log_input();
1128
1129=== modified file 'miral/window_management_trace.h'
1130--- miral/window_management_trace.h 2016-09-29 14:41:11 +0000
1131+++ miral/window_management_trace.h 2016-11-04 16:34:03 +0000
1132@@ -49,6 +49,7 @@
1133 virtual auto info_for(Window const& window) const -> WindowInfo& override;
1134
1135 virtual void ask_client_to_close(Window const& window) override;
1136+ virtual void force_close(Window const& window) override;
1137
1138 virtual auto active_window() const -> Window override;
1139 virtual auto select_active_window(Window const& hint) -> Window override;
1140
1141=== modified file 'miral/window_manager_tools.cpp'
1142--- miral/window_manager_tools.cpp 2016-10-05 16:54:07 +0000
1143+++ miral/window_manager_tools.cpp 2016-11-04 16:34:03 +0000
1144@@ -50,6 +50,9 @@
1145 void miral::WindowManagerTools::ask_client_to_close(Window const& window)
1146 { tools->ask_client_to_close(window); }
1147
1148+void miral::WindowManagerTools::force_close(Window const& window)
1149+{ tools->force_close(window); }
1150+
1151 auto miral::WindowManagerTools::active_window() const -> Window
1152 { return tools->active_window(); }
1153
1154
1155=== modified file 'miral/window_manager_tools_implementation.h'
1156--- miral/window_manager_tools_implementation.h 2016-09-29 14:41:11 +0000
1157+++ miral/window_manager_tools_implementation.h 2016-11-04 16:34:03 +0000
1158@@ -54,6 +54,7 @@
1159 virtual auto info_for(Window const& window) const -> WindowInfo& = 0;
1160
1161 virtual void ask_client_to_close(Window const& window) = 0;
1162+ virtual void force_close(Window const& window) = 0;
1163 virtual auto active_window() const -> Window = 0;
1164 virtual auto select_active_window(Window const& hint) -> Window = 0;
1165 virtual void drag_active_window(mir::geometry::Displacement movement) = 0;
1166
1167=== added file 'scripts/filter_symbols_diff.sh'
1168--- scripts/filter_symbols_diff.sh 1970-01-01 00:00:00 +0000
1169+++ scripts/filter_symbols_diff.sh 2016-11-04 16:34:03 +0000
1170@@ -0,0 +1,2 @@
1171+#!/bin/sh
1172+c++filt | sed 's/+ \([^@]*[^[:space:]]*\)\(.*\)/+ (c++)"\1"\2/'
1173
1174=== modified file 'scripts/process_doxygen_xml.py'
1175--- scripts/process_doxygen_xml.py 2016-10-06 08:26:40 +0000
1176+++ scripts/process_doxygen_xml.py 2016-11-04 16:34:03 +0000
1177@@ -1,79 +1,87 @@
1178 #! /usr/bin/python
1179-from xml.dom import minidom
1180-from sys import argv
1181-
1182-helptext = \
1183 """This script processes the XML generated by "make doc" and produces summary information
1184 on symbols that libmiral intends to make public.
1185
1186 To use: Go to your build folder and run "make symbols"""""
1187
1188-debug = False
1189-
1190-def get_text(node):
1191- rc = []
1192+from xml.dom import minidom
1193+from sys import argv
1194+
1195+HELPTEXT = __doc__
1196+DEBUG = False
1197+
1198+def _get_text(node):
1199+ substrings = []
1200 for node in node.childNodes:
1201 if node.nodeType == node.TEXT_NODE:
1202- rc.append(node.data)
1203+ substrings.append(node.data)
1204 elif node.nodeType == node.ELEMENT_NODE:
1205- rc.append(get_text(node))
1206- return ''.join(rc)
1207-
1208-def get_text_for_element(parent, tagname):
1209- rc = []
1210- nodes = parent.getElementsByTagName(tagname);
1211- for node in nodes : rc.append(get_text(node))
1212- return ''.join(rc)
1213-
1214-def get_file_location(node):
1215+ substrings.append(_get_text(node))
1216+ return ''.join(substrings)
1217+
1218+def _get_text_for_element(parent, tagname):
1219+ substrings = []
1220+
1221+ for node in parent.getElementsByTagName(tagname):
1222+ substrings.append(_get_text(node))
1223+
1224+ return ''.join(substrings)
1225+
1226+def _get_file_location(node):
1227 for node in node.childNodes:
1228 if node.nodeType == node.ELEMENT_NODE and node.tagName == 'location':
1229 return node.attributes['file'].value
1230- if debug: print 'no location in:', node
1231+ if DEBUG:
1232+ print 'no location in:', node
1233 return None
1234-
1235-def has_element(node, tagname):
1236+
1237+def _has_element(node, tagname):
1238 for node in node.childNodes:
1239 if node.nodeType == node.ELEMENT_NODE and node.tagName in tagname:
1240 return True
1241 return False
1242
1243-def print_attribs(node, attribs):
1244- for attrib in attribs : print ' ', attrib, '=', node.attributes[attrib].value
1245-
1246-def concat_text_from_tags(parent, tagnames):
1247- rc = []
1248- for tag in tagnames : rc.append(get_text_for_element(parent, tag))
1249- return ''.join(rc)
1250-
1251-def print_location(node):
1252- print ' ', 'location', '=', get_file_location(node)
1253-
1254-def get_attribs(node):
1255+def _print_attribs(node, attribs):
1256+ for attrib in attribs:
1257+ print ' ', attrib, '=', node.attributes[attrib].value
1258+
1259+def _concat_text_from_tags(parent, tagnames):
1260+ substrings = []
1261+
1262+ for tag in tagnames:
1263+ substrings.append(_get_text_for_element(parent, tag))
1264+
1265+ return ''.join(substrings)
1266+
1267+def _print_location(node):
1268+ print ' ', 'location', '=', _get_file_location(node)
1269+
1270+def _get_attribs(node):
1271 kind = node.attributes['kind'].value
1272 static = node.attributes['static'].value
1273- prot = node.attributes['prot'].value
1274- return (kind, static, prot)
1275-
1276-# Special cases for publishing anyway:
1277-publish_special_cases = {}
1278-
1279-component_map = {}
1280-symbols = {'public' : set(), 'private' : set()}
1281-
1282-def report(publish, symbol):
1283+ prot = node.attributes['prot'].value
1284+ return kind, static, prot
1285+
1286+COMPONENT_MAP = {}
1287+SYMBOLS = {'public' : set(), 'private' : set()}
1288+
1289+def _report(publish, symbol):
1290 symbol = symbol.replace('~', '?')
1291
1292- if symbol in publish_special_cases: publish = True
1293-
1294- if publish: symbols['public'].add(symbol)
1295- else: symbols['private'].add(symbol)
1296-
1297- if not debug: return
1298- if publish: print ' PUBLISH: {}'.format(symbol)
1299- else : print 'NOPUBLISH: {}'.format(symbol)
1300-
1301-old_stanzas = '''MIRAL_0.1 {
1302+ if publish:
1303+ SYMBOLS['public'].add(symbol)
1304+ else:
1305+ SYMBOLS['private'].add(symbol)
1306+
1307+ if not DEBUG:
1308+ return
1309+
1310+ if publish:
1311+ print ' PUBLISH: {}'.format(symbol)
1312+ else:
1313+ print 'NOPUBLISH: {}'.format(symbol)
1314+
1315+OLD_STANZAS = '''MIRAL_0.1 {
1316 global:
1317 # We need to specify the overload of miral::WindowManagerTools::modify_window
1318 _ZN5miral18WindowManagerTools13modify_windowERNS_10WindowInfoERKNS_19WindowSpecificationE;
1319@@ -378,123 +386,161 @@
1320 global:
1321 # We need to specify the overload of miral::WindowManagerTools::modify_window
1322 _ZN5miral18WindowManagerTools13modify_windowERKNS_6WindowERKNS_19WindowSpecificationE;
1323+ extern "C++" {
1324+ miral::Keymap::?Keymap*;
1325+ miral::Keymap::Keymap*;
1326+ miral::Keymap::operator*;
1327+ miral::Keymap::set_keymap*;
1328+ miral::WindowSpecification::userdata*;
1329+ typeinfo?for?miral::Keymap;
1330+ vtable?for?miral::Keymap;
1331+ };
1332+} MIRAL_0.2;
1333+
1334+MIRAL_0.4 {
1335+global:
1336 extern "C++" {'''
1337
1338-end_new_stanza = ''' };
1339-} MIRAL_0.2;'''
1340+END_NEW_STANZA = ''' };
1341+} MIRAL_0.3;'''
1342
1343-def print_report():
1344- print old_stanzas
1345- for symbol in sorted(symbols['public']):
1346+def _print_report():
1347+ print OLD_STANZAS
1348+ for symbol in sorted(SYMBOLS['public']):
1349 formatted_symbol = ' {};'.format(symbol)
1350- if not formatted_symbol in old_stanzas:
1351+ if formatted_symbol not in OLD_STANZAS:
1352 print formatted_symbol
1353- print end_new_stanza
1354+ print END_NEW_STANZA
1355
1356-def print_debug_info(node, attributes):
1357- if not debug: return
1358+def _print_debug_info(node, attributes):
1359+ if not DEBUG:
1360+ return
1361 print
1362- print_attribs(node, attributes)
1363- print_location(node)
1364-
1365-def find_physical_component(location_file):
1366- path_elements = location_file.split('/')
1367- found = False
1368- for element in path_elements:
1369- if found: return element
1370- found = element in ['include', 'src']
1371- if debug: print 'no component in:', location_file
1372- return None
1373-
1374-def parse_member_def(context_name, node, is_class):
1375- (kind, static, prot) = get_attribs(node)
1376-
1377- if kind in ['enum', 'typedef']: return
1378- if has_element(node, ['templateparamlist']): return
1379- if kind in ['function'] and node.attributes['inline'].value == 'yes': return
1380-
1381- name = concat_text_from_tags(node, ['name'])
1382+ _print_attribs(node, attributes)
1383+ _print_location(node)
1384+
1385+def _parse_member_def(context_name, node, is_class):
1386+ kind = node.attributes['kind'].value
1387+
1388+ if (kind in ['enum', 'typedef']
1389+ or _has_element(node, ['templateparamlist'])
1390+ or kind in ['function'] and node.attributes['inline'].value == 'yes'):
1391+ return
1392+
1393+ name = _concat_text_from_tags(node, ['name'])
1394+
1395 if name in ['__attribute__']:
1396- if debug: print ' ignoring doxygen mis-parsing:', concat_text_from_tags(node, ['argsstring'])
1397+ if DEBUG:
1398+ print ' ignoring doxygen mis-parsing:', _concat_text_from_tags(node, ['argsstring'])
1399 return
1400
1401- if name.startswith('operator'): name = 'operator'
1402- if not context_name == None: symbol = context_name + '::' + name
1403- else: symbol = name
1404+ if name.startswith('operator'):
1405+ name = 'operator'
1406+
1407+ if not context_name is None:
1408+ symbol = context_name + '::' + name
1409+ else:
1410+ symbol = name
1411+
1412+ is_function = kind == 'function'
1413+
1414+ if is_function:
1415+ _print_debug_info(node, ['kind', 'prot', 'static', 'virt'])
1416+ else:
1417+ _print_debug_info(node, ['kind', 'prot', 'static'])
1418+
1419+ if DEBUG:
1420+ print ' is_class:', is_class
1421+
1422+ publish = _should_publish(is_class, is_function, node)
1423+
1424+ _report(publish, symbol + '*')
1425+
1426+ if is_function and node.attributes['virt'].value == 'virtual':
1427+ _report(publish, 'non-virtual?thunk?to?' + symbol + '*')
1428+
1429+
1430+def _should_publish(is_class, is_function, node):
1431+ (kind, static, prot) = _get_attribs(node)
1432
1433 publish = True
1434
1435- is_function = kind == 'function'
1436- if publish: publish = kind != 'define'
1437- if publish and is_class: publish = is_function or static == 'yes'
1438+ if publish:
1439+ publish = kind != 'define'
1440+
1441+ if publish and is_class:
1442+ publish = is_function or static == 'yes'
1443+
1444 if publish and prot == 'private':
1445- if is_function: publish = node.attributes['virt'].value == 'virtual'
1446- else: publish = False
1447-
1448- if publish and has_element(node, ['argsstring']):
1449- publish = not get_text_for_element(node, 'argsstring').endswith('=0')
1450-
1451- if is_function: print_debug_info(node, ['kind', 'prot', 'static', 'virt'])
1452- else: print_debug_info(node, ['kind', 'prot', 'static'])
1453- if debug: print ' is_class:', is_class
1454- report(publish, symbol + '*')
1455- if is_function and node.attributes['virt'].value == 'virtual': report(publish,
1456- 'non-virtual?thunk?to?' + symbol + '*')
1457-
1458-def parse_compound_defs(xmldoc):
1459- compounddefs = xmldoc.getElementsByTagName('compounddef')
1460+ if is_function:
1461+ publish = node.attributes['virt'].value == 'virtual'
1462+ else:
1463+ publish = False
1464+
1465+ if publish and _has_element(node, ['argsstring']):
1466+ publish = not _get_text_for_element(node, 'argsstring').endswith('=0')
1467+
1468+ return publish
1469+
1470+
1471+def _parse_compound_defs(xmldoc):
1472+ compounddefs = xmldoc.getElementsByTagName('compounddef')
1473 for node in compounddefs:
1474 kind = node.attributes['kind'].value
1475
1476- if kind in ['page', 'file', 'example', 'union']: continue
1477-
1478- if kind in ['group']:
1479- for member in node.getElementsByTagName('memberdef') :
1480- parse_member_def(None, member, False)
1481- continue
1482-
1483- if kind in ['namespace']:
1484- symbol = concat_text_from_tags(node, ['compoundname'])
1485- for member in node.getElementsByTagName('memberdef') :
1486- parse_member_def(symbol, member, False)
1487- continue
1488-
1489- file = get_file_location(node)
1490- if debug: print ' from file:', file
1491- if '/examples/' in file or '/test/' in file or '[generated]' in file or '[STL]' in file:
1492- continue
1493-
1494- if has_element(node, ['templateparamlist']): continue
1495-
1496- symbol = concat_text_from_tags(node, ['compoundname'])
1497-
1498+ if kind in ['page', 'file', 'example', 'union']:
1499+ continue
1500+
1501+ if kind in ['group']:
1502+ for member in node.getElementsByTagName('memberdef'):
1503+ _parse_member_def(None, member, False)
1504+ continue
1505+
1506+ if kind in ['namespace']:
1507+ symbol = _concat_text_from_tags(node, ['compoundname'])
1508+ for member in node.getElementsByTagName('memberdef'):
1509+ _parse_member_def(symbol, member, False)
1510+ continue
1511+
1512+ filename = _get_file_location(node)
1513+
1514+ if DEBUG:
1515+ print ' from file:', filename
1516+
1517+ if ('/examples/' in filename or '/test/' in filename or '[generated]' in filename
1518+ or '[STL]' in filename or _has_element(node, ['templateparamlist'])):
1519+ continue
1520+
1521+ symbol = _concat_text_from_tags(node, ['compoundname'])
1522+
1523 publish = True
1524
1525- if publish:
1526+ if publish:
1527 if kind in ['class', 'struct']:
1528- prot = node.attributes['prot'].value
1529+ prot = node.attributes['prot'].value
1530 publish = prot != 'private'
1531- print_debug_info(node, ['kind', 'prot'])
1532- report(publish, 'vtable?for?' + symbol)
1533- report(publish, 'typeinfo?for?' + symbol)
1534+ _print_debug_info(node, ['kind', 'prot'])
1535+ _report(publish, 'vtable?for?' + symbol)
1536+ _report(publish, 'typeinfo?for?' + symbol)
1537
1538- if publish:
1539- for member in node.getElementsByTagName('memberdef') :
1540- parse_member_def(symbol, member, kind in ['class', 'struct'])
1541+ if publish:
1542+ for member in node.getElementsByTagName('memberdef'):
1543+ _parse_member_def(symbol, member, kind in ['class', 'struct'])
1544
1545 if __name__ == "__main__":
1546 if len(argv) == 1 or '-h' in argv or '--help' in argv:
1547- print helptext
1548+ print HELPTEXT
1549 exit()
1550
1551 for arg in argv[1:]:
1552 try:
1553- if debug: print 'Processing:', arg
1554- xmldoc = minidom.parse(arg)
1555- parse_compound_defs(xmldoc)
1556+ if DEBUG:
1557+ print 'Processing:', arg
1558+ _parse_compound_defs(minidom.parse(arg))
1559 except Exception as error:
1560 print 'Error:', arg, error
1561
1562- if debug: print 'Processing complete'
1563+ if DEBUG:
1564+ print 'Processing complete'
1565
1566- print_report()
1567+ _print_report()
1568
1569=== modified file 'tasks_for_the_interested_reader.md'
1570--- tasks_for_the_interested_reader.md 2016-09-21 16:36:56 +0000
1571+++ tasks_for_the_interested_reader.md 2016-11-04 16:34:03 +0000
1572@@ -37,9 +37,6 @@
1573 - Titlebars. GTK+ apps provide their own titlebars, better integration is
1574 needed.
1575
1576- - Keyboard layouts. It should be possible to configure and use non-US keyboard
1577- layouts.
1578-
1579 - Better integration of startup animation. A short animation is played on
1580 startup. Ideally this should remain visible until a client is launched,
1581 fade out over the top of the client and resume when the last client exits.
1582@@ -72,9 +69,6 @@
1583 - ability to track connected input devices
1584 - ability to control cursor visibility
1585
1586- - Cursor images. lp:qtmir stubs the cursor images and paints the cursor in its
1587- compositor. Need to consider what ought to be supported here.
1588-
1589 - Cut&Paste/Drag&Drop toolkits expect this functionality, but it isn't
1590 provided by Mir. We ought to find a way to provide this.
1591

Subscribers

People subscribed via source and target branches