From 0d6af14efa1250631b081ad9d1f3aa0263221fd8 Mon Sep 17 00:00:00 2001 From: TUVIMEN Date: Fri, 6 Jun 2025 09:08:40 +0200 Subject: [PATCH] [PATCH] 6.5 keysequence patch --- config.def.h | 1 + dwm.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/config.def.h b/config.def.h index 9efa774..6104343 100644 --- a/config.def.h +++ b/config.def.h @@ -95,6 +95,7 @@ static const Key keys[] = { TAGKEYS( XK_8, 7) TAGKEYS( XK_9, 8) { MODKEY|ShiftMask, XK_q, quit, {0} }, + {0} }; /* button definitions */ diff --git a/dwm.c b/dwm.c index f1d86b2..89a4bc5 100644 --- a/dwm.c +++ b/dwm.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -177,6 +178,7 @@ static void grabbuttons(Client *c, int focused); static void grabkeys(void); static void incnmaster(const Arg *arg); static void keypress(XEvent *e); +static void keypress_other(const Arg *arg); static void killclient(const Arg *arg); static void manage(Window w, XWindowAttributes *wa); static void mappingnotify(XEvent *e); @@ -949,6 +951,13 @@ grabbuttons(Client *c, int focused) } } +static char +key_not_empty(const Key *key) +{ + static const Key empty = {0}; + return memcmp(key, &empty, sizeof(Key)) != 0; +} + void grabkeys(void) { @@ -965,7 +974,7 @@ grabkeys(void) if (!syms) return; for (k = start; k <= end; k++) - for (i = 0; i < LENGTH(keys); i++) + for (i = 0; key_not_empty(keys+i); i++) /* skip modifier codes, we do that ourselves */ if (keys[i].keysym == syms[(k - start) * skip]) for (j = 0; j < LENGTH(modifiers); j++) @@ -996,8 +1005,8 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) } #endif /* XINERAMA */ -void -keypress(XEvent *e) +static void +keypress_r(XEvent *e, const Key *keys) { unsigned int i; KeySym keysym; @@ -1005,11 +1014,74 @@ keypress(XEvent *e) ev = &e->xkey; keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); - for (i = 0; i < LENGTH(keys); i++) + for (i = 0; key_not_empty(keys+i); i++) if (keysym == keys[i].keysym - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keys[i].func) - keys[i].func(&(keys[i].arg)); + && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) + && keys[i].func) + keys[i].func(&(keys[i].arg)); +} + +static char +grabkeyboard(void) //taken from dmenu +{ + struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; + + /* try to grab keyboard, we may have to wait for another process to ungrab */ + for (int i = 0; i < 1000; i++) { + if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, + GrabModeAsync, CurrentTime) == GrabSuccess) + return 0; + nanosleep(&ts, NULL); + } + return 1; //failed +} + +static char +keysym_is_modifier(KeySym s) +{ + return (s == XK_Shift_L || + s == XK_Shift_R || + s == XK_Control_L || + s == XK_Control_R || + s == XK_Caps_Lock || + s == XK_Shift_Lock || + s == XK_Meta_L || + s == XK_Meta_R || + s == XK_Alt_L || + s == XK_Alt_R || + s == XK_Super_L || + s == XK_Super_R || + s == XK_Hyper_L || + s == XK_Hyper_R); +} + +void +keypress_other(const Arg *arg) +{ + if (grabkeyboard()) + return; + + XEvent ev; + while (!XNextEvent(dpy, &ev)) { + if (ev.type == ButtonPress) + break; + if (ev.type == KeyPress) { + KeySym keysym = XKeycodeToKeysym(dpy, (KeyCode)ev.xkey.keycode, 0); + if (keysym_is_modifier(keysym)) + continue; + keypress_r(&ev, (Key*)arg->v); + break; + } + } + + XUngrabKeyboard(dpy, CurrentTime); + grabkeys(); +} + +void +keypress(XEvent *e) +{ + keypress_r(e,keys); } void -- 2.49.0