My configuration of sxmo fork of suckless dwm.

git clone git://watertao.xyz/programs/sxmo-dwm.git

commit 95f1fd201b3ef7b39deedfffdc1a643f9199b2df
parent 4ae374e2cfb5cf43bcdacbc1e5e6833fd071a6e0
Author: Willow Barraco <contact@willowbarraco.fr>
Date:   Thu, 16 Feb 2023 11:34:36 +0100

Add keypressrelease patch

Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
Signed-off-by: Peter John Hartman <peterjohnhartman@gmail.com>

Diffstat:
Mconfig.def.h | 97+++++++++++++++++++++++++++++++++++++++----------------------------------------
Mdwm.c | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 146 insertions(+), 49 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -67,9 +67,9 @@ static const Layout layouts[] = { /* key definitions */ #define MODKEY Mod4Mask #define TAGKEYS(KEY,TAG) \ - { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ - { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, + { KeyPress, MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { KeyPress, MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { KeyPress, MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, /* helper for spawning shell commands in the pre dwm-5.0 fashion */ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } @@ -81,74 +81,73 @@ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, #include <X11/XF86keysym.h> static Key keys[] = { /* PP */ - { 0, XF86XK_AudioRaiseVolume, spawn, SHCMD("sxmo_hook_inputhandler.sh volup_one") }, - { 0, XF86XK_AudioLowerVolume, spawn, SHCMD("sxmo_hook_inputhandler.sh voldown_one") }, - - { 0, XF86XK_PowerOff, spawn, SHCMD("sxmo_hook_inputhandler.sh powerbutton_one") }, + { KeyPress, 0, XF86XK_AudioRaiseVolume, spawn, { .v = (const char*[]){ "sxmo_hook_inputhandler.sh", "volup_one", NULL } } }, + { KeyPress, 0, XF86XK_AudioLowerVolume, spawn, { .v = (const char*[]){ "sxmo_hook_inputhandler.sh", "voldown_one", NULL } } }, + { KeyPress, 0, XF86XK_PowerOff, spawn, { .v = (const char*[]){ "sxmo_hook_inputhandler.sh", "powerbutton_one", NULL } } }, /* Used by scripts via xdotool */ - { MODKEY|ShiftMask, XK_e, shiftview, {.i = -1} }, - { MODKEY|ShiftMask, XK_r, shiftview, {.i = +1} }, - { MODKEY, XK_e, clienttagpush, {.i = -1} }, - { MODKEY, XK_r, clienttagpush, {.i = +1} }, + { KeyPress, MODKEY|ShiftMask, XK_e, shiftview, {.i = -1} }, + { KeyPress, MODKEY|ShiftMask, XK_r, shiftview, {.i = +1} }, + { KeyPress, MODKEY, XK_e, clienttagpush, {.i = -1} }, + { KeyPress, MODKEY, XK_r, clienttagpush, {.i = +1} }, /* PBP */ - { MODKEY, XK_p, spawn, SHCMD("sxmo_appmenu.sh") }, - { MODKEY, XK_d, spawn, SHCMD("sxmo_files.sh") }, + { KeyPress, MODKEY, XK_p, spawn, SHCMD("sxmo_appmenu.sh") }, + { KeyPress, MODKEY, XK_d, spawn, SHCMD("sxmo_files.sh") }, - { MODKEY|ShiftMask, XK_Return, spawn, SHCMD("st") }, - { MODKEY, XK_b, togglebar, {0} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, + { KeyPress, MODKEY|ShiftMask, XK_Return, spawn, SHCMD("st") }, + { KeyPress, MODKEY, XK_b, togglebar, {0} }, + { KeyPress, MODKEY, XK_j, focusstack, {.i = +1 } }, + { KeyPress, MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY|ShiftMask, XK_j, pushdown, {.i = +1 } }, - { MODKEY|ShiftMask, XK_k, pushup, {.i = -1 } }, + { KeyPress, MODKEY|ShiftMask, XK_j, pushdown, {.i = +1 } }, + { KeyPress, MODKEY|ShiftMask, XK_k, pushup, {.i = -1 } }, - { MODKEY, XK_x, inplacerotate, {.i = +2 } }, + { KeyPress, MODKEY, XK_x, inplacerotate, {.i = +2 } }, - { 0, XF86XK_MonBrightnessUp, spawn, SHCMD("sxmo_brightness.sh up") }, - { 0, XF86XK_MonBrightnessDown, spawn, SHCMD("sxmo_brightness.sh down") }, - { MODKEY|ShiftMask, XK_Down, spawn, SHCMD("sxmo_audio.sh vol down") }, - { MODKEY|ShiftMask, XK_Up, spawn, SHCMD("sxmo_audio.sh vol up") }, + { KeyPress, 0, XF86XK_MonBrightnessUp, spawn, SHCMD("sxmo_brightness.sh up") }, + { KeyPress, 0, XF86XK_MonBrightnessDown, spawn, SHCMD("sxmo_brightness.sh down") }, + { KeyPress, MODKEY|ShiftMask, XK_Down, spawn, SHCMD("sxmo_audio.sh vol down") }, + { KeyPress, MODKEY|ShiftMask, XK_Up, spawn, SHCMD("sxmo_audio.sh vol up") }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, - { MODKEY, XK_o, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, - { MODKEY|ShiftMask, XK_q, killclient, {0} }, + { KeyPress, MODKEY, XK_i, incnmaster, {.i = +1 } }, + { KeyPress, MODKEY, XK_o, incnmaster, {.i = -1 } }, + { KeyPress, MODKEY, XK_h, setmfact, {.f = -0.05} }, + { KeyPress, MODKEY, XK_l, setmfact, {.f = +0.05} }, + { KeyPress, MODKEY, XK_Return, zoom, {0} }, + { KeyPress, MODKEY, XK_Tab, view, {0} }, + { KeyPress, MODKEY|ShiftMask, XK_c, killclient, {0} }, + { KeyPress, MODKEY|ShiftMask, XK_q, killclient, {0} }, - { MODKEY|ShiftMask, XK_q, killclient, {0} }, + { KeyPress, MODKEY|ShiftMask, XK_q, killclient, {0} }, - { MODKEY, XK_semicolon, switchcol, {0} }, + { KeyPress, MODKEY, XK_semicolon, switchcol, {0} }, - { MODKEY, XK_s, transfer, {0} }, - { MODKEY, XK_s, transferall, {0} }, + { KeyPress, MODKEY, XK_s, transfer, {0} }, + { KeyPress, MODKEY, XK_s, transferall, {0} }, /* monocle */ - { MODKEY, XK_m, setlayout, {.v = &layouts[3]} }, + { KeyPress, MODKEY, XK_m, setlayout, {.v = &layouts[3]} }, /* tile */ - { MODKEY, XK_slash, setlayout, {.v = &layouts[1]} }, + { KeyPress, MODKEY, XK_slash, setlayout, {.v = &layouts[1]} }, /* bstack */ - { MODKEY|ShiftMask, XK_slash, setlayout, {.v = &layouts[0]} }, + { KeyPress, MODKEY|ShiftMask, XK_slash, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, togglefloating, {0} }, - { MODKEY|ShiftMask, XK_f, unfloatvisible, {0} }, + { KeyPress, MODKEY, XK_f, togglefloating, {0} }, + { KeyPress, MODKEY|ShiftMask, XK_f, unfloatvisible, {0} }, /* cycle through the layouts in ppcyclelayouts */ - { MODKEY, XK_space, cyclelayout, {.i = +1} }, + { KeyPress, MODKEY, XK_space, cyclelayout, {.i = +1} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { KeyPress, MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { KeyPress, MODKEY, XK_0, view, {.ui = ~0 } }, + { KeyPress, MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + { KeyPress, MODKEY, XK_comma, focusmon, {.i = -1 } }, + { KeyPress, MODKEY, XK_period, focusmon, {.i = +1 } }, + { KeyPress, MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { KeyPress, MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, TAGKEYS( XK_1, 0) TAGKEYS( XK_2, 1) diff --git a/dwm.c b/dwm.c @@ -107,6 +107,7 @@ struct Client { }; typedef struct { + int type; unsigned int mod; KeySym keysym; void (*func)(const Arg *); @@ -118,6 +119,11 @@ typedef struct { void (*arrange)(Monitor *); } Layout; +typedef struct HoldKey { + KeySym keysym; + struct HoldKey *next; +}; + struct Monitor { char ltsymbol[16]; float mfact; @@ -191,6 +197,7 @@ static void grabkeys(void); static void incnmaster(const Arg *arg); static void inplacerotate(const Arg *arg); static void keypress(XEvent *e); +static void keyrelease(XEvent *e); static void killclient(const Arg *arg); static void manage(Window w, XWindowAttributes *wa); static void mappingnotify(XEvent *e); @@ -286,6 +293,7 @@ static void (*handler[LASTEvent]) (XEvent *) = { [Expose] = expose, [FocusIn] = focusin, [KeyPress] = keypress, + [KeyRelease] = keyrelease, [MappingNotify] = mappingnotify, [MapRequest] = maprequest, //[MotionNotify] = motionnotify, @@ -306,6 +314,8 @@ static char *colors[4][3]; /* 4 schemes, 3 colors each */ static xcb_connection_t *xcon; +static struct HoldKey *holdkeyroot = NULL; + /* configuration, allows nested code to access above variables */ #include "config.h" @@ -1263,6 +1273,64 @@ iswide() { } void +markhold(KeySym keysym) +{ + struct HoldKey *new = malloc(sizeof(struct HoldKey)); + new->keysym = keysym; + new->next = NULL; + + if (holdkeyroot == NULL) { + holdkeyroot = new; + return; + } + + struct HoldKey *cur = holdkeyroot; + while (cur->next != NULL) + cur = cur->next; + + cur->next = new; +} + +void +markreleased(KeySym keysym) +{ + if (holdkeyroot == NULL) { + return; + } + + struct HoldKey *cur = holdkeyroot; + + if (cur->keysym == keysym) { + holdkeyroot = cur->next; + free(cur); + return; + } + + while (cur->next != NULL) { + if (cur->next->keysym == keysym) { + struct HoldKey *toremove = cur->next; + cur->next = toremove->next; + free(toremove); + return; + } + cur = cur->next; + } +} + +int +ishold(KeySym keysym) +{ + struct HoldKey *cur = holdkeyroot; + while (cur != NULL) { + if (cur->keysym == keysym) + return 1; + cur = cur->next; + }; + + return 0; +} + +void keypress(XEvent *e) { unsigned int i; @@ -1271,8 +1339,37 @@ keypress(XEvent *e) ev = &e->xkey; keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); + + if (ishold(keysym)) + return; + + markhold(keysym); + + for (i = 0; i < LENGTH(keys); i++) { + if (keysym == keys[i].keysym + && KeyPress == keys[i].type + && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) + && keys[i].func) { + keys[i].func(&(keys[i].arg)); + } + } +} + +void +keyrelease(XEvent *e) +{ + unsigned int i; + KeySym keysym; + XKeyEvent *ev; + + ev = &e->xkey; + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); + + markreleased(keysym); + for (i = 0; i < LENGTH(keys); i++) { if (keysym == keys[i].keysym + && KeyRelease == keys[i].type && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && keys[i].func) { keys[i].func(&(keys[i].arg)); @@ -2640,6 +2737,7 @@ main(int argc, char *argv[]) fputs("warning: no locale support\n", stderr); if (!(dpy = XOpenDisplay(NULL))) die("dwm: cannot open display"); + XkbSetDetectableAutoRepeat(dpy, True, NULL); if (!(xcon = XGetXCBConnection(dpy))) die("dwm: cannot get xcb connection\n"); checkotherwm();