diff --git a/patches/globalkey/README.md b/patches/globalkey/README.md index 92cced1..d250f92 100644 --- a/patches/globalkey/README.md +++ b/patches/globalkey/README.md @@ -6,13 +6,13 @@ This might deal with Wayland's lack of global shortcuts. Example: ``` static const PassKeypressRule pass_rules[] = { - ADDPASSRULE("com.obsproject.Studio", MODKEY, XKB_KEY_Home), - ADDPASSRULE("discord", 0, XKB_KEY_n), + ADDPASSRULE("com.obsproject.Studio", XKB_KEY_Home), + ADDPASSRULE("WebCord", XKB_KEY_n), /* xkb key is case-insensitive */ }; ``` -This will pass the `MODKEY + Home` keys to OBS regardless of what client is currently focused, if any. +This will pass the `Home` key (alongside with mods) to OBS regardless of what client is currently focused, if any. The string "com.obsproject.Studio" should match the exact appid of the client. To get the appid use [dwlmsg](https://codeberg.org/notchoc/dwlmsg) or run stock dwl from a terminal then launch the needed application inside, dwl will print all the info to the stdout. @@ -20,6 +20,12 @@ To get the appid use [dwlmsg](https://codeberg.org/notchoc/dwlmsg) or run stock Note that if a popup (like [fuzzel](https://codeberg.org/dnkl/fuzzel)) is focused, no keys will be globally passed. This is done so these menus don't get closed after hitting some of the global keys. +## Warning +This patch is a stupid hack, it doesn't work all the time. +Examples: obs needs to be clicked on once before applying global hotkeys. +Electron (discord/webcord/chromium) with wayland backend ignores the very first press. +Other programs might not work at all. + ### Download - [git branch](https://codeberg.org/korei999/dwl/src/branch/globalkey) - [2024-06-08](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/globalkey/globalkey.patch) diff --git a/patches/globalkey/globalkey.patch b/patches/globalkey/globalkey.patch index 90b4b0d..07d3856 100644 --- a/patches/globalkey/globalkey.patch +++ b/patches/globalkey/globalkey.patch @@ -1,51 +1,50 @@ -From 65e2466212beb3040241e3b6ca8e730e6b96fd66 Mon Sep 17 00:00:00 2001 +From f36e3f134c9f14a9821783d9908471ed0bdca0ed Mon Sep 17 00:00:00 2001 From: korei999 -Date: Thu, 21 Nov 2024 02:24:32 +0200 +Date: Fri, 14 Mar 2025 20:05:45 +0200 Subject: [PATCH] implement globalkey patch --- - config.def.h | 8 ++++++++ - dwl.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 66 insertions(+) + config.def.h | 8 +++++++ + dwl.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 69 insertions(+) diff --git a/config.def.h b/config.def.h -index 22d2171..2bf1c68 100644 +index 22d2171..25486c8 100644 --- a/config.def.h +++ b/config.def.h @@ -122,6 +122,14 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA static const char *termcmd[] = { "foot", NULL }; static const char *menucmd[] = { "wmenu-run", NULL }; -+#define ADDPASSRULE(S, M, K) {.appid = S, .len = LENGTH(S), .key = K} ++#define ADDPASSRULE(S, K) {.appid = S, .len = LENGTH(S), .key = K} +static const PassKeypressRule pass_rules[] = { -+ ADDPASSRULE("com.obsproject.Studio", MODKEY, XKB_KEY_Home), -+ ADDPASSRULE("com.obsproject.Studio", MODKEY, XKB_KEY_End), -+ ADDPASSRULE("com.obsproject.Studio", MODKEY, XKB_KEY_F12), -+ ADDPASSRULE("discord", 0, XKB_KEY_n), ++ ADDPASSRULE("com.obsproject.Studio", XKB_KEY_Home), ++ ADDPASSRULE("com.obsproject.Studio", XKB_KEY_End), ++ ADDPASSRULE("com.obsproject.Studio", XKB_KEY_F12), ++ ADDPASSRULE("WebCord", XKB_KEY_n), +}; + static const Key keys[] = { /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ /* modifier key function argument */ diff --git a/dwl.c b/dwl.c -index 9acb898..a0d632a 100644 +index 4816159..9ad64dd 100644 --- a/dwl.c +++ b/dwl.c -@@ -221,6 +221,13 @@ typedef struct { +@@ -217,6 +217,12 @@ typedef struct { int x, y; } MonitorRule; +typedef struct { + const char* appid; + size_t len; -+ uint32_t mod; + uint32_t key; +} PassKeypressRule; + typedef struct { struct wlr_pointer_constraint_v1 *constraint; struct wl_listener destroy; -@@ -297,6 +304,7 @@ static void incnmaster(const Arg *arg); +@@ -293,6 +299,7 @@ static void incnmaster(const Arg *arg); static void inputdevice(struct wl_listener *listener, void *data); static int keybinding(uint32_t mods, xkb_keysym_t sym); static void keypress(struct wl_listener *listener, void *data); @@ -53,7 +52,7 @@ index 9acb898..a0d632a 100644 static void keypressmod(struct wl_listener *listener, void *data); static int keyrepeat(void *data); static void killclient(const Arg *arg); -@@ -1575,6 +1583,12 @@ keypress(struct wl_listener *listener, void *data) +@@ -1628,6 +1635,12 @@ keypress(struct wl_listener *listener, void *data) /* This event is raised when a key is pressed or released. */ KeyboardGroup *group = wl_container_of(listener, group, key); struct wlr_keyboard_key_event *event = data; @@ -66,7 +65,7 @@ index 9acb898..a0d632a 100644 /* Translate libinput keycode -> xkbcommon */ uint32_t keycode = event->keycode + 8; -@@ -1609,12 +1623,56 @@ keypress(struct wl_listener *listener, void *data) +@@ -1662,12 +1675,60 @@ keypress(struct wl_listener *listener, void *data) if (handled) return; @@ -78,8 +77,10 @@ index 9acb898..a0d632a 100644 +#endif + ; + /* passed keys don't get repeated */ -+ if (pass && syms) -+ keypressglobal(last_surface, &group->wlr_group->keyboard, event, mods, syms[0]); ++ if (!locked && pass) { ++ for (i = 0; i < nsyms; ++i) ++ keypressglobal(last_surface, &group->wlr_group->keyboard, event, mods, syms[i]); ++ } + wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard); /* Pass unhandled keycodes along to the client. */ @@ -91,13 +92,13 @@ index 9acb898..a0d632a 100644 +keypressglobal(struct wlr_surface *last_surface, struct wlr_keyboard *keyboard, struct wlr_keyboard_key_event *event, uint32_t mods, xkb_keysym_t keysym) +{ + Client *c = NULL, *lastc = focustop(selmon); -+ uint32_t keycodes[32] = {0}; + int reset = false; + const char *appid = NULL; + + for (size_t r = 0; r < LENGTH(pass_rules); r++) { + uint32_t rcode = xkb_keysym_to_upper(pass_rules[r].key); + uint32_t pcode = xkb_keysym_to_upper(keysym); ++ + /* match key only (case insensitive) ignoring mods */ + if (rcode == pcode) { + wl_list_for_each(c, &clients, link) { @@ -105,7 +106,9 @@ index 9acb898..a0d632a 100644 + appid = client_get_appid(c); + if (appid && strncmp(appid, pass_rules[r].appid, pass_rules[r].len) == 0) { + reset = true; -+ wlr_seat_keyboard_enter(seat, client_surface(c), keycodes, 0, &keyboard->modifiers); ++ ++ client_notify_enter(client_surface(c), keyboard); ++ client_activate_surface(client_surface(c), 1); + wlr_seat_keyboard_send_key(seat, event->time_msec, event->keycode, event->state); + + goto done; @@ -116,13 +119,13 @@ index 9acb898..a0d632a 100644 + } + +done: -+ if (reset) -+ wlr_seat_keyboard_enter(seat, last_surface, keycodes, 0, &keyboard->modifiers); ++ if (reset && last_surface) ++ client_notify_enter(last_surface, keyboard); +} + void keypressmod(struct wl_listener *listener, void *data) { -- -2.47.0 +2.48.1