mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 21:17:45 +00:00
Base+WindowsServer+keymap: Store multiple keymaps in a config
This commit is contained in:
parent
5a31697bcf
commit
c7bd47c87c
12 changed files with 405 additions and 100 deletions
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/JsonObject.h>
|
||||
#include <LibCore/ConfigFile.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <WindowServer/KeymapSwitcher.h>
|
||||
#include <spawn.h>
|
||||
|
@ -14,6 +15,15 @@ namespace WindowServer {
|
|||
|
||||
KeymapSwitcher::KeymapSwitcher()
|
||||
{
|
||||
m_file_watcher = MUST(Core::FileWatcher::create());
|
||||
|
||||
m_file_watcher->on_change = [this](auto&) {
|
||||
refresh();
|
||||
};
|
||||
|
||||
MUST(m_file_watcher->add_watch(m_keyboard_config, Core::FileWatcherEvent::Type::ContentModified));
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
KeymapSwitcher::~KeymapSwitcher()
|
||||
|
@ -24,15 +34,34 @@ void KeymapSwitcher::refresh()
|
|||
{
|
||||
m_keymaps.clear();
|
||||
|
||||
//TODO: load keymaps from file
|
||||
m_keymaps.append("en-us");
|
||||
m_keymaps.append("ru");
|
||||
auto mapper_config(Core::ConfigFile::open(m_keyboard_config));
|
||||
auto keymaps = mapper_config->read_entry("Mapping", "Keymaps", "");
|
||||
|
||||
auto keymaps_vector = keymaps.split(',');
|
||||
|
||||
for (auto& keymap : keymaps_vector) {
|
||||
m_keymaps.append(keymap);
|
||||
}
|
||||
|
||||
if (m_keymaps.is_empty()) {
|
||||
dbgln("Empty list of keymaps - adding default (en-us)");
|
||||
m_keymaps.append("en-us");
|
||||
}
|
||||
|
||||
auto current_keymap = get_current_keymap();
|
||||
|
||||
// Refresh might indicate that some external program has changed the keymap,
|
||||
// so better notify our clients that we may have a new keymap
|
||||
if (on_keymap_change)
|
||||
on_keymap_change(current_keymap);
|
||||
|
||||
if (m_keymaps.find(current_keymap).is_end()) {
|
||||
setkeymap(m_keymaps.first());
|
||||
}
|
||||
}
|
||||
|
||||
void KeymapSwitcher::next_keymap()
|
||||
{
|
||||
refresh();
|
||||
|
||||
if (m_keymaps.is_empty()) {
|
||||
dbgln("No keymaps loaded - leaving system keymap unchanged");
|
||||
return; // TODO: figure out what to do when there is no keymap configured
|
||||
|
@ -77,7 +106,7 @@ String KeymapSwitcher::get_current_keymap() const
|
|||
void KeymapSwitcher::setkeymap(const AK::String& keymap)
|
||||
{
|
||||
pid_t child_pid;
|
||||
const char* argv[] = { "/bin/keymap", keymap.characters(), nullptr };
|
||||
const char* argv[] = { "/bin/keymap", "-m", keymap.characters(), nullptr };
|
||||
if ((errno = posix_spawn(&child_pid, "/bin/keymap", nullptr, nullptr, const_cast<char**>(argv), environ))) {
|
||||
perror("posix_spawn");
|
||||
dbgln("Failed to call /bin/keymap, error: {} ({})", errno, strerror(errno));
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <LibCore/FileWatcher.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <LibKeyboard/CharacterMap.h>
|
||||
#include <WindowServer/WMClientConnection.h>
|
||||
|
@ -20,8 +21,6 @@ class KeymapSwitcher final : public Core::Object {
|
|||
public:
|
||||
virtual ~KeymapSwitcher() override;
|
||||
|
||||
void refresh();
|
||||
|
||||
void next_keymap();
|
||||
|
||||
Function<void(String const& keymap)> on_keymap_change;
|
||||
|
@ -29,11 +28,17 @@ public:
|
|||
String get_current_keymap() const;
|
||||
|
||||
private:
|
||||
void refresh();
|
||||
|
||||
KeymapSwitcher();
|
||||
|
||||
Vector<AK::String> m_keymaps;
|
||||
|
||||
void setkeymap(AK::String const&);
|
||||
|
||||
RefPtr<Core::FileWatcher> m_file_watcher;
|
||||
|
||||
const char* m_keyboard_config = "/etc/Keyboard.ini";
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
|
|||
TRY(Core::System::unveil("/res", "r"));
|
||||
TRY(Core::System::unveil("/tmp", "cw"));
|
||||
TRY(Core::System::unveil("/etc/WindowServer.ini", "rwc"));
|
||||
TRY(Core::System::unveil("/etc/Keyboard.ini", "r"));
|
||||
TRY(Core::System::unveil("/dev", "rw"));
|
||||
TRY(Core::System::unveil("/bin/keymap", "x"));
|
||||
TRY(Core::System::unveil("/proc/keymap", "r"));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue