mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
Keymap+WindowServer: Add context menu to keymap applet
Adding a context menu which lists configured keymaps and allows setting the active keymap
This commit is contained in:
parent
db11cfa2c5
commit
9906f41e01
Notes:
sideshowbarker
2024-07-17 08:41:57 +09:00
Author: https://github.com/TSultanov Commit: https://github.com/SerenityOS/serenity/commit/9906f41e01 Pull-request: https://github.com/SerenityOS/serenity/pull/14463
11 changed files with 126 additions and 27 deletions
|
@ -6,6 +6,7 @@ serenity_component(
|
|||
|
||||
set(SOURCES
|
||||
KeymapStatusWindow.cpp
|
||||
KeymapStatusWidget.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
|
|
73
Userland/Applets/Keymap/KeymapStatusWidget.cpp
Normal file
73
Userland/Applets/Keymap/KeymapStatusWidget.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2022, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "KeymapStatusWidget.h"
|
||||
#include "LibGUI/ActionGroup.h"
|
||||
#include <LibGUI/Action.h>
|
||||
#include <LibGUI/ConnectionToWindowManagerServer.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGUI/Process.h>
|
||||
#include <LibGfx/Point.h>
|
||||
#include <LibKeyboard/CharacterMap.h>
|
||||
|
||||
void KeymapStatusWidget::mousedown_event(GUI::MouseEvent& event)
|
||||
{
|
||||
Gfx::IntPoint point(event.x(), event.y());
|
||||
MUST(refresh_menu());
|
||||
m_context_menu->popup(point.translated(this->screen_relative_rect().location()));
|
||||
}
|
||||
|
||||
ErrorOr<void> KeymapStatusWidget::refresh_menu()
|
||||
{
|
||||
m_keymaps_group.for_each_action([&](auto& action) {
|
||||
m_keymaps_group.remove_action(action);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
|
||||
m_context_menu = GUI::Menu::construct();
|
||||
|
||||
auto mapper_config = TRY(Core::ConfigFile::open("/etc/Keyboard.ini"));
|
||||
auto keymaps_string = mapper_config->read_entry("Mapping", "Keymaps", "");
|
||||
auto keymaps = keymaps_string.split(',');
|
||||
|
||||
for (auto& keymap : keymaps) {
|
||||
auto action = GUI::Action::create_checkable(keymap, [=](auto&) {
|
||||
GUI::ConnectionToWindowManagerServer::the().async_set_keymap(keymap);
|
||||
});
|
||||
|
||||
action->set_checked(keymap == m_current_keymap);
|
||||
|
||||
m_keymaps_group.add_action(action);
|
||||
m_context_menu->add_action(action);
|
||||
}
|
||||
|
||||
m_keymaps_group.set_exclusive(true);
|
||||
|
||||
m_context_menu->add_separator();
|
||||
|
||||
auto settings_icon = TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/settings.png"sv));
|
||||
|
||||
m_context_menu->add_action(GUI::Action::create("&Settings",
|
||||
settings_icon,
|
||||
[&](auto&) {
|
||||
GUI::Process::spawn_or_show_error(window(), "/bin/KeyboardSettings"sv);
|
||||
}));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void KeymapStatusWidget::set_current_keymap(String const& keymap, ClearBackground clear_background)
|
||||
{
|
||||
if (clear_background == ClearBackground::Yes) {
|
||||
GUI::Painter painter(*this);
|
||||
painter.clear_rect(rect(), Color::Transparent);
|
||||
}
|
||||
|
||||
m_current_keymap = keymap;
|
||||
|
||||
set_tooltip(keymap);
|
||||
set_text(keymap.substring(0, 2));
|
||||
}
|
34
Userland/Applets/Keymap/KeymapStatusWidget.h
Normal file
34
Userland/Applets/Keymap/KeymapStatusWidget.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2022, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibCore/FileWatcher.h>
|
||||
#include <LibGUI/ActionGroup.h>
|
||||
#include <LibGUI/Label.h>
|
||||
#include <LibGUI/Menu.h>
|
||||
#include <LibGUI/Window.h>
|
||||
|
||||
enum class ClearBackground {
|
||||
No,
|
||||
Yes
|
||||
};
|
||||
|
||||
class KeymapStatusWidget : public GUI::Label {
|
||||
C_OBJECT(KeymapStatusWidget);
|
||||
|
||||
virtual void mousedown_event(GUI::MouseEvent& event) override;
|
||||
|
||||
void set_current_keymap(String const& keymap, ClearBackground clear_background = ClearBackground::Yes);
|
||||
|
||||
private:
|
||||
RefPtr<GUI::Menu> m_context_menu;
|
||||
String m_current_keymap;
|
||||
|
||||
ErrorOr<void> refresh_menu();
|
||||
|
||||
GUI::ActionGroup m_keymaps_group;
|
||||
};
|
|
@ -6,19 +6,10 @@
|
|||
*/
|
||||
|
||||
#include "KeymapStatusWindow.h"
|
||||
#include <LibGUI/ConnectionToWindowManagerServer.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGUI/Process.h>
|
||||
#include <LibKeyboard/CharacterMap.h>
|
||||
|
||||
void KeymapStatusWidget::mousedown_event(GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() != GUI::MouseButton::Primary)
|
||||
return;
|
||||
|
||||
GUI::Process::spawn_or_show_error(window(), "/bin/KeyboardSettings"sv);
|
||||
}
|
||||
|
||||
KeymapStatusWindow::KeymapStatusWindow()
|
||||
{
|
||||
set_window_type(GUI::WindowType::Applet);
|
||||
|
@ -27,8 +18,7 @@ KeymapStatusWindow::KeymapStatusWindow()
|
|||
|
||||
auto current_keymap = MUST(Keyboard::CharacterMap::fetch_system_map());
|
||||
auto current_keymap_name = current_keymap.character_map_name();
|
||||
m_status_widget->set_tooltip(current_keymap_name);
|
||||
m_status_widget->set_text(current_keymap_name.substring(0, 2));
|
||||
m_status_widget->set_current_keymap(current_keymap_name, ClearBackground::No);
|
||||
}
|
||||
|
||||
void KeymapStatusWindow::wm_event(GUI::WMEvent& event)
|
||||
|
@ -42,9 +32,5 @@ void KeymapStatusWindow::wm_event(GUI::WMEvent& event)
|
|||
|
||||
void KeymapStatusWindow::set_keymap_text(String const& keymap)
|
||||
{
|
||||
GUI::Painter painter(*m_status_widget);
|
||||
painter.clear_rect(m_status_widget->rect(), Color::from_argb(0));
|
||||
|
||||
m_status_widget->set_tooltip(keymap);
|
||||
m_status_widget->set_text(keymap.substring(0, 2));
|
||||
m_status_widget->set_current_keymap(keymap);
|
||||
}
|
||||
|
|
|
@ -7,14 +7,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "KeymapStatusWidget.h"
|
||||
#include <LibGUI/Label.h>
|
||||
#include <LibGUI/Window.h>
|
||||
|
||||
class KeymapStatusWidget : public GUI::Label {
|
||||
C_OBJECT(KeymapStatusWidget);
|
||||
|
||||
virtual void mousedown_event(GUI::MouseEvent& event) override;
|
||||
};
|
||||
class KeymapStatusWindow final : public GUI::Window {
|
||||
C_OBJECT(KeymapStatusWindow)
|
||||
public:
|
||||
|
|
|
@ -53,7 +53,7 @@ void KeymapSwitcher::refresh()
|
|||
on_keymap_change(current_keymap);
|
||||
|
||||
if (m_keymaps.find(current_keymap).is_end()) {
|
||||
setkeymap(m_keymaps.first());
|
||||
set_keymap(m_keymaps.first());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ void KeymapSwitcher::next_keymap()
|
|||
if (it.is_end()) {
|
||||
auto first_keymap = m_keymaps.first();
|
||||
dbgln("Cannot find current keymap in the keymap list - setting first available ({})", first_keymap);
|
||||
setkeymap(first_keymap);
|
||||
set_keymap(first_keymap);
|
||||
} else {
|
||||
it++;
|
||||
|
||||
|
@ -84,7 +84,7 @@ void KeymapSwitcher::next_keymap()
|
|||
}
|
||||
|
||||
dbgln("Setting system keymap to: {}", *it);
|
||||
setkeymap(*it);
|
||||
set_keymap(*it);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ String KeymapSwitcher::get_current_keymap() const
|
|||
return keymap_object.get("keymap"sv).to_string();
|
||||
}
|
||||
|
||||
void KeymapSwitcher::setkeymap(const AK::String& keymap)
|
||||
void KeymapSwitcher::set_keymap(const AK::String& keymap)
|
||||
{
|
||||
if (Core::Process::spawn("/bin/keymap"sv, Array { "-m", keymap.characters() }).is_error())
|
||||
dbgln("Failed to call /bin/keymap, error: {} ({})", errno, strerror(errno));
|
||||
|
|
|
@ -27,6 +27,8 @@ public:
|
|||
|
||||
String get_current_keymap() const;
|
||||
|
||||
void set_keymap(AK::String const&);
|
||||
|
||||
private:
|
||||
void refresh();
|
||||
|
||||
|
@ -34,8 +36,6 @@ private:
|
|||
|
||||
Vector<AK::String> m_keymaps;
|
||||
|
||||
void setkeymap(AK::String const&);
|
||||
|
||||
RefPtr<Core::FileWatcher> m_file_watcher;
|
||||
|
||||
char const* m_keyboard_config = "/etc/Keyboard.ini";
|
||||
|
|
|
@ -183,4 +183,9 @@ void WMConnectionFromClient::set_window_taskbar_rect(i32 client_id, i32 window_i
|
|||
window.set_taskbar_rect(rect);
|
||||
}
|
||||
|
||||
void WMConnectionFromClient::set_keymap(String const& keymap)
|
||||
{
|
||||
WindowManager::the().keymap_switcher()->set_keymap(keymap);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ public:
|
|||
virtual void set_event_mask(u32) override;
|
||||
virtual void set_manager_window(i32) override;
|
||||
virtual void set_workspace(u32, u32) override;
|
||||
virtual void set_keymap(String const&) override;
|
||||
|
||||
unsigned event_mask() const { return m_event_mask; }
|
||||
int window_id() const { return m_window_id; }
|
||||
|
|
|
@ -336,6 +336,8 @@ public:
|
|||
|
||||
bool is_cursor_highlight_enabled() const { return m_cursor_highlight_radius > 0 && m_cursor_highlight_enabled; }
|
||||
|
||||
RefPtr<KeymapSwitcher> keymap_switcher() { return m_keymap_switcher; }
|
||||
|
||||
private:
|
||||
explicit WindowManager(Gfx::PaletteImpl const&);
|
||||
|
||||
|
|
|
@ -13,4 +13,5 @@ endpoint WindowManagerServer
|
|||
set_window_taskbar_rect(i32 client_id, i32 window_id, Gfx::IntRect rect) =|
|
||||
set_applet_area_position(Gfx::IntPoint position) =|
|
||||
set_workspace(u32 row, u32 column) =|
|
||||
set_keymap([UTF8] String keymap) =|
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue