Merge lp:~alan-griffiths/miral/Keymap into lp:miral

Proposed by Alan Griffiths
Status: Merged
Approved by: Gerry Boland
Approved revision: 411
Merged at revision: 405
Proposed branch: lp:~alan-griffiths/miral/Keymap
Merge into: lp:miral
Diff against target: 315 lines (+251/-0)
6 files modified
debian/libmiral1.symbols (+11/-0)
include/miral/keymap.h (+56/-0)
miral-shell/shell_main.cpp (+4/-0)
miral/CMakeLists.txt (+1/-0)
miral/keymap.cpp (+173/-0)
miral/symbols.map (+6/-0)
To merge this branch: bzr merge lp:~alan-griffiths/miral/Keymap
Reviewer Review Type Date Requested Status
Gerry Boland (community) Approve
Brandon Schaefer (community) Approve
Andreas Pokorny (community) Approve
Review via email: mp+308121@code.launchpad.net

Commit message

miral::Keymap - support for keyboard maps (either programatically Keymap::set_keymap(), or via config --keymap)

To post a comment you must log in.
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

yes this looks reasonable

review: Approve
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

lgtm

review: Approve
lp:~alan-griffiths/miral/Keymap updated
411. By Alan Griffiths

Mutex to permit multi-threaded operation

Revision history for this message
Gerry Boland (gerboland) wrote :

looks ok to me

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/libmiral1.symbols'
--- debian/libmiral1.symbols 2016-10-05 16:54:07 +0000
+++ debian/libmiral1.symbols 2016-10-12 10:30:39 +0000
@@ -264,3 +264,14 @@
264 (c++)"vtable for miral::ActiveOutputsListener@MIRAL_0.1" 0.1.0264 (c++)"vtable for miral::ActiveOutputsListener@MIRAL_0.1" 0.1.0
265 (c++)"vtable for miral::CanonicalWindowManagerPolicy@MIRAL_0.1" 0.1.0265 (c++)"vtable for miral::CanonicalWindowManagerPolicy@MIRAL_0.1" 0.1.0
266 (c++)"vtable for miral::WindowManagementPolicy@MIRAL_0.1" 0.1.0266 (c++)"vtable for miral::WindowManagementPolicy@MIRAL_0.1" 0.1.0
267 (c++)"miral::Keymap::set_keymap(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.3" 0.3.0
268 (c++)"miral::Keymap::Keymap(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.3" 0.3.0
269 (c++)"miral::Keymap::Keymap(miral::Keymap const&)@MIRAL_0.3" 0.3.0
270 (c++)"miral::Keymap::Keymap()@MIRAL_0.3" 0.3.0
271 (c++)"miral::Keymap::Keymap(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@MIRAL_0.3" 0.3.0
272 (c++)"miral::Keymap::Keymap(miral::Keymap const&)@MIRAL_0.3" 0.3.0
273 (c++)"miral::Keymap::Keymap()@MIRAL_0.3" 0.3.0
274 (c++)"miral::Keymap::~Keymap()@MIRAL_0.3" 0.3.0
275 (c++)"miral::Keymap::~Keymap()@MIRAL_0.3" 0.3.0
276 (c++)"miral::Keymap::operator=(miral::Keymap const&)@MIRAL_0.3" 0.3.0
277 (c++)"miral::Keymap::operator()(mir::Server&) const@MIRAL_0.3" 0.3.0
267278
=== added file 'include/miral/keymap.h'
--- include/miral/keymap.h 1970-01-01 00:00:00 +0000
+++ include/miral/keymap.h 2016-10-12 10:30:39 +0000
@@ -0,0 +1,56 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#ifndef MIRAL_KEYMAP_H
20#define MIRAL_KEYMAP_H
21
22#include <memory>
23#include <string>
24
25namespace mir { class Server; }
26
27namespace miral
28{
29/// Load a keymap
30class Keymap
31{
32public:
33
34 /// Apply keymap from the config.
35 Keymap();
36
37 /// Specify a keymap.
38 /// Format is <language>[+<variant>]
39 /// e.g. "uk" or "us+dvorak"
40 explicit Keymap(std::string const& keymap);
41 ~Keymap();
42 Keymap(Keymap const& that);
43 auto operator=(Keymap const& rhs) -> Keymap&;
44
45 void operator()(mir::Server& server) const;
46
47 /// Specify a new keymap.
48 void set_keymap(std::string const& keymap);
49
50private:
51 struct Self;
52 std::shared_ptr<Self> self;
53};
54}
55
56#endif //MIRAL_KEYMAP_H
057
=== modified file 'miral-shell/shell_main.cpp'
--- miral-shell/shell_main.cpp 2016-09-28 10:38:36 +0000
+++ miral-shell/shell_main.cpp 2016-10-12 10:30:39 +0000
@@ -26,6 +26,7 @@
26#include <miral/append_event_filter.h>26#include <miral/append_event_filter.h>
27#include <miral/internal_client.h>27#include <miral/internal_client.h>
28#include <miral/cursor_theme.h>28#include <miral/cursor_theme.h>
29#include <miral/keymap.h>
2930
30#include <linux/input.h>31#include <linux/input.h>
3132
@@ -68,6 +69,8 @@
68 return true;69 return true;
69 };70 };
7071
72 Keymap config_keymap;
73
71 return runner.run_with(74 return runner.run_with(
72 {75 {
73 CursorTheme{"default"},76 CursorTheme{"default"},
@@ -75,6 +78,7 @@
75 display_configuration_options,78 display_configuration_options,
76 launcher,79 launcher,
77 outputs_monitor,80 outputs_monitor,
81 config_keymap,
78 AppendEventFilter{quit_on_ctrl_alt_bksp},82 AppendEventFilter{quit_on_ctrl_alt_bksp},
79 StartupInternalClient{"Intro", spinner}83 StartupInternalClient{"Intro", spinner}
80 });84 });
8185
=== modified file 'miral/CMakeLists.txt'
--- miral/CMakeLists.txt 2016-09-28 13:16:14 +0000
+++ miral/CMakeLists.txt 2016-10-12 10:30:39 +0000
@@ -32,6 +32,7 @@
32 application_info.cpp ${CMAKE_SOURCE_DIR}/include/miral/application_info.h32 application_info.cpp ${CMAKE_SOURCE_DIR}/include/miral/application_info.h
33 canonical_window_manager.cpp ${CMAKE_SOURCE_DIR}/include/miral/canonical_window_manager.h33 canonical_window_manager.cpp ${CMAKE_SOURCE_DIR}/include/miral/canonical_window_manager.h
34 cursor_theme.cpp ${CMAKE_SOURCE_DIR}/include/miral/cursor_theme.h34 cursor_theme.cpp ${CMAKE_SOURCE_DIR}/include/miral/cursor_theme.h
35 keymap.cpp ${CMAKE_SOURCE_DIR}/include/miral/keymap.h
35 runner.cpp ${CMAKE_SOURCE_DIR}/include/miral/runner.h36 runner.cpp ${CMAKE_SOURCE_DIR}/include/miral/runner.h
36 display_configuration_option.cpp ${CMAKE_SOURCE_DIR}/include/miral/display_configuration_option.h37 display_configuration_option.cpp ${CMAKE_SOURCE_DIR}/include/miral/display_configuration_option.h
37 output.cpp ${CMAKE_SOURCE_DIR}/include/miral/output.h38 output.cpp ${CMAKE_SOURCE_DIR}/include/miral/output.h
3839
=== added file 'miral/keymap.cpp'
--- miral/keymap.cpp 1970-01-01 00:00:00 +0000
+++ miral/keymap.cpp 2016-10-12 10:30:39 +0000
@@ -0,0 +1,173 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "miral/keymap.h"
20
21#include <mir/input/input_device_observer.h>
22#include <mir/input/input_device_hub.h>
23#include <mir/input/device.h>
24#include <mir/options/option.h>
25#include <mir/server.h>
26#include <mir/version.h>
27
28#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 1)
29#include <mir/input/keymap.h>
30#include <mir/input/keyboard_configuration.h>
31#endif
32
33#define MIR_LOG_COMPONENT "miral::Keymap"
34#include <mir/log.h>
35
36#include <algorithm>
37#include <mutex>
38#include <vector>
39
40namespace
41{
42char const* const keymap_option = "keymap";
43char const* const keymap_default = "us";
44}
45
46struct miral::Keymap::Self : mir::input::InputDeviceObserver
47{
48 Self(std::string const& keymap) : layout{}, variant{}
49 {
50 set_keymap(keymap);
51 }
52
53 void set_keymap(std::string const& keymap)
54 {
55 std::lock_guard<decltype(mutex)> lock{mutex};
56
57 auto const i = keymap.find('+');
58
59 layout = keymap.substr(0, i);
60
61 if (i != std::string::npos)
62 variant = keymap.substr(i + 1);
63
64 for (auto const& keyboard : keyboards)
65 apply_keymap(keyboard);
66 }
67
68 void device_added(std::shared_ptr<mir::input::Device> const& device) override
69 {
70 std::lock_guard<decltype(mutex)> lock{mutex};
71
72 if (mir::contains(device->capabilities(), mir::input::DeviceCapability::keyboard))
73 add_keyboard(device);
74 }
75
76 void device_changed(std::shared_ptr<mir::input::Device> const& device) override
77 {
78 std::lock_guard<decltype(mutex)> lock{mutex};
79
80 auto const keyboard = std::find(begin(keyboards), end(keyboards), device);
81
82 if (mir::contains(device->capabilities(), mir::input::DeviceCapability::keyboard))
83 {
84 if (keyboard == end(keyboards))
85 add_keyboard(device);
86 }
87 else
88 {
89 if (keyboard != end(keyboards))
90 keyboards.erase(keyboard);
91 }
92 }
93
94 void add_keyboard(std::shared_ptr<mir::input::Device> const& keyboard)
95 {
96 keyboards.push_back(keyboard);
97 apply_keymap(keyboard);
98 }
99
100#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 1)
101 void apply_keymap(std::shared_ptr<mir::input::Device> const& keyboard)
102 {
103 auto const keyboard_config = keyboard->keyboard_configuration();
104 mir::input::Keymap keymap;
105
106 if (keyboard_config.is_set())
107 {
108 keymap = keyboard_config.value().device_keymap;
109 }
110
111 keymap.layout = layout;
112 keymap.variant = variant;
113 keyboard->apply_keyboard_configuration(std::move(keymap));
114 }
115#else
116 void apply_keymap(std::shared_ptr<mir::input::Device> const&)
117 {
118 mir::log_warning("Cannot apply keymap - not supported for Mir versions prior to 0.24.1");
119 }
120#endif
121
122 void device_removed(std::shared_ptr<mir::input::Device> const& device) override
123 {
124 std::lock_guard<decltype(mutex)> lock{mutex};
125
126 if (mir::contains(device->capabilities(), mir::input::DeviceCapability::keyboard))
127 keyboards.erase(std::find(begin(keyboards), end(keyboards), device));
128 }
129
130 void changes_complete() override
131 {
132 }
133
134 std::mutex mutable mutex;
135 std::string layout;
136 std::string variant;
137 std::vector<std::shared_ptr<mir::input::Device>> keyboards;
138};
139
140miral::Keymap::Keymap() :
141 self{std::make_shared<Self>(std::string{})}
142{
143}
144
145miral::Keymap::Keymap(std::string const& keymap) :
146 self{std::make_shared<Self>(keymap)}
147{
148}
149
150miral::Keymap::~Keymap() = default;
151
152miral::Keymap::Keymap(Keymap const&) = default;
153
154auto miral::Keymap::operator=(Keymap const& rhs) -> Keymap& = default;
155
156void miral::Keymap::operator()(mir::Server& server) const
157{
158 if (self->layout.empty())
159 server.add_configuration_option(keymap_option, "keymap <layout>[+<variant>], e,g, \"gb\" or \"cz+qwerty\"", keymap_default);
160
161 server.add_init_callback([this, &server]
162 {
163 if (self->layout.empty())
164 self->set_keymap(server.get_options()->get<std::string>(keymap_option));
165
166 server.the_input_device_hub()->add_observer(self);
167 });
168}
169
170void miral::Keymap::set_keymap(std::string const& keymap)
171{
172 self->set_keymap(keymap);
173}
0174
=== modified file 'miral/symbols.map'
--- miral/symbols.map 2016-10-05 16:54:07 +0000
+++ miral/symbols.map 2016-10-12 10:30:39 +0000
@@ -304,6 +304,12 @@
304 # We need to specify the overload of miral::WindowManagerTools::modify_window304 # We need to specify the overload of miral::WindowManagerTools::modify_window
305 _ZN5miral18WindowManagerTools13modify_windowERKNS_6WindowERKNS_19WindowSpecificationE;305 _ZN5miral18WindowManagerTools13modify_windowERKNS_6WindowERKNS_19WindowSpecificationE;
306 extern "C++" {306 extern "C++" {
307 miral::Keymap::?Keymap*;
308 miral::Keymap::Keymap*;
309 miral::Keymap::operator*;
310 miral::Keymap::set_keymap*;
307 miral::WindowSpecification::userdata*;311 miral::WindowSpecification::userdata*;
312 typeinfo?for?miral::Keymap;
313 vtable?for?miral::Keymap;
308 };314 };
309} MIRAL_0.2;315} MIRAL_0.2;

Subscribers

People subscribed via source and target branches