summaryrefslogtreecommitdiffstats
path: root/dwl-patches/patches/globalkey/globalkey.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dwl-patches/patches/globalkey/globalkey.patch')
-rw-r--r--dwl-patches/patches/globalkey/globalkey.patch131
1 files changed, 131 insertions, 0 deletions
diff --git a/dwl-patches/patches/globalkey/globalkey.patch b/dwl-patches/patches/globalkey/globalkey.patch
new file mode 100644
index 0000000..07d3856
--- /dev/null
+++ b/dwl-patches/patches/globalkey/globalkey.patch
@@ -0,0 +1,131 @@
+From f36e3f134c9f14a9821783d9908471ed0bdca0ed Mon Sep 17 00:00:00 2001
+From: korei999 <ju7t1xe@gmail.com>
+Date: Fri, 14 Mar 2025 20:05:45 +0200
+Subject: [PATCH] implement globalkey patch
+
+---
+ config.def.h | 8 +++++++
+ dwl.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 69 insertions(+)
+
+diff --git a/config.def.h b/config.def.h
+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, K) {.appid = S, .len = LENGTH(S), .key = K}
++static const PassKeypressRule pass_rules[] = {
++ 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 4816159..9ad64dd 100644
+--- a/dwl.c
++++ b/dwl.c
+@@ -217,6 +217,12 @@ typedef struct {
+ int x, y;
+ } MonitorRule;
+
++typedef struct {
++ const char* appid;
++ size_t len;
++ uint32_t key;
++} PassKeypressRule;
++
+ typedef struct {
+ struct wlr_pointer_constraint_v1 *constraint;
+ struct wl_listener destroy;
+@@ -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);
++static void keypressglobal(struct wlr_surface *last_surface, struct wlr_keyboard *keyboard, struct wlr_keyboard_key_event *event, uint32_t mods, xkb_keysym_t keysym);
+ static void keypressmod(struct wl_listener *listener, void *data);
+ static int keyrepeat(void *data);
+ static void killclient(const Arg *arg);
+@@ -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;
++ struct wlr_surface *last_surface = seat->keyboard_state.focused_surface;
++ struct wlr_xdg_surface *xdg_surface = last_surface ? wlr_xdg_surface_try_from_wlr_surface(last_surface) : NULL;
++ int pass = 0;
++#ifdef XWAYLAND
++ struct wlr_xwayland_surface *xsurface = last_surface ? wlr_xwayland_surface_try_from_wlr_surface(last_surface) : NULL;
++#endif
+
+ /* Translate libinput keycode -> xkbcommon */
+ uint32_t keycode = event->keycode + 8;
+@@ -1662,12 +1675,60 @@ keypress(struct wl_listener *listener, void *data)
+ if (handled)
+ return;
+
++ /* don't pass when popup is focused
++ * this is better than having popups (like fuzzel or wmenu) closing while typing in a passed keybind */
++ pass = (xdg_surface && xdg_surface->role != WLR_XDG_SURFACE_ROLE_POPUP) || !last_surface
++#ifdef XWAYLAND
++ || xsurface
++#endif
++ ;
++ /* passed keys don't get repeated */
++ 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. */
+ wlr_seat_keyboard_notify_key(seat, event->time_msec,
+ event->keycode, event->state);
+ }
+
++void
++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);
++ 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) {
++ if (c && c != lastc) {
++ appid = client_get_appid(c);
++ if (appid && strncmp(appid, pass_rules[r].appid, pass_rules[r].len) == 0) {
++ reset = true;
++
++ 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;
++ }
++ }
++ }
++ }
++ }
++
++done:
++ if (reset && last_surface)
++ client_notify_enter(last_surface, keyboard);
++}
++
+ void
+ keypressmod(struct wl_listener *listener, void *data)
+ {
+--
+2.48.1
+