From 2d0d68ce93d35a46029879addd567c89cc41597d Mon Sep 17 00:00:00 2001 From: Malfurious Date: Mon, 26 Feb 2024 15:20:38 -0500 Subject: patch: holdbar dwm's built-in status bar is now only shown when HOLDKEY is pressed. In addition the bar will now overlay the display. This will work regardless of the topbar setting. This is meant to be used with the bar off by default. None of the togglebar code has been removed, although you might want to remove the togglebar binding in your config.def.h. The holdbar-modkey patch (this) is a variant where holdbar is only active when the bar is toggled off and the holdkey can be the same as the modkey. This reverts commit 8657affa2a61 ("drawbar: Don't expend effort drawing bar if it is occluded"). When holdbar is applied, its effect prevents the bar from ever being drawn. Only a black rectangle appears when the key is held. This patch allows HOLDKEY to also be used in place of MODKEY for sending keystrokes to dwm while simultaneously peeking at the statusbar. --- config.def.h | 7 +++++-- dwm.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/config.def.h b/config.def.h index 9ef5309..aae7682 100644 --- a/config.def.h +++ b/config.def.h @@ -3,7 +3,7 @@ /* appearance */ static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ -static const int showbar = 1; /* 0 means no bar */ +static const int showbar = 0; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ static const char *fonts[] = { "monospace:size=10" }; static const char dmenufont[] = "monospace:size=10"; @@ -58,6 +58,8 @@ static const Layout layouts[] = { { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, +#define HOLDKEY XK_Super_L +#define HOLDMOD Mod4Mask /* helper for spawning shell commands in the pre dwm-5.0 fashion */ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } @@ -79,7 +81,7 @@ static const Key keys[] = { { MODKEY|ShiftMask, XK_z, spawn, {.v = slockucmd } }, { MODKEY|ShiftMask, XK_backslash, spawn, {.v = browsercmd } }, { MODKEY|ControlMask|ShiftMask, XK_backslash, spawn, {.v = browserpcmd } }, - { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, HOLDKEY, togglebar, {0} }, { MODKEY, XK_j, focusstack, {.i = +1 } }, { MODKEY, XK_k, focusstack, {.i = -1 } }, { MODKEY, XK_i, incnmaster, {.i = +1 } }, @@ -109,6 +111,7 @@ static const Key keys[] = { TAGKEYS( XK_9, 8) TAGKEYS( XK_0, 9) { MODKEY|ShiftMask, XK_q, quit, {0} }, + { 0, HOLDKEY, holdbar, {0} }, }; /* button definitions */ diff --git a/dwm.c b/dwm.c index a82e276..d6391f5 100644 --- a/dwm.c +++ b/dwm.c @@ -181,6 +181,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 keyrelease(XEvent *e); static void killclient(const Arg *arg); static void manage(Window w, XWindowAttributes *wa); static void mappingnotify(XEvent *e); @@ -214,6 +215,7 @@ static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *m); static void togglebar(const Arg *arg); +static void holdbar(const Arg *arg); static void togglefloating(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); @@ -221,6 +223,7 @@ static void unfocus(Client *c, int setfocus); static void unmanage(Client *c, int destroyed); static void unmapnotify(XEvent *e); static void updatebarpos(Monitor *m); +static void updateholdbarpos(Monitor *m); static void updatebars(void); static void updateclientlist(void); static int updategeom(void); @@ -250,6 +253,7 @@ static int (*xerrorxlib)(Display *, XErrorEvent *); static unsigned int numlockmask = 0; static void (*handler[LASTEvent]) (XEvent *) = { [ButtonPress] = buttonpress, + [ButtonRelease] = keyrelease, [ClientMessage] = clientmessage, [ConfigureRequest] = configurerequest, [ConfigureNotify] = configurenotify, @@ -257,6 +261,7 @@ static void (*handler[LASTEvent]) (XEvent *) = { [EnterNotify] = enternotify, [Expose] = expose, [FocusIn] = focusin, + [KeyRelease] = keyrelease, [KeyPress] = keypress, [MappingNotify] = mappingnotify, [MapRequest] = maprequest, @@ -285,6 +290,54 @@ static Colormap cmap; struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; /* function implementations */ +void +holdbar(const Arg *arg) +{ + if (selmon->showbar) + return; + selmon->showbar = 2; + updateholdbarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); +} + +void +keyrelease(XEvent *e) +{ + if (XEventsQueued(dpy, QueuedAfterReading)) { + XEvent ne; + XPeekEvent(dpy, &ne); + + if (ne.type == KeyPress && ne.xkey.time == e->xkey.time && + ne.xkey.keycode == e->xkey.keycode) { + XNextEvent(dpy, &ne); + return; + } + } + if (e->xkey.keycode == XKeysymToKeycode(dpy, HOLDKEY)) { + for (Monitor *m = mons; m; m = m->next) { + if (m->showbar == 2) { + m->showbar = 0; + updateholdbarpos(m); + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); + arrange(m); + } + } + } +} + +void +updateholdbarpos(Monitor *m) +{ + m->wy = m->my; + m->wh = m->mh; + if (m->showbar) { + m->by = m->topbar ? m->wy : m->wy + m->wh - bh; + m->wy = m->topbar ? m->wy - bh + bh : m->wy; + } else { + m->by = -bh; + } +} + void applyrules(Client *c) { @@ -469,7 +522,8 @@ buttonpress(XEvent *e) } for (i = 0; i < LENGTH(buttons); i++) if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) + && (CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state) + || CLEANMASK(((buttons[i].mask & ~MODKEY) | HOLDMOD)) == CLEANMASK(ev->state))) buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); } @@ -720,9 +774,6 @@ drawbar(Monitor *m) unsigned int i, occ = 0, urg = 0; Client *c; - if (!m->showbar) - return; - /* clear bar from last draw */ drw_setscheme(drw, scheme[SchemeNorm]); drw_rect(drw, 0, 0, m->ww, bh, lrpad / 2, 1); @@ -1031,7 +1082,8 @@ keypress(XEvent *e) keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); for (i = 0; i < LENGTH(keys); i++) if (keysym == keys[i].keysym - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) + && (CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) + || CLEANMASK(((keys[i].mod & ~MODKEY) | HOLDMOD)) == CLEANMASK(ev->state)) && keys[i].func) keys[i].func(&(keys[i].arg)); } @@ -1740,7 +1792,7 @@ tile(Monitor *m) void togglebar(const Arg *arg) { - selmon->showbar = !selmon->showbar; + selmon->showbar = (selmon->showbar == 2 ? 1 : !selmon->showbar); updatebarpos(selmon); XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); arrange(selmon); -- cgit v1.2.3