keysequence-20250606-0d6af14.diff (4102B)
1 From 0d6af14efa1250631b081ad9d1f3aa0263221fd8 Mon Sep 17 00:00:00 2001 2 From: TUVIMEN <hexderm@gmail.com> 3 Date: Fri, 6 Jun 2025 09:08:40 +0200 4 Subject: [PATCH] [PATCH] 6.5 keysequence patch 5 6 --- 7 config.def.h | 1 + 8 dwm.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++----- 9 2 files changed, 80 insertions(+), 7 deletions(-) 10 11 diff --git a/config.def.h b/config.def.h 12 index 9efa774..6104343 100644 13 --- a/config.def.h 14 +++ b/config.def.h 15 @@ -95,6 +95,7 @@ static const Key keys[] = { 16 TAGKEYS( XK_8, 7) 17 TAGKEYS( XK_9, 8) 18 { MODKEY|ShiftMask, XK_q, quit, {0} }, 19 + {0} 20 }; 21 22 /* button definitions */ 23 diff --git a/dwm.c b/dwm.c 24 index f1d86b2..89a4bc5 100644 25 --- a/dwm.c 26 +++ b/dwm.c 27 @@ -28,6 +28,7 @@ 28 #include <stdlib.h> 29 #include <string.h> 30 #include <unistd.h> 31 +#include <time.h> 32 #include <sys/types.h> 33 #include <sys/wait.h> 34 #include <X11/cursorfont.h> 35 @@ -177,6 +178,7 @@ static void grabbuttons(Client *c, int focused); 36 static void grabkeys(void); 37 static void incnmaster(const Arg *arg); 38 static void keypress(XEvent *e); 39 +static void keypress_other(const Arg *arg); 40 static void killclient(const Arg *arg); 41 static void manage(Window w, XWindowAttributes *wa); 42 static void mappingnotify(XEvent *e); 43 @@ -949,6 +951,13 @@ grabbuttons(Client *c, int focused) 44 } 45 } 46 47 +static char 48 +key_not_empty(const Key *key) 49 +{ 50 + static const Key empty = {0}; 51 + return memcmp(key, &empty, sizeof(Key)) != 0; 52 +} 53 + 54 void 55 grabkeys(void) 56 { 57 @@ -965,7 +974,7 @@ grabkeys(void) 58 if (!syms) 59 return; 60 for (k = start; k <= end; k++) 61 - for (i = 0; i < LENGTH(keys); i++) 62 + for (i = 0; key_not_empty(keys+i); i++) 63 /* skip modifier codes, we do that ourselves */ 64 if (keys[i].keysym == syms[(k - start) * skip]) 65 for (j = 0; j < LENGTH(modifiers); j++) 66 @@ -996,8 +1005,8 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) 67 } 68 #endif /* XINERAMA */ 69 70 -void 71 -keypress(XEvent *e) 72 +static void 73 +keypress_r(XEvent *e, const Key *keys) 74 { 75 unsigned int i; 76 KeySym keysym; 77 @@ -1005,11 +1014,74 @@ keypress(XEvent *e) 78 79 ev = &e->xkey; 80 keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); 81 - for (i = 0; i < LENGTH(keys); i++) 82 + for (i = 0; key_not_empty(keys+i); i++) 83 if (keysym == keys[i].keysym 84 - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) 85 - && keys[i].func) 86 - keys[i].func(&(keys[i].arg)); 87 + && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) 88 + && keys[i].func) 89 + keys[i].func(&(keys[i].arg)); 90 +} 91 + 92 +static char 93 +grabkeyboard(void) //taken from dmenu 94 +{ 95 + struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; 96 + 97 + /* try to grab keyboard, we may have to wait for another process to ungrab */ 98 + for (int i = 0; i < 1000; i++) { 99 + if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, 100 + GrabModeAsync, CurrentTime) == GrabSuccess) 101 + return 0; 102 + nanosleep(&ts, NULL); 103 + } 104 + return 1; //failed 105 +} 106 + 107 +static char 108 +keysym_is_modifier(KeySym s) 109 +{ 110 + return (s == XK_Shift_L || 111 + s == XK_Shift_R || 112 + s == XK_Control_L || 113 + s == XK_Control_R || 114 + s == XK_Caps_Lock || 115 + s == XK_Shift_Lock || 116 + s == XK_Meta_L || 117 + s == XK_Meta_R || 118 + s == XK_Alt_L || 119 + s == XK_Alt_R || 120 + s == XK_Super_L || 121 + s == XK_Super_R || 122 + s == XK_Hyper_L || 123 + s == XK_Hyper_R); 124 +} 125 + 126 +void 127 +keypress_other(const Arg *arg) 128 +{ 129 + if (grabkeyboard()) 130 + return; 131 + 132 + XEvent ev; 133 + while (!XNextEvent(dpy, &ev)) { 134 + if (ev.type == ButtonPress) 135 + break; 136 + if (ev.type == KeyPress) { 137 + KeySym keysym = XKeycodeToKeysym(dpy, (KeyCode)ev.xkey.keycode, 0); 138 + if (keysym_is_modifier(keysym)) 139 + continue; 140 + keypress_r(&ev, (Key*)arg->v); 141 + break; 142 + } 143 + } 144 + 145 + XUngrabKeyboard(dpy, CurrentTime); 146 + grabkeys(); 147 +} 148 + 149 +void 150 +keypress(XEvent *e) 151 +{ 152 + keypress_r(e,keys); 153 } 154 155 void 156 -- 157 2.49.0 158