summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2024-02-26 15:20:38 -0500
committerMatt Hunter <m@lfurio.us>2026-01-18 00:18:27 -0500
commitae8a9fe600ac29c04e72e42a16052c67e203cb26 (patch)
treecaad2c061aa228979badedd8c6e9c4693af9fd01
parente780d94ea2baf22968391532ed1564a9ab728847 (diff)
downloaddwm-ae8a9fe600ac29c04e72e42a16052c67e203cb26.tar.gz
dwm-ae8a9fe600ac29c04e72e42a16052c67e203cb26.zip
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.
-rw-r--r--config.def.h7
-rw-r--r--dwm.c64
2 files changed, 63 insertions, 8 deletions
diff --git a/config.def.h b/config.def.h
index 13af0c4..abd464a 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";
@@ -54,6 +54,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 } }
@@ -75,7 +77,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 } },
@@ -105,6 +107,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 e82d8f1..89dfe06 100644
--- a/dwm.c
+++ b/dwm.c
@@ -180,6 +180,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);
@@ -213,6 +214,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);
@@ -220,6 +222,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);
@@ -249,6 +252,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,
@@ -256,6 +260,7 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[EnterNotify] = enternotify,
[Expose] = expose,
[FocusIn] = focusin,
+ [KeyRelease] = keyrelease,
[KeyPress] = keypress,
[MappingNotify] = mappingnotify,
[MapRequest] = maprequest,
@@ -284,6 +289,54 @@ 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)
{
const char *class, *instance;
@@ -467,7 +520,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);
}
@@ -718,9 +772,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);
@@ -1030,7 +1081,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);