1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 04:58:13 +00:00

LibGUI+WindowServer: Add app-global keyboard shortcuts.

This patch adds a GShortcut class. Each GAction can have a GShortcut which
will cause the event loop to listen for that key combination app-globally
and activate the event in case it's pressed.

The shortcut will also be displayed when the action is added to a menu.

Use this to hook up Alt+Up with the "open parent directory" action in the
FileManager app. :^)
This commit is contained in:
Andreas Kling 2019-03-02 10:04:49 +01:00
parent 5c0fca0a95
commit 596a5ce5a4
17 changed files with 263 additions and 17 deletions

View file

@ -18,18 +18,17 @@
//#define GEVENTLOOP_DEBUG
static HashMap<GShortcut, GAction*>* g_actions;
static GEventLoop* s_mainGEventLoop;
void GEventLoop::initialize()
{
s_mainGEventLoop = nullptr;
}
GEventLoop::GEventLoop()
{
if (!s_mainGEventLoop)
s_mainGEventLoop = this;
if (!g_actions)
g_actions = new HashMap<GShortcut, GAction*>;
m_event_fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
if (m_event_fd < 0) {
perror("socket");
@ -154,6 +153,14 @@ void GEventLoop::handle_key_event(const WSAPI_ServerMessage& event, GWindow& win
#ifdef GEVENTLOOP_DEBUG
dbgprintf("WID=%x KeyEvent character=0x%b\n", event.window_id, event.key.character);
#endif
unsigned modifiers = (event.key.alt * Mod_Alt) + (event.key.ctrl * Mod_Ctrl) + (event.key.shift * Mod_Shift);
auto it = g_actions->find(GShortcut(modifiers, (KeyCode)event.key.key));
if (it != g_actions->end()) {
(*it).value->activate();
return;
}
auto key_event = make<GKeyEvent>(event.type == WSAPI_ServerMessage::Type::KeyDown ? GEvent::KeyDown : GEvent::KeyUp, event.key.key);
key_event->m_alt = event.key.alt;
key_event->m_ctrl = event.key.ctrl;
@ -448,3 +455,13 @@ WSAPI_ServerMessage GEventLoop::sync_request(const WSAPI_ClientMessage& request,
ASSERT(success);
return response;
}
void GEventLoop::register_action_with_shortcut(Badge<GAction>, GAction& action)
{
g_actions->set(action.shortcut(), &action);
}
void GEventLoop::unregister_action_with_shortcut(Badge<GAction>, GAction& action)
{
g_actions->remove(action.shortcut());
}