Serenity Operating System
1/*
2 * Copyright (c) 2022, the SerenityOS developers.
3 * Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include "KeymapStatusWidget.h"
9#include <LibGUI/Action.h>
10#include <LibGUI/ActionGroup.h>
11#include <LibGUI/ConnectionToWindowManagerServer.h>
12#include <LibGUI/Menu.h>
13#include <LibGUI/Painter.h>
14#include <LibGUI/Process.h>
15#include <LibGfx/Point.h>
16
17KeymapStatusWidget::KeymapStatusWidget() = default;
18KeymapStatusWidget::~KeymapStatusWidget() = default;
19
20void KeymapStatusWidget::mousedown_event(GUI::MouseEvent& event)
21{
22 Gfx::IntPoint point(event.x(), event.y());
23 MUST(refresh_menu());
24 m_context_menu->popup(point.translated(this->screen_relative_rect().location()));
25}
26
27ErrorOr<void> KeymapStatusWidget::refresh_menu()
28{
29 m_keymaps_group.for_each_action([&](auto& action) {
30 m_keymaps_group.remove_action(action);
31 return IterationDecision::Continue;
32 });
33
34 m_context_menu = GUI::Menu::construct();
35
36 auto mapper_config = TRY(Core::ConfigFile::open("/etc/Keyboard.ini"));
37 auto keymaps_string = mapper_config->read_entry("Mapping", "Keymaps", "");
38 auto keymaps = keymaps_string.split(',');
39
40 for (auto& keymap : keymaps) {
41 auto action = GUI::Action::create_checkable(keymap, [=](auto&) {
42 GUI::ConnectionToWindowManagerServer::the().async_set_keymap(keymap);
43 });
44
45 action->set_checked(keymap == m_current_keymap);
46
47 m_keymaps_group.add_action(action);
48 m_context_menu->add_action(action);
49 }
50
51 m_keymaps_group.set_exclusive(true);
52
53 m_context_menu->add_separator();
54
55 auto settings_icon = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/settings.png"sv));
56
57 m_context_menu->add_action(GUI::Action::create("Keyboard &Settings",
58 settings_icon,
59 [&](auto&) {
60 GUI::Process::spawn_or_show_error(window(), "/bin/KeyboardSettings"sv);
61 }));
62
63 return {};
64}
65
66void KeymapStatusWidget::set_current_keymap(DeprecatedString const& keymap)
67{
68 m_current_keymap = keymap;
69 set_tooltip(keymap);
70 update();
71}
72
73void KeymapStatusWidget::paint_event(GUI::PaintEvent& event)
74{
75 GUI::Painter painter(*this);
76 painter.add_clip_rect(event.rect());
77 painter.clear_rect(event.rect(), Gfx::Color::Transparent);
78 painter.draw_text(rect(), m_current_keymap.substring_view(0, 2), Gfx::TextAlignment::Center);
79}