summaryrefslogtreecommitdiff
path: root/Userland/Services/WindowServer
diff options
context:
space:
mode:
authorJulian Offenhäuser <offenhaeuser@protonmail.com>2023-03-20 20:45:36 +0100
committerSam Atkins <atkinssj@gmail.com>2023-04-14 12:38:40 +0100
commite32ab161ae2bb8096f4b8f7c91c4ca481a2b2ecb (patch)
treef0567bf906d8ea3fc55283df71303daca5ed879c /Userland/Services/WindowServer
parente59137d4f6638e960aa0260c5c3b03ce7d740eab (diff)
downloadserenity-e32ab161ae2bb8096f4b8f7c91c4ca481a2b2ecb.zip
WindowServer: Fix alt shortcut navigation for non-default keymaps
Some keymaps will bind key presses with the alt modifier to characters other than the unmodified one, in which case you couldn't activate the alt shortcuts in the menu bar before. We now ask the current keymap for the code point that is mapped to the pressed (unmodified) key instead.
Diffstat (limited to 'Userland/Services/WindowServer')
-rw-r--r--Userland/Services/WindowServer/CMakeLists.txt2
-rw-r--r--Userland/Services/WindowServer/Window.cpp39
-rw-r--r--Userland/Services/WindowServer/main.cpp6
3 files changed, 30 insertions, 17 deletions
diff --git a/Userland/Services/WindowServer/CMakeLists.txt b/Userland/Services/WindowServer/CMakeLists.txt
index ed975c387e..77875a349f 100644
--- a/Userland/Services/WindowServer/CMakeLists.txt
+++ b/Userland/Services/WindowServer/CMakeLists.txt
@@ -45,5 +45,5 @@ set(GENERATED_SOURCES
)
serenity_bin(WindowServer)
-target_link_libraries(WindowServer PRIVATE LibCore LibFileSystem LibGfx LibThreading LibIPC LibMain)
+target_link_libraries(WindowServer PRIVATE LibCore LibFileSystem LibKeyboard LibGfx LibThreading LibIPC LibMain)
serenity_install_headers(Services/WindowServer)
diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp
index cee941835d..3ca0538613 100644
--- a/Userland/Services/WindowServer/Window.cpp
+++ b/Userland/Services/WindowServer/Window.cpp
@@ -19,6 +19,7 @@
#include <LibCore/Account.h>
#include <LibCore/ProcessStatisticsReader.h>
#include <LibCore/SessionManagement.h>
+#include <LibKeyboard/CharacterMap.h>
namespace WindowServer {
@@ -516,20 +517,32 @@ void Window::handle_keydown_event(KeyEvent const& event)
return;
}
if (event.modifiers() == Mod_Alt && event.code_point() && m_menubar.has_menus()) {
- Menu* menu_to_open = nullptr;
- m_menubar.for_each_menu([&](Menu& menu) {
- if (to_ascii_lowercase(menu.alt_shortcut_character()) == to_ascii_lowercase(event.code_point())) {
- menu_to_open = &menu;
- return IterationDecision::Break;
+ // When handling alt shortcuts, we only care about the key that has been pressed in addition
+ // to alt, not the code point that has been mapped to alt+[key], so we have to look up the
+ // scancode directly from the "unmodified" character map.
+ auto character_map_or_error = Keyboard::CharacterMap::fetch_system_map();
+ if (!character_map_or_error.is_error()) {
+ auto& character_map = character_map_or_error.value();
+
+ // The lowest byte serves as our index into the character table.
+ auto index = event.scancode() & 0xff;
+ u32 character = to_ascii_lowercase(character_map.character_map_data().map[index]);
+
+ Menu* menu_to_open = nullptr;
+ m_menubar.for_each_menu([&](Menu& menu) {
+ if (to_ascii_lowercase(menu.alt_shortcut_character()) == character) {
+ menu_to_open = &menu;
+ return IterationDecision::Break;
+ }
+ return IterationDecision::Continue;
+ });
+
+ if (menu_to_open) {
+ frame().open_menubar_menu(*menu_to_open);
+ if (!menu_to_open->is_empty())
+ menu_to_open->set_hovered_index(0);
+ return;
}
- return IterationDecision::Continue;
- });
-
- if (menu_to_open) {
- frame().open_menubar_menu(*menu_to_open);
- if (!menu_to_open->is_empty())
- menu_to_open->set_hovered_index(0);
- return;
}
}
m_client->async_key_down(m_window_id, (u32)event.code_point(), (u32)event.key(), event.modifiers(), (u32)event.scancode());
diff --git a/Userland/Services/WindowServer/main.cpp b/Userland/Services/WindowServer/main.cpp
index 6b0176e1fb..c71efa5f76 100644
--- a/Userland/Services/WindowServer/main.cpp
+++ b/Userland/Services/WindowServer/main.cpp
@@ -25,7 +25,7 @@ RefPtr<Core::ConfigFile> g_config;
ErrorOr<int> serenity_main(Main::Arguments)
{
- TRY(Core::System::pledge("stdio video thread sendfd recvfd accept rpath wpath cpath unix proc sigaction exec tty"));
+ TRY(Core::System::pledge("stdio video thread sendfd recvfd accept rpath wpath cpath unix proc getkeymap sigaction exec tty"));
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/tmp", "cw"));
TRY(Core::System::unveil("/etc/WindowServer.ini", "rwc"));
@@ -42,7 +42,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
act.sa_flags = SA_NOCLDWAIT;
act.sa_handler = SIG_IGN;
TRY(Core::System::sigaction(SIGCHLD, &act, nullptr));
- TRY(Core::System::pledge("stdio video thread sendfd recvfd accept rpath wpath cpath unix proc exec tty"));
+ TRY(Core::System::pledge("stdio video thread sendfd recvfd accept rpath wpath cpath unix proc getkeymap exec tty"));
WindowServer::g_config = TRY(Core::ConfigFile::open("/etc/WindowServer.ini", Core::ConfigFile::AllowWriting::Yes));
auto theme_name = WindowServer::g_config->read_entry("Theme", "Name", "Default");
@@ -73,7 +73,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
WindowServer::EventLoop loop;
- TRY(Core::System::pledge("stdio video thread sendfd recvfd accept rpath wpath cpath unix proc exec"));
+ TRY(Core::System::pledge("stdio video thread sendfd recvfd accept rpath wpath cpath unix proc getkeymap exec"));
// First check which screens are explicitly configured
{