mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 17:10:23 +00:00
WindowServer+Keymap+LibGUI: Add widget to display current keymap
This commit is contained in:
parent
68a01f0e27
commit
b9c558f6c6
Notes:
sideshowbarker
2024-07-19 01:59:31 +09:00
Author: https://github.com/TSultanov Commit: https://github.com/SerenityOS/serenity/commit/b9c558f6c6e Pull-request: https://github.com/SerenityOS/serenity/pull/12010
14 changed files with 160 additions and 17 deletions
|
@ -32,7 +32,7 @@ DoubleClickSpeed=250
|
|||
Mode=stretch
|
||||
|
||||
[Applet]
|
||||
Order=WorkspacePicker,CPUGraph,MemoryGraph,Network,ClipboardHistory,Audio
|
||||
Order=WorkspacePicker,CPUGraph,MemoryGraph,Network,ClipboardHistory,Audio,Keymap
|
||||
|
||||
[Workspaces]
|
||||
Rows=2
|
||||
|
|
|
@ -3,3 +3,4 @@ add_subdirectory(ClipboardHistory)
|
|||
add_subdirectory(Network)
|
||||
add_subdirectory(ResourceGraph)
|
||||
add_subdirectory(WorkspacePicker)
|
||||
add_subdirectory(Keymap)
|
||||
|
|
13
Userland/Applets/Keymap/CMakeLists.txt
Normal file
13
Userland/Applets/Keymap/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
serenity_component(
|
||||
Keymap.Applet
|
||||
REQUIRED
|
||||
TARGETS Keymap.Applet
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
KeymapStatusWindow.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
serenity_bin(Keymap.Applet)
|
||||
target_link_libraries(Keymap.Applet LibGUI LibCore LibGfx LibMain LibKeyboard)
|
44
Userland/Applets/Keymap/KeymapStatusWindow.cpp
Normal file
44
Userland/Applets/Keymap/KeymapStatusWindow.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Timur Sultanov <SultanovTS@yandex.ru>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "KeymapStatusWindow.h"
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGUI/WindowManagerServerConnection.h>
|
||||
#include <LibKeyboard/CharacterMap.h>
|
||||
|
||||
KeymapStatusWindow::KeymapStatusWindow()
|
||||
{
|
||||
set_window_type(GUI::WindowType::Applet);
|
||||
set_has_alpha_channel(true);
|
||||
m_label = &set_main_widget<GUI::Label>();
|
||||
|
||||
auto current_keymap = MUST(Keyboard::CharacterMap::fetch_system_map());
|
||||
auto current_keymap_name = current_keymap.character_map_name();
|
||||
m_label->set_tooltip(current_keymap_name);
|
||||
m_label->set_text(current_keymap_name.substring(0, 2));
|
||||
}
|
||||
|
||||
KeymapStatusWindow::~KeymapStatusWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void KeymapStatusWindow::wm_event(GUI::WMEvent& event)
|
||||
{
|
||||
if (event.type() == GUI::WMEvent::WM_KeymapChanged) {
|
||||
auto& keymap_event = static_cast<GUI::WMKeymapChangedEvent&>(event);
|
||||
auto keymap = keymap_event.keymap();
|
||||
set_keymap_text(keymap);
|
||||
}
|
||||
}
|
||||
|
||||
void KeymapStatusWindow::set_keymap_text(const String& keymap)
|
||||
{
|
||||
GUI::Painter painter(*m_label);
|
||||
painter.clear_rect(m_label->rect(), Color::from_rgba(0));
|
||||
|
||||
m_label->set_tooltip(keymap);
|
||||
m_label->set_text(keymap.substring(0, 2));
|
||||
}
|
27
Userland/Applets/Keymap/KeymapStatusWindow.h
Normal file
27
Userland/Applets/Keymap/KeymapStatusWindow.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Timur Sultanov <SultanovTS@yandex.ru>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGUI/Label.h>
|
||||
#include <LibGUI/Window.h>
|
||||
|
||||
class KeymapStatusWidget;
|
||||
|
||||
class KeymapStatusWindow final : public GUI::Window {
|
||||
C_OBJECT(KeymapStatusWindow)
|
||||
public:
|
||||
virtual ~KeymapStatusWindow() override;
|
||||
|
||||
private:
|
||||
void wm_event(GUI::WMEvent&) override;
|
||||
|
||||
KeymapStatusWindow();
|
||||
|
||||
RefPtr<GUI::Label> m_label;
|
||||
|
||||
void set_keymap_text(String const& keymap);
|
||||
};
|
30
Userland/Applets/Keymap/main.cpp
Normal file
30
Userland/Applets/Keymap/main.cpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Timur Sultanov <SultanovTS@yandex.ru>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "KeymapStatusWindow.h"
|
||||
#include <LibCore/System.h>
|
||||
#include <LibGUI/Application.h>
|
||||
#include <LibGUI/WindowManagerServerConnection.h>
|
||||
#include <LibMain/Main.h>
|
||||
#include <WindowServer/Window.h>
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
TRY(Core::System::pledge("stdio recvfd sendfd rpath unix getkeymap"));
|
||||
|
||||
auto app = TRY(GUI::Application::try_create(arguments));
|
||||
|
||||
auto window = TRY(KeymapStatusWindow::try_create());
|
||||
window->set_has_alpha_channel(true);
|
||||
window->set_title("Keymap");
|
||||
window->resize(16, 16);
|
||||
window->show();
|
||||
window->make_window_manager(WindowServer::WMEventMask::KeymapChanged);
|
||||
|
||||
TRY(Core::System::pledge("stdio recvfd sendfd rpath getkeymap"));
|
||||
|
||||
return app->exec();
|
||||
}
|
|
@ -67,6 +67,7 @@ public:
|
|||
WM_SuperKeyPressed,
|
||||
WM_SuperSpaceKeyPressed,
|
||||
WM_WorkspaceChanged,
|
||||
WM_KeymapChanged,
|
||||
__End_WM_Events,
|
||||
};
|
||||
|
||||
|
@ -228,6 +229,20 @@ private:
|
|||
const unsigned m_current_column;
|
||||
};
|
||||
|
||||
class WMKeymapChangedEvent : public WMEvent {
|
||||
public:
|
||||
explicit WMKeymapChangedEvent(int client_id, String const& keymap)
|
||||
: WMEvent(Event::Type::WM_KeymapChanged, client_id, 0)
|
||||
, m_keymap(keymap)
|
||||
{
|
||||
}
|
||||
|
||||
String const& keymap() const { return m_keymap; }
|
||||
|
||||
private:
|
||||
const String m_keymap;
|
||||
};
|
||||
|
||||
class MultiPaintEvent final : public Event {
|
||||
public:
|
||||
explicit MultiPaintEvent(Vector<Gfx::IntRect, 32> rects, Gfx::IntSize const& window_size)
|
||||
|
|
|
@ -70,4 +70,10 @@ void WindowManagerServerConnection::workspace_changed(i32 wm_id, u32 row, u32 co
|
|||
Core::EventLoop::current().post_event(*window, make<WMWorkspaceChangedEvent>(wm_id, row, column));
|
||||
}
|
||||
|
||||
void WindowManagerServerConnection::keymap_changed(i32 wm_id, String const& keymap)
|
||||
{
|
||||
if (auto* window = Window::from_window_id(wm_id))
|
||||
Core::EventLoop::current().post_event(*window, make<WMKeymapChangedEvent>(wm_id, keymap));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ private:
|
|||
virtual void super_key_pressed(i32) override;
|
||||
virtual void super_space_key_pressed(i32) override;
|
||||
virtual void workspace_changed(i32, u32, u32) override;
|
||||
virtual void keymap_changed(i32, String const&) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -12,17 +12,8 @@
|
|||
|
||||
namespace WindowServer {
|
||||
|
||||
static KeymapSwitcher* s_the;
|
||||
|
||||
KeymapSwitcher& KeymapSwitcher::the()
|
||||
{
|
||||
VERIFY(s_the);
|
||||
return *s_the;
|
||||
}
|
||||
|
||||
KeymapSwitcher::KeymapSwitcher()
|
||||
{
|
||||
s_the = this;
|
||||
}
|
||||
|
||||
KeymapSwitcher::~KeymapSwitcher()
|
||||
|
@ -80,10 +71,7 @@ String KeymapSwitcher::get_current_keymap() const
|
|||
auto json = JsonValue::from_string(proc_keymap->read_all()).release_value_but_fixme_should_propagate_errors();
|
||||
auto const& keymap_object = json.as_object();
|
||||
VERIFY(keymap_object.has("keymap"));
|
||||
auto keymap = keymap_object.get("keymap").to_string();
|
||||
dbgln("Current keymap is: {}", keymap);
|
||||
|
||||
return keymap;
|
||||
return keymap_object.get("keymap").to_string();
|
||||
}
|
||||
|
||||
void KeymapSwitcher::setkeymap(const AK::String& keymap)
|
||||
|
@ -94,6 +82,8 @@ void KeymapSwitcher::setkeymap(const AK::String& keymap)
|
|||
perror("posix_spawn");
|
||||
dbgln("Failed to call /bin/keymap, error: {} ({})", errno, strerror(errno));
|
||||
}
|
||||
if (on_keymap_change)
|
||||
on_keymap_change(keymap);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,27 +11,29 @@
|
|||
#include <AK/WeakPtr.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <LibKeyboard/CharacterMap.h>
|
||||
#include <WindowServer/WMClientConnection.h>
|
||||
|
||||
namespace WindowServer {
|
||||
|
||||
class KeymapSwitcher final : public Core::Object {
|
||||
C_OBJECT(KeymapSwitcher)
|
||||
public:
|
||||
static KeymapSwitcher& the();
|
||||
|
||||
virtual ~KeymapSwitcher() override;
|
||||
|
||||
void refresh();
|
||||
|
||||
void next_keymap();
|
||||
|
||||
Function<void(String const& keymap)> on_keymap_change;
|
||||
|
||||
String get_current_keymap() const;
|
||||
|
||||
private:
|
||||
KeymapSwitcher();
|
||||
|
||||
Vector<AK::String> m_keymaps;
|
||||
|
||||
void setkeymap(AK::String const&);
|
||||
String get_current_keymap() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ enum WMEventMask {
|
|||
WindowIconChanges = 1 << 2,
|
||||
WindowRemovals = 1 << 3,
|
||||
WorkspaceChanges = 1 << 4,
|
||||
KeymapChanged = 1 << 5,
|
||||
};
|
||||
|
||||
enum class WindowTileType {
|
||||
|
|
|
@ -53,6 +53,18 @@ WindowManager::WindowManager(Gfx::PaletteImpl const& palette)
|
|||
|
||||
reload_config();
|
||||
|
||||
m_keymap_switcher->on_keymap_change = [&](String const& keymap) {
|
||||
for_each_window_manager([&keymap](WMClientConnection& conn) {
|
||||
if (!(conn.event_mask() & WMEventMask::KeymapChanged))
|
||||
return IterationDecision::Continue;
|
||||
if (conn.window_id() < 0)
|
||||
return IterationDecision::Continue;
|
||||
|
||||
conn.async_keymap_changed(conn.window_id(), keymap);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
};
|
||||
|
||||
Compositor::the().did_construct_window_manager({});
|
||||
}
|
||||
|
||||
|
|
|
@ -10,4 +10,5 @@ endpoint WindowManagerClient
|
|||
super_key_pressed(i32 wm_id) =|
|
||||
super_space_key_pressed(i32 wm_id) =|
|
||||
workspace_changed(i32 wm_id, u32 row, u32 column) =|
|
||||
keymap_changed(i32 wm_id, [UTF8] String keymap) =|
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue