dwm

my dwm build
Log | Files | Refs | LICENSE

commit 43791fd5edc5aa3bbb0928279af039962b0be9cd
parent 567e7cbaca2b37433e85f68fa9ac8f6d44abff56
Author: ssnf <ssnf@ssnf.xyz>
Date:   Wed, 21 Sep 2022 15:44:28 +0000

formatting and dynamic bar

Diffstat:
Mconfig.h | 7++++---
Mdwm.c | 1203++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Apatches/dwm-holdbar-modkey-6.2.diff | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 848 insertions(+), 508 deletions(-)

diff --git a/config.h b/config.h @@ -5,10 +5,10 @@ static const uint gappih = 4; /* horiz inner gap between windows */ static const uint gappiv = 4; /* vert inner gap between windows */ static const uint gappoh = 4; /* horiz outer gap between windows and screen edge */ static const uint gappov = 4; /* vert outer gap between windows and screen edge */ -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 int vertpad = 7; /* vertical padding of bar */ -static const int sidepad = 7; /* horizontal padding of bar */ +static const int vertpad = 4; /* vertical padding of bar */ +static const int sidepad = 4; /* horizontal padding of bar */ static const char* fonts[] = { "hack:size=12" }; static const char col_fg[] = "#454138"; static const char col_bg[] = "#d1cdb7"; @@ -131,6 +131,7 @@ static Key keys[] = { { MOD|SHIFT, XK_period, tagmon, {.i = +1 } }, { MOD|SHIFT, XK_q, quit, {0} }, { MOD|CTRL|SHIFT, XK_q, spawn, {.v = stopdwm} }, + { 0, XK_Super_L, NULL, {0} }, TAGKEYS( XK_1, 0) TAGKEYS( XK_2, 1) TAGKEYS( XK_3, 2) diff --git a/dwm.c b/dwm.c @@ -29,7 +29,8 @@ #define CLEANMASK(mask) \ ( \ mask & ~(numlockmask | LockMask) & \ - (ShiftMask | ControlMask | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)) + (ShiftMask | ControlMask | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask \ + | Mod5Mask)) #define INTERSECT(x, y, w, h, m) \ ( \ MAX(0, MIN((x) + (w), (m)->wx + (m)->ww) - MAX((x), (m)->wx)) * \ @@ -46,121 +47,122 @@ /* enums */ enum { /* cursor */ - CurNormal, - CurResize, - CurMove, - CurLast + CurNormal, + CurResize, + CurMove, + CurLast }; enum { /* color schemes */ - SchemeNorm, - SchemeSel + SchemeNorm, + SchemeSel }; enum { /* EWMH atoms */ - NetSupported, - NetWMName, - NetWMState, - NetWMCheck, - NetWMFullscreen, - NetActiveWindow, - NetWMWindowType, - NetWMWindowTypeDialog, - NetClientList, - NetLast + NetSupported, + NetWMName, + NetWMState, + NetWMCheck, + NetWMFullscreen, + NetActiveWindow, + NetWMWindowType, + NetWMWindowTypeDialog, + NetClientList, + NetLast }; enum { /* default atoms */ - WMProtocols, - WMDelete, - WMState, - WMTakeFocus, - WMLast + WMProtocols, + WMDelete, + WMState, + WMTakeFocus, + WMLast }; enum { /* clicks */ - ClkTagBar, - ClkLtSymbol, - ClkStatusText, - ClkWinTitle, - ClkClientWin, - ClkRootWin, - ClkLast + ClkTagBar, + ClkLtSymbol, + ClkStatusText, + ClkWinTitle, + ClkClientWin, + ClkRootWin, + ClkLast }; typedef union { - int i; - uint ui; - float f; - const void* v; + int i; + uint ui; + float f; + const void* v; } Arg; typedef struct { - uint click; - uint mask; - uint button; - void (*func)(const Arg* arg); + uint click; + uint mask; + uint button; + void (*func)(const Arg* arg); const Arg arg; } Button; typedef struct Client { - char name[256]; - float mina, maxa; - int x, y, w, h; - int oldx, oldy, oldw, oldh; - int basew, baseh, incw, inch, maxw, maxh, minw, minh; - int bw, oldbw; - uint tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow; - pid_t pid; - struct Client* next; - struct Client* snext; - struct Client* swallowing; + char name[256]; + float mina, maxa; + int x, y, w, h; + int oldx, oldy, oldw, oldh; + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; + uint tags; + int isfixed, isfloating, isurgent, neverfocus, oldstate; + int isfullscreen, isterminal, noswallow; + pid_t pid; + struct Client* next; + struct Client* snext; + struct Client* swallowing; struct Monitor* mon; - Window win; + Window win; } Client; typedef struct { - uint mod; - KeySym keysym; - void (*func)(const Arg*); + uint mod; + KeySym keysym; + void (*func)(const Arg*); const Arg arg; } Key; typedef struct { const char* symbol; - void (*arrange)(struct Monitor*); + void (*arrange)(struct Monitor*); } Layout; typedef struct Monitor { - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - int gappih; /* horizontal gap between windows */ - int gappiv; /* vertical gap between windows */ - int gappoh; /* horizontal outer gaps */ - int gappov; /* vertical outer gaps */ - uint seltags; - uint sellt; - uint tagset[2]; - int showbar; - int topbar; - Client* clients; - Client* sel; - Client* stack; - struct Monitor* next; - Window barwin; - const Layout* lt[2]; + float mfact; + int nmaster; + int num; + int by; /* bar geometry */ + int mx, my, mw, mh; /* screen size */ + int wx, wy, ww, wh; /* window area */ + int gappih; /* horizontal gap between windows */ + int gappiv; /* vertical gap between windows */ + int gappoh; /* horizontal outer gaps */ + int gappov; /* vertical outer gaps */ + uint seltags; + uint sellt; + uint tagset[2]; + int showbar; + int topbar; + Client* clients; + Client* sel; + Client* stack; + struct Monitor* next; + Window barwin; + const Layout* lt[2]; } Monitor; typedef struct { const char* class; - const char* instance; - const char* title; - uint tags; - int isfloating; - int isterminal; - int noswallow; - int monitor; + const char* instance; + const char* title; + uint tags; + int isfloating; + int isterminal; + int noswallow; + int monitor; } Rule; /* function declarations */ @@ -199,6 +201,7 @@ static int gettextprop(Window w, Atom atom, char* text, uint size); static void grabbuttons(Client* c, int focused); static void grabkeys(void); 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); @@ -238,6 +241,7 @@ static void toggleview(const Arg* arg); static void unfocus(Client* c, int setfocus); static void unmanage(Client* c, int destroyed); static void unmapnotify(XEvent* e); +static void updatebar(void); static void updatebarpos(Monitor* m); static void updatebars(void); static void updateclientlist(void); @@ -266,18 +270,19 @@ static pid_t winpid(Window w); /* variables */ static const char broken[] = "broken"; -static char stext[256]; -static int scanner; -static int screen; -static int sw, sh; /* X display screen geometry width, height */ -static int bh, blw = 0; /* bar geometry */ -static int lrpad; /* sum of left and right padding for text */ -static int vp; /* vertical padding for bar */ -static int sp; /* side padding for bar */ +static char stext[256]; +static int scanner; +static int screen; +static int sw, sh; /* X display screen geometry width, height */ +static int bh, blw = 0; /* bar geometry */ +static int lrpad; /* sum of left and right padding for text */ +static int vp; /* vertical padding for bar */ +static int sp; /* side padding for bar */ static int (*xerrorxlib)(Display*, XErrorEvent*); -static uint numlockmask = 0; +static uint numlockmask = 0; static void (*handler[LASTEvent])(XEvent*) = { [ButtonPress] = buttonpress, + [ButtonRelease] = keyrelease, [ClientMessage] = clientmessage, [ConfigureRequest] = configurerequest, [ConfigureNotify] = configurenotify, @@ -285,6 +290,7 @@ static void (*handler[LASTEvent])(XEvent*) = { [EnterNotify] = enternotify, [Expose] = expose, [FocusIn] = focusin, + [KeyRelease] = keyrelease, [KeyPress] = keypress, [MappingNotify] = mappingnotify, [MapRequest] = maprequest, @@ -298,7 +304,7 @@ static Cur* cursor[CurLast]; static Color** scheme; static Display* dpy; static Drw* drw; -static Monitor *mons, *selmon; +static Monitor* mons, *selmon; static Window root, wmcheckwin; static xcb_connection_t* xcon; @@ -316,6 +322,30 @@ struct NumTags { }; /* function implementations */ + +void +keyrelease(XEvent* e) +{ + XEvent ev; + + if (e->xkey.keycode != XKeysymToKeycode(dpy, XK_Super_L)) + return; + if (XEventsQueued(dpy, QueuedAfterReading)) { + XPeekEvent(dpy, &ev); + if (ev.type == KeyPress + && ev.xkey.time == e->xkey.time + && ev.xkey.keycode == e->xkey.keycode + ) { + XNextEvent(dpy, &ev); + return; + } + } + if (selmon->showbar == 1) { + selmon->showbar = 0; + updatebar(); + } +} + void swallow(Client* p, Client* c) { @@ -327,11 +357,11 @@ swallow(Client* p, Client* c) detachstack(c); setclientstate(c, WithdrawnState); XUnmapWindow(dpy, p->win); - p->swallowing = c; - c->mon = p->mon; - win = p->win; - p->win = c->win; - c->win = win; + p->swallowing = c; + c->mon = p->mon; + win = p->win; + p->win = c->win; + c->win = win; updatetitle(p); XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h); arrange(p->mon); @@ -361,28 +391,30 @@ unswallow(Client* c) void applyrules(Client* c) { - const char* class, *instance; - uint i; - const Rule* r; - Monitor* m; - XClassHint ch = { NULL, NULL }; + const char* class, *instance; + uint i; + const Rule* r; + Monitor* m; + XClassHint ch = { NULL, NULL }; /* rule matching */ - c->isfloating = 0; - c->isterminal = 0; - c->noswallow = 0; - c->tags = 0; + c->isfloating = 0; + c->isterminal = 0; + c->noswallow = 0; + c->tags = 0; XGetClassHint(dpy, c->win, &ch); - class = ch.res_class ? ch.res_class : broken; + class = ch.res_class ? ch.res_class : broken; instance = ch.res_name ? ch.res_name : broken; for (i = 0; i < LENGTH(rules); i++) { r = &rules[i]; if ( - (!r->title || strstr(c->name, r->title)) && (!r->class || strstr(class, r->class)) && - (!r->instance || strstr(instance, r->instance))) { + (!r->title || strstr(c->name, r->title)) + && (!r->class || strstr(class, r->class)) + && (!r->instance || strstr(instance, r->instance)) + ) { c->isterminal = r->isterminal; - c->noswallow = r->noswallow; + c->noswallow = r->noswallow; c->isfloating = r->isfloating; c->tags |= r->tags; for (m = mons; m && m->num != r->monitor; m = m->next); @@ -394,14 +426,18 @@ applyrules(Client* c) XFree(ch.res_class); if (ch.res_name) XFree(ch.res_name); - c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; + c->tags = c->tags & TAGMASK + ? c->tags & TAGMASK + : c->mon->tagset[c->mon->seltags]; } -int applysizehints(Client* c, int* x, int* y, int* w, int* h, int interact) +int +applysizehints(Client* c, int* x, int* y, int* w, int* h, int interact) { - int baseismin; - Monitor* m = c->mon; + int baseismin; + Monitor* m; + m = c->mon; /* set minimum possible */ *w = MAX(1, *w); *h = MAX(1, *h); @@ -416,8 +452,10 @@ int applysizehints(Client* c, int* x, int* y, int* w, int* h, int interact) if (*x + *w + 2 * c->bw <= m->wx) *x = m->wx; if (*y + *h + 2 * c->bw <= m->wy) *y = m->wy; } - if (*h < bh) *h = bh; - if (*w < bh) *w = bh; + if (*h < bh) + *h = bh; + if (*w < bh) + *w = bh; if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { /* see last two sentences in ICCCM 4.1.2.3 */ baseismin = c->basew == c->minw && c->baseh == c->minh; @@ -427,7 +465,8 @@ int applysizehints(Client* c, int* x, int* y, int* w, int* h, int interact) } /* adjust for aspect limits */ if (c->mina > 0 && c->maxa > 0) { - if (c->maxa < (float)*w / *h) *w = *h * c->maxa + 0.5; + if (c->maxa < (float)*w / *h) + *w = *h * c->maxa + 0.5; else if (c->mina < (float)*h / *w) *h = *w * c->mina + 0.5; } @@ -436,13 +475,17 @@ int applysizehints(Client* c, int* x, int* y, int* w, int* h, int interact) *h -= c->baseh; } /* adjust for increment value */ - if (c->incw) *w -= *w % c->incw; - if (c->inch) *h -= *h % c->inch; + if (c->incw) + *w -= *w % c->incw; + if (c->inch) + *h -= *h % c->inch; /* restore base dimensions */ *w = MAX(*w + c->basew, c->minw); *h = MAX(*h + c->baseh, c->minh); - if (c->maxw) *w = MIN(*w, c->maxw); - if (c->maxh) *h = MIN(*h, c->maxh); + if (c->maxw) + *w = MIN(*w, c->maxw); + if (c->maxh) + *h = MIN(*h, c->maxh); } return *x != c->x || *y != c->y || *w != c->w || *h != c->h; } @@ -473,24 +516,24 @@ arrangemon(Monitor* m) void attach(Client* c) { - c->next = c->mon->clients; + c->next = c->mon->clients; c->mon->clients = c; } void attachstack(Client* c) { - c->snext = c->mon->stack; + c->snext = c->mon->stack; c->mon->stack = c; } void buttonpress(XEvent* e) { - uint i, x, click; - Arg arg = { 0 }; - Client* c; - Monitor* m; + uint i, x, click; + Arg arg = { 0 }; + Client* c; + Monitor* m; XButtonPressedEvent* ev = &e->xbutton; click = ClkRootWin; @@ -528,9 +571,16 @@ 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)) - buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); + click == buttons[i].click + && buttons[i].func + && buttons[i].button == ev->button + && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state) + ) + buttons[i].func( + click == ClkTagBar && buttons[i].arg.i == 0 + ? &arg + : &buttons[i].arg + ); } void @@ -547,10 +597,10 @@ checkotherwm(void) void cleanup(void) { - Arg a = { .ui = ~0 }; - Layout foo = { "", NULL }; + Arg a = { .ui = ~0 }; + Layout foo = { "", NULL }; Monitor* m; - size_t i; + size_t i; view(&a); selmon->lt[selmon->sellt] = &foo; @@ -579,8 +629,7 @@ cleanupmon(Monitor* mon) if (mon == mons) mons = mons->next; else { - for (m = mons; m && m->next != mon; m = m->next) - ; + for (m = mons; m && m->next != mon; m = m->next); m->next = mon->next; } XUnmapWindow(dpy, mon->barwin); @@ -591,20 +640,25 @@ cleanupmon(Monitor* mon) void clientmessage(XEvent* e) { - XClientMessageEvent* cme = &e->xclient; - Client* c = wintoclient(cme->window); + XClientMessageEvent* cme; + Client* c; + cme = &e->xclient; + c = wintoclient(cme->window); if (!c) return; if (cme->message_type == netatom[NetWMState]) { - if (cme->data.l[1] == netatom[NetWMFullscreen] || cme->data.l[2] == netatom[NetWMFullscreen]) - setfullscreen(c, ( - cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ || - (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); - } else if (cme->message_type == netatom[NetActiveWindow]) { + if (cme->data.l[1] == netatom[NetWMFullscreen] + || cme->data.l[2] == netatom[NetWMFullscreen] + ) + setfullscreen(c, + cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ + || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ + && !c->isfullscreen) + ); + } else if (cme->message_type == netatom[NetActiveWindow]) if (c != selmon->sel && !c->isurgent) seturgent(c, 1); - } } void @@ -612,16 +666,16 @@ configure(Client* c) { XConfigureEvent ce; - ce.type = ConfigureNotify; - ce.display = dpy; - ce.event = c->win; - ce.window = c->win; - ce.x = c->x; - ce.y = c->y; - ce.width = c->w; - ce.height = c->h; - ce.border_width = c->bw; - ce.above = None; + ce.type = ConfigureNotify; + ce.display = dpy; + ce.event = c->win; + ce.window = c->win; + ce.x = c->x; + ce.y = c->y; + ce.width = c->w; + ce.height = c->h; + ce.border_width = c->bw; + ce.above = None; ce.override_redirect = False; XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent*)&ce); } @@ -629,16 +683,17 @@ configure(Client* c) void configurenotify(XEvent* e) { - Monitor* m; - Client* c; - XConfigureEvent* ev = &e->xconfigure; - int dirty; + Monitor* m; + Client* c; + XConfigureEvent* ev; + int dirty; /* TODO: updategeom handling sucks, needs to be simplified */ + ev = &e->xconfigure; if (ev->window == root) { dirty = (sw != ev->width || sh != ev->height); - sw = ev->width; - sh = ev->height; + sw = ev->width; + sh = ev->height; if (updategeom() || dirty) { drw_resize(drw, sw, bh); updatebars(); @@ -646,7 +701,9 @@ configurenotify(XEvent* e) for (c = m->clients; c; c = c->next) if (c->isfullscreen) resizeclient(c, m->mx, m->my, m->mw, m->mh); - XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh); + XMoveResizeWindow( + dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh + ); } focus(NULL); arrange(NULL); @@ -657,11 +714,12 @@ configurenotify(XEvent* e) void configurerequest(XEvent* e) { - Client* c; - Monitor* m; - XConfigureRequestEvent* ev = &e->xconfigurerequest; - XWindowChanges wc; + Client* c; + Monitor* m; + XConfigureRequestEvent* ev; + XWindowChanges wc; + ev = &e->xconfigurerequest; if ((c = wintoclient(ev->window))) { if (ev->value_mask & CWBorderWidth) c->bw = ev->border_width; @@ -687,20 +745,22 @@ configurerequest(XEvent* e) c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ if ((c->y + c->h) > m->my + m->mh && c->isfloating) c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ - if ((ev->value_mask & (CWX | CWY)) && !(ev->value_mask & (CWWidth | CWHeight))) + if ((ev->value_mask & (CWX | CWY)) + && !(ev->value_mask & (CWWidth | CWHeight)) + ) configure(c); if (ISVISIBLE(c)) XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); } else configure(c); } else { - wc.x = ev->x; - wc.y = ev->y; - wc.width = ev->width; - wc.height = ev->height; + wc.x = ev->x; + wc.y = ev->y; + wc.width = ev->width; + wc.height = ev->height; wc.border_width = ev->border_width; - wc.sibling = ev->above; - wc.stack_mode = ev->detail; + wc.sibling = ev->above; + wc.stack_mode = ev->detail; XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); } XSync(dpy, False); @@ -711,27 +771,28 @@ createmon() { Monitor* m; - m = ecalloc(1, sizeof(Monitor)); + m = ecalloc(1, sizeof(Monitor)); m->tagset[0] = m->tagset[1] = 1; - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; + m->mfact = mfact; + m->nmaster = nmaster; + m->showbar = showbar; + m->topbar = topbar; m->gappih = gappih; m->gappiv = gappiv; m->gappoh = gappoh; m->gappov = gappov; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; return m; } void destroynotify(XEvent* e) { - Client* c; - XDestroyWindowEvent* ev = &e->xdestroywindow; + Client* c; + XDestroyWindowEvent* ev; + ev = &e->xdestroywindow; if ((c = wintoclient(ev->window))) unmanage(c, 1); else if ((c = swallowingclient(ev->window))) @@ -743,8 +804,7 @@ detach(Client* c) { Client** tc; - for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next) - ; + for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next) ; *tc = c->next; } @@ -753,10 +813,8 @@ detachstack(Client* c) { Client **tc, *t; - for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext) - ; + for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); *tc = c->snext; - if (c == c->mon->sel) { for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); c->mon->sel = t; @@ -765,27 +823,26 @@ detachstack(Client* c) Monitor* dirtomon(int dir) { - Monitor* m = NULL; + Monitor* m; + m = NULL; if (dir > 0) { if (!(m = selmon->next)) m = mons; } else if (selmon == mons) - for (m = mons; m->next; m = m->next) - ; + for (m = mons; m->next; m = m->next); else - for (m = mons; m->next != selmon; m = m->next) - ; + for (m = mons; m->next != selmon; m = m->next); return m; } void drawbar(Monitor* m) { - int x, w, tw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; - uint i, occ = 0, urg = 0; + int x, w, tw = 0; + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; + uint i, occ = 0, urg = 0; Client* c; /* draw status first so it can be overdrawn by tags later */ @@ -797,17 +854,25 @@ drawbar(Monitor* m) for (c = m->clients; c; c = c->next) { occ |= c->tags; - if (c->isurgent) urg |= c->tags; + if (c->isurgent) + urg |= c->tags; } x = 0; for (i = 0; i < LENGTH(tags); i++) { if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) continue; w = TEXTW(tags[i]); - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); + drw_setscheme( + drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm] + ); drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); +/* if (occ & 1 << i) - drw_rect(drw, x + boxs, boxs, boxw, boxw, m == selmon && selmon->sel && selmon->sel->tags & 1 << i, urg & 1 << i); + drw_rect(drw, x + boxs, boxs, boxw, boxw, + m == selmon && selmon->sel && selmon->sel->tags & 1 << i, + urg & 1 << i + ); +*/ x += w; } drw_setscheme(drw, scheme[SchemeNorm]); @@ -818,7 +883,10 @@ drawbar(Monitor* m) if (TEXTW(m->sel->name) > w) drw_text(drw, x, 0, w - 2 * sp, bh, lrpad / 2, m->sel->name, 0); else - drw_text(drw, x, 0, w - 2 * sp, bh, (w - TEXTW(m->sel->name)) / 2, m->sel->name, 0); + drw_text( + drw, x, 0, w - 2 * sp, bh, (w - TEXTW(m->sel->name)) / 2, + m->sel->name, 0 + ); if (m->sel->isfloating) drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); } else { @@ -841,11 +909,14 @@ drawbars(void) void enternotify(XEvent* e) { - Client* c; - Monitor* m; - XCrossingEvent* ev = &e->xcrossing; + Client* c; + Monitor* m; + XCrossingEvent* ev; - if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) + ev = &e->xcrossing; + if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) + && ev->window != root + ) return; c = wintoclient(ev->window); m = c ? c->mon : wintomon(ev->window); @@ -860,9 +931,10 @@ enternotify(XEvent* e) void expose(XEvent* e) { - Monitor* m; - XExposeEvent* ev = &e->xexpose; + Monitor* m; + XExposeEvent* ev; + ev = &e->xexpose; if (ev->count == 0 && (m = wintomon(ev->window))) drawbar(m); } @@ -887,7 +959,8 @@ fibonacci(Monitor* m) for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) { if (r) { if ((i % 2 && (ch - m->gappih) / 2 <= (bh + 2 * c->bw)) - || (!(i % 2) && (cw - m->gappiv) / 2 <= (bh + 2 * c->bw))) + || (!(i % 2) && (cw - m->gappiv) / 2 <= (bh + 2 * c->bw)) + ) r = 0; if (r && i < n - 1) { if (i % 2) { @@ -901,7 +974,10 @@ fibonacci(Monitor* m) } } switch (i % 4) { - case 0: + case 2: + if (i < n - 1) + cw += wrest; + case 0: /*fallthrough */ cy += ch + m->gappih; ch += hrest; break; @@ -909,12 +985,6 @@ fibonacci(Monitor* m) cx += cw + m->gappiv; cw += wrest; break; - case 2: - cy += ch + m->gappih; - ch += hrest; - if (i < n - 1) - cw += wrest; - break; case 3: cx += cw + m->gappiv; cw -= wrest; @@ -941,13 +1011,14 @@ void focus(Client* c) { if (!c || !ISVISIBLE(c)) - for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext) - ; + for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); if (selmon->sel && selmon->sel != c) unfocus(selmon->sel, 0); if (c) { - if (c->mon != selmon) selmon = c->mon; - if (c->isurgent) seturgent(c, 0); + if (c->mon != selmon) + selmon = c->mon; + if (c->isurgent) + seturgent(c, 0); detachstack(c); attachstack(c); grabbuttons(c, 1); @@ -965,8 +1036,9 @@ focus(Client* c) void focusin(XEvent* e) { - XFocusChangeEvent* ev = &e->xfocus; + XFocusChangeEvent* ev; + ev = &e->xfocus; if (selmon->sel && ev->window != selmon->sel->win) setfocus(selmon->sel); } @@ -988,32 +1060,34 @@ focusmon(const Arg* arg) void focusstack(const Arg* arg) { - Client *c = NULL, *i; + Client* c, *i; if (!selmon->sel) return; if (arg->i > sizeof(arg)) return; + c = NULL; if (arg->i > 0) { - for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next) - ; + for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); if (!c) - for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next) - ; + for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); } else { for (i = selmon->clients; i != selmon->sel; i = i->next) - if (ISVISIBLE(i)) c = i; - if (!c) + if (ISVISIBLE(i)) + c = i; + if (c == NULL) for (; i; i = i->next) - if (ISVISIBLE(i)) c = i; + if (ISVISIBLE(i)) + c = i; } - if (c) { + if (c != NULL) { focus(c); restack(selmon); } } -Atom getatomprop(Client* c, Atom prop) +Atom +getatomprop(Client* c, Atom prop) { int di; unsigned long dl; @@ -1022,57 +1096,63 @@ Atom getatomprop(Client* c, Atom prop) p = NULL; atom = None; - if ( - XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, &da, &di, &dl, &dl, &p) == Success && p) { + if (XGetWindowProperty( + dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, &da, &di, &dl, &dl, &p + ) == Success && p + ) { atom = *(Atom*)p; XFree(p); } return atom; } -int getrootptr(int* x, int* y) +int +getrootptr(int* x, int* y) { - int di; - uint dui; - Window dummy; + Window dummy; + uint dui; + int di; return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); } -long getstate(Window w) +long +getstate(Window w) { - int format; - long result = -1; - uchar* p = NULL; - unsigned long n, extra; - Atom real; + Atom real; + uchar* p; + ulong n, null; + long r; - if ( - XGetWindowProperty( - dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], &real, &format, &n, &extra, (uchar**)&p) != - Success) + if (XGetWindowProperty( + dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], &real, (int*)&null, + &n, &null, (uchar**)&p + ) != Success + ) return -1; - if (n != 0) - result = *p; + r = n ? *p : -1; XFree(p); - return result; + return r; } -int gettextprop(Window w, Atom atom, char* text, uint size) +int +gettextprop(Window w, Atom atom, char* text, uint size) { - char** list = NULL; - int n; + char** list = NULL; + int n; XTextProperty name; - if (!text || size == 0) + if (text == NULL || !size) return 0; text[0] = '\0'; - if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) + if (!XGetTextProperty(dpy, w, &name, atom)) + return 0; + if (!name.nitems) return 0; if (name.encoding == XA_STRING) strncpy(text, (char*)name.value, size - 1); - else { - if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { + else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success) { + if (n > 0 && *list) { strncpy(text, *list, size - 1); XFreeStringList(list); } @@ -1089,15 +1169,20 @@ grabbuttons(Client* c, int focused) { uint i, j; uint modifiers[] = { 0, LockMask, numlockmask, numlockmask | LockMask }; + XUngrabButton(dpy, AnyButton, AnyModifier, c->win); if (!focused) - XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, BUTTONMASK, GrabModeSync, GrabModeSync, None, None); + XGrabButton( + dpy, AnyButton, AnyModifier, c->win, False, BUTTONMASK, GrabModeSync, + GrabModeSync, None, None + ); for (i = 0; i < LENGTH(buttons); i++) if (buttons[i].click == ClkClientWin) for (j = 0; j < LENGTH(modifiers); j++) XGrabButton( - dpy, buttons[i].button, buttons[i].mask | modifiers[j], c->win, False, BUTTONMASK, GrabModeAsync, - GrabModeSync, None, None); + dpy, buttons[i].button, buttons[i].mask | modifiers[j], c->win, + False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None + ); } } @@ -1106,26 +1191,31 @@ grabkeys(void) { updatenumlockmask(); { - uint i, j; - uint modifiers[] = { 0, LockMask, numlockmask, numlockmask | LockMask }; - KeyCode code; + uint i, j; + uint modifiers[] = { 0, LockMask, numlockmask, numlockmask | LockMask }; + KeyCode code; XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < LENGTH(keys); i++) + for (i = 0; i < LENGTH(keys); ++i) if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, True, GrabModeAsync, GrabModeAsync); + for (j = 0; j < LENGTH(modifiers); ++j) + XGrabKey( + dpy, code, keys[i].mod | modifiers[j], root, True, GrabModeAsync, + GrabModeAsync + ); } } #ifdef XINERAMA -static int isuniquegeom(XineramaScreenInfo* unique, size_t n, XineramaScreenInfo* info) +static int +isuniquegeom(XineramaScreenInfo* unique, size_t n, XineramaScreenInfo* info) { for (;n--;) - if (unique[n].x_org == info->x_org && - unique[n].y_org == info->y_org && - unique[n].width == info->width && - unique[n].height == info->height) + if (unique[n].x_org == info->x_org + && unique[n].y_org == info->y_org + && unique[n].width == info->width + && unique[n].height == info->height + ) return 0; return 1; } @@ -1138,10 +1228,13 @@ keypress(XEvent* e) KeySym keysym; XKeyEvent* ev; - ev = &e->xkey; + ev = &e->xkey; 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) && keys[i].func) + if (keysym == keys[i].keysym + && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) + && keys[i].func + ) keys[i].func(&(keys[i].arg)); } @@ -1164,22 +1257,23 @@ killclient(const Arg* arg) void manage(Window w, XWindowAttributes* wa) { - Client *c, *t, *term; - Window trans = None; + Client* c, *t, *term; + Window trans; XWindowChanges wc; - t = NULL; - term = NULL; - c = ecalloc(1, sizeof(Client)); - c->win = w; - c->pid = winpid(w); + t = NULL; + term = NULL; + c = ecalloc(1, sizeof(Client)); + c->win = w; + c->pid = winpid(w); /* geometry */ c->x = c->oldx = wa->x; c->y = c->oldy = wa->y; c->w = c->oldw = wa->width; c->h = c->oldh = wa->height; - c->oldbw = wa->border_width; + c->oldbw = wa->border_width; + trans = None; updatetitle(c); if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { c->mon = t->mon; @@ -1189,20 +1283,19 @@ manage(Window w, XWindowAttributes* wa) applyrules(c); term = termforwin(c); } - if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) c->x = c->mon->mx + c->mon->mw - WIDTH(c); if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) c->y = c->mon->my + c->mon->mh - HEIGHT(c); c->x = MAX(c->x, c->mon->mx); /* only fix client y-offset, if the client center might cover the bar */ - c->y = MAX( - c->y, - ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) - ? bh - : c->mon->my); + c->y = MAX(c->y, + ((c->mon->by == c->mon->my) + && (c->x + (c->w / 2) >= c->mon->wx) + && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww) + ) ? bh : c->mon->my + ); c->bw = borderpx; - wc.border_width = c->bw; XConfigureWindow(dpy, w, CWBorderWidth, &wc); XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); @@ -1210,7 +1303,10 @@ manage(Window w, XWindowAttributes* wa) updatewindowtype(c); updatesizehints(c); updatewmhints(c); - XSelectInput(dpy, w, EnterWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask); + XSelectInput( + dpy, w, + EnterWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask + ); grabbuttons(c, 0); if (!c->isfloating) c->isfloating = c->oldstate = trans != None || c->isfixed; @@ -1218,7 +1314,10 @@ manage(Window w, XWindowAttributes* wa) XRaiseWindow(dpy, c->win); attach(c); attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, (uchar*)&(c->win), 1); + XChangeProperty( + dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, + (uchar*)&(c->win), 1 + ); XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ setclientstate(c, NormalState); if (c->mon == selmon) @@ -1234,8 +1333,9 @@ manage(Window w, XWindowAttributes* wa) void mappingnotify(XEvent* e) { - XMappingEvent* ev = &e->xmapping; + XMappingEvent* ev; + ev = &e->xmapping; XRefreshKeyboardMapping(ev); if (ev->request == MappingKeyboard) grabkeys(); @@ -1245,8 +1345,9 @@ void maprequest(XEvent* e) { static XWindowAttributes wa; - XMapRequestEvent* ev = &e->xmaprequest; + XMapRequestEvent* ev; + ev = &e->xmaprequest; if (!XGetWindowAttributes(dpy, ev->window, &wa)) return; if (wa.override_redirect) @@ -1259,9 +1360,10 @@ void motionnotify(XEvent* e) { static Monitor* mon = NULL; - Monitor* m; - XMotionEvent* ev = &e->xmotion; + Monitor* m; + XMotionEvent* ev; + ev = &e->xmotion; if (ev->window != root) return; if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { @@ -1275,11 +1377,12 @@ motionnotify(XEvent* e) void movemouse(const Arg* arg) { - int x, y, ocx, ocy, nx, ny; - Client* c; + int x, y, ocx, ocy, nx, ny; + Client* c; Monitor* m; - XEvent ev; - Time lasttime = 0; + XEvent ev; + Time lasttime; + if (!(c = selmon->sel)) return; @@ -1288,19 +1391,23 @@ movemouse(const Arg* arg) restack(selmon); ocx = c->x; ocy = c->y; - if ( - XGrabPointer( - dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, cursor[CurMove]->cursor, CurrentTime) != - GrabSuccess) + if (XGrabPointer( + dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, + cursor[CurMove]->cursor, CurrentTime + ) != GrabSuccess + ) return; if (!getrootptr(&x, &y)) return; + lasttime = 0; do { XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); switch (ev.type) { case ConfigureRequest: case Expose: - case MapRequest: handler[ev.type](&ev); break; + case MapRequest: + handler[ev.type](&ev); + break; case MotionNotify: if ((ev.xmotion.time - lasttime) <= (1000 / 60)) continue; @@ -1312,12 +1419,13 @@ movemouse(const Arg* arg) nx = selmon->wx; else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap) nx = selmon->wx + selmon->ww - WIDTH(c); - if (abs(selmon->wy - ny) < snap) ny = selmon->wy; + if (abs(selmon->wy - ny) < snap) + ny = selmon->wy; else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) ny = selmon->wy + selmon->wh - HEIGHT(c); - if ( - !c->isfloating && selmon->lt[selmon->sellt]->arrange && - (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange + && (abs(nx - c->x) > snap || abs(ny - c->y) > snap) + ) togglefloating(NULL); if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) resize(c, nx, ny, c->w, c->h, 1); @@ -1332,10 +1440,10 @@ movemouse(const Arg* arg) } } -Client* nexttiled(Client* c) +Client* +nexttiled(Client* c) { - for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next) - ; + for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); return c; } @@ -1351,24 +1459,29 @@ pop(Client* c) void propertynotify(XEvent* e) { - Client* c; - Window trans; - XPropertyEvent* ev = &e->xproperty; + XPropertyEvent* ev; + Client* c; + Window trans; + ev = &e->xproperty; if ((ev->window == root) && (ev->atom == XA_WM_NAME)) updatestatus(); else if (ev->state == PropertyDelete) return; else if ((c = wintoclient(ev->window))) { switch (ev->atom) { - default: break; + default: + break; case XA_WM_TRANSIENT_FOR: - if ( !c->isfloating && - (XGetTransientForHint(dpy, c->win, &trans)) && - (c->isfloating = (wintoclient(trans)) != NULL)) + if (!c->isfloating && + (XGetTransientForHint(dpy, c->win, &trans)) + && (c->isfloating = (wintoclient(trans)) != NULL) + ) arrange(c->mon); break; - case XA_WM_NORMAL_HINTS: updatesizehints(c); break; + case XA_WM_NORMAL_HINTS: + updatesizehints(c); + break; case XA_WM_HINTS: updatewmhints(c); drawbars(); @@ -1390,15 +1503,18 @@ quit(const Arg* arg) running = 0; } -Monitor* recttomon(int x, int y, int w, int h) +Monitor* +recttomon(int x, int y, int w, int h) { - Monitor *m, *r = selmon; - int a, area = 0; + Monitor* m, *r; + int a, area; + r = selmon; + area = 0; for (m = mons; m; m = m->next) if ((a = INTERSECT(x, y, w, h, m)) > area) { area = a; - r = m; + r = m; } return r; } @@ -1417,13 +1533,13 @@ resizeclient(Client* c, int x, int y, int w, int h) c->oldx = c->x; c->x = wc.x = x; - c->oldy = c->y; + c->oldy = c->y; c->y = wc.y = y; - c->oldw = c->w; + c->oldw = c->w; c->w = wc.width = w; - c->oldh = c->h; + c->oldh = c->h; c->h = wc.height = h; - wc.border_width = c->bw; + wc.border_width = c->bw; XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc); configure(c); XSync(dpy, False); @@ -1432,11 +1548,11 @@ resizeclient(Client* c, int x, int y, int w, int h) void resizemouse(const Arg* arg) { - int ocx, ocy, nw, nh; - Client* c; + int ocx, ocy, nw, nh; + Client* c; Monitor* m; - XEvent ev; - Time lasttime = 0; + XEvent ev; + Time lasttime; if (!(c = selmon->sel)) return; @@ -1445,30 +1561,37 @@ resizemouse(const Arg* arg) restack(selmon); ocx = c->x; ocy = c->y; - if ( - XGrabPointer( - dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, cursor[CurResize]->cursor, CurrentTime) != - GrabSuccess) + if (XGrabPointer( + dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, + cursor[CurResize]->cursor, CurrentTime + ) != GrabSuccess + ) return; XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); + lasttime = 0; do { XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); switch (ev.type) { case ConfigureRequest: case Expose: - case MapRequest: handler[ev.type](&ev); break; + case MapRequest: + handler[ev.type](&ev); + break; case MotionNotify: - if ((ev.xmotion.time - lasttime) <= (1000 / 60)) continue; + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; lasttime = ev.xmotion.time; nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); - if ( - c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww && - c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh) { - if ( - !c->isfloating && selmon->lt[selmon->sellt]->arrange && - (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) + if (c->mon->wx + nw >= selmon->wx + && c->mon->wx + nw <= selmon->wx + selmon->ww + && c->mon->wy + nh >= selmon->wy + && c->mon->wy + nh <= selmon->wy + selmon->wh + ) { + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange + && (abs(nw - c->w) > snap || abs(nh - c->h) > snap) + ) togglefloating(NULL); } if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) @@ -1478,8 +1601,7 @@ resizemouse(const Arg* arg) } while (ev.type != ButtonRelease); XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); XUngrabPointer(dpy, CurrentTime); - while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)) - ; + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { sendmon(c, m); selmon = m; @@ -1490,8 +1612,8 @@ resizemouse(const Arg* arg) void restack(Monitor* m) { - Client* c; - XEvent ev; + Client* c; + XEvent ev; XWindowChanges wc; drawbar(m); @@ -1509,8 +1631,7 @@ restack(Monitor* m) } } XSync(dpy, False); - while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)) - ; + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); } void @@ -1527,29 +1648,34 @@ run(void) void scan() { - scanner = 1; - uint i, num; - char swin[256]; - Window d1, d2, *wins = NULL; + uint i, num; + char swin[256]; + Window d1, d2, *wins; XWindowAttributes wa; + scanner = 1; + wins = NULL; if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { - for (i = 0; i < num; i++) { - if ( - !XGetWindowAttributes(dpy, wins[i], &wa) || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) + for (i = 0; i < num; ++i) { + if (!XGetWindowAttributes(dpy, wins[i], &wa) + || wa.override_redirect + || XGetTransientForHint(dpy, wins[i], &d1) + ) continue; - if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) manage(wins[i], &wa); + if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) + manage(wins[i], &wa); else if (gettextprop(wins[i], netatom[NetClientList], swin, sizeof swin)) manage(wins[i], &wa); } for (i = 0; i < num; i++) { /* now the transients */ if (!XGetWindowAttributes(dpy, wins[i], &wa)) continue; - if ( - XGetTransientForHint(dpy, wins[i], &d1) && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) + if (XGetTransientForHint(dpy, wins[i], &d1) + && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) + ) manage(wins[i], &wa); } - if (wins) + if (wins != NULL) XFree(wins); } scanner = 0; @@ -1576,29 +1702,33 @@ setclientstate(Client* c, long state) { long data[] = { state, None }; - XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, PropModeReplace, (uchar*)data, 2); + XChangeProperty( + dpy, c->win, wmatom[WMState], wmatom[WMState], 32, PropModeReplace, + (uchar*)data, 2 + ); } int sendevent(Client* c, Atom proto) { - int n; + int n; Atom* protocols; - int exists = 0; + int exists; XEvent ev; + exists = 0; if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { while (!exists && n--) exists = protocols[n] == proto; XFree(protocols); } if (exists) { - ev.type = ClientMessage; - ev.xclient.window = c->win; + ev.type = ClientMessage; + ev.xclient.window = c->win; ev.xclient.message_type = wmatom[WMProtocols]; - ev.xclient.format = 32; - ev.xclient.data.l[0] = proto; - ev.xclient.data.l[1] = CurrentTime; + ev.xclient.format = 32; + ev.xclient.data.l[0] = proto; + ev.xclient.data.l[1] = CurrentTime; XSendEvent(dpy, c->win, False, NoEventMask, &ev); } return exists; @@ -1610,7 +1740,9 @@ setfocus(Client* c) if (!c->neverfocus) { XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); XChangeProperty( - dpy, root, netatom[NetActiveWindow], XA_WINDOW, 32, PropModeReplace, (uchar*)&(c->win), 1); + dpy, root, netatom[NetActiveWindow], XA_WINDOW, 32, PropModeReplace, + (uchar*)&(c->win), 1 + ); } sendevent(c, wmatom[WMTakeFocus]); } @@ -1619,23 +1751,31 @@ void setfullscreen(Client* client, int fullscreen) { if (fullscreen && !client->isfullscreen) { - XChangeProperty(dpy, client->win, netatom[NetWMState], XA_ATOM, 32, PropModeReplace, (uchar*)&netatom[NetWMFullscreen], 1); + XChangeProperty( + dpy, client->win, netatom[NetWMState], XA_ATOM, 32, PropModeReplace, + (uchar*)&netatom[NetWMFullscreen], 1 + ); client->isfullscreen = 1; - client->oldstate = client->isfloating; - client->oldbw = client->bw; - client->bw = 0; - client->isfloating = 1; - resizeclient(client, client->mon->mx, client->mon->my, client->mon->mw, client->mon->mh); + client->oldstate = client->isfloating; + client->oldbw = client->bw; + client->bw = 0; + client->isfloating = 1; + resizeclient( + client, client->mon->mx, client->mon->my, client->mon->mw, client->mon->mh + ); XRaiseWindow(dpy, client->win); } else if (!fullscreen && client->isfullscreen) { - XChangeProperty(dpy, client->win, netatom[NetWMState], XA_ATOM, 32, PropModeReplace, (uchar*)0, 0); + XChangeProperty( + dpy, client->win, netatom[NetWMState], XA_ATOM, 32, PropModeReplace, + (uchar*)0, 0 + ); client->isfullscreen = 0; - client->isfloating = client->oldstate; - client->bw = client->oldbw; - client->x = client->oldx; - client->y = client->oldy; - client->w = client->oldw; - client->h = client->oldh; + client->isfloating = client->oldstate; + client->bw = client->oldbw; + client->x = client->oldx; + client->y = client->oldy; + client->w = client->oldw; + client->h = client->oldh; resizeclient(client, client->x, client->y, client->w, client->h); arrange(client->mon); } @@ -1673,47 +1813,47 @@ void setup() { XSetWindowAttributes wa; - int i; - Atom utf8string; + int i; + Atom utf8string; /* clean up any zombies immediately */ sigchld(0); /* init screen */ screen = DefaultScreen(dpy); - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - root = RootWindow(dpy, screen); + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + root = RootWindow(dpy, screen); xinitvisual(); drw = drw_create(dpy, screen, root, sw, sh, visual, depth, cmap); if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) die("no fonts could be loaded."); lrpad = drw->fonts->h; - bh = drw->fonts->h + 2; + bh = drw->fonts->h + 2; sp = sidepad; vp = (topbar == 1) ? vertpad : - vertpad; updategeom(); /* init atoms */ - utf8string = XInternAtom(dpy, "UTF8_STRING", False); - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); - wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); - wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); - netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); - netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); - netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); - netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); - netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); - netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); - netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + utf8string = XInternAtom(dpy, "UTF8_STRING", False); + wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); + wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); + wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); + netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); + netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); + netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); + netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); - netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); + netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); /* init cursors */ cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); cursor[CurResize] = drw_cur_create(drw, XC_sizing); - cursor[CurMove] = drw_cur_create(drw, XC_fleur); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); /* init appearance */ scheme = ecalloc(LENGTH(colors), sizeof(Color*)); @@ -1727,17 +1867,32 @@ setup() /* supporting window for NetWMCheck */ wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); XChangeProperty( - dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, PropModeReplace, (uchar*)&wmcheckwin, 1); - XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8, PropModeReplace, (uchar*)"dwm", 3); - XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32, PropModeReplace, (uchar*)&wmcheckwin, 1); + dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, PropModeReplace, + (uchar*)&wmcheckwin, 1 + ); + XChangeProperty( + dpy, wmcheckwin, netatom[NetWMName], utf8string, 8, PropModeReplace, + (uchar*)"dwm", 3 + ); + XChangeProperty( + dpy, root, netatom[NetWMCheck], XA_WINDOW, 32, PropModeReplace, + (uchar*)&wmcheckwin, 1 + ); /* EWMH support per view */ - XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, PropModeReplace, (uchar*)netatom, NetLast); + XChangeProperty( + dpy, root, netatom[NetSupported], XA_ATOM, 32, PropModeReplace, + (uchar*)netatom, NetLast + ); XDeleteProperty(dpy, root, netatom[NetClientList]); /* select events */ - wa.cursor = cursor[CurNormal]->cursor; - wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | ButtonPressMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | StructureNotifyMask | PropertyChangeMask; + wa.cursor = cursor[CurNormal]->cursor; + wa.event_mask = + SubstructureRedirectMask | SubstructureNotifyMask | ButtonPressMask + | PointerMotionMask | EnterWindowMask | LeaveWindowMask | StructureNotifyMask + | PropertyChangeMask + ; XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); XSelectInput(dpy, root, wa.event_mask); grabkeys(); @@ -1749,6 +1904,10 @@ seturgent(Client* c, int urg) { XWMHints* wmh; + if (urg && !selmon->showbar) { + selmon->showbar = 1; + updatebar(); + } c->isurgent = urg; if (!(wmh = XGetWMHints(dpy, c->win))) return; @@ -1820,10 +1979,8 @@ tagmon(const Arg* arg) void togglebar(const Arg* arg) { - selmon->showbar = !selmon->showbar; - updatebarpos(selmon); - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx + sp, selmon->by + vp, selmon->ww - 2 * sp, bh); - arrange(selmon); + selmon->showbar = selmon->showbar ? 0 : 2; + updatebar(); } void @@ -1835,7 +1992,10 @@ togglefloating(const Arg* arg) return; /* no support for fullscreen windows */ selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; if (selmon->sel->isfloating) - resize(selmon->sel, selmon->sel->x, selmon->sel->y, selmon->sel->w, selmon->sel->h, 0); + resize( + selmon->sel, selmon->sel->x, selmon->sel->y, selmon->sel->w, + selmon->sel->h, 0 + ); arrange(selmon); } @@ -1864,8 +2024,9 @@ toggletag(const Arg* arg) void toggleview(const Arg* arg) { - uint newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); + uint newtagset; + newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); if (newtagset) { selmon->tagset[selmon->seltags] = newtagset; focus(NULL); @@ -1889,9 +2050,9 @@ unfocus(Client* c, int setfocus) void unmanage(Client* c, int destroyed) { - Monitor* m; - Client* s; - XWindowChanges wc; + Monitor* m; + Client* s; + XWindowChanges wc; m = c->mon; if (c->swallowing) { @@ -1928,31 +2089,40 @@ unmanage(Client* c, int destroyed) } void -unmapnotify(XEvent* e) +updatebar(void) { - Client* c; - XUnmapEvent* ev = &e->xunmap; + updatebarpos(selmon); + XMoveResizeWindow( + dpy, selmon->barwin, selmon->wx + sp, selmon->by + vp, selmon->ww - 2 * sp, bh + ); + arrange(selmon); +} - if ((c = wintoclient(ev->window))) { - if (ev->send_event) - setclientstate(c, WithdrawnState); - else - unmanage(c, 0); - } +void +updatebarpos(Monitor* m) +{ + m->wy = m->my; + m->wh = m->mh; + if (m->showbar) { + m->wh = m->wh - vertpad - bh; + m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad; + m->wy = m->topbar ? m->wy + bh + vp : m->wy; + } else + m->by = -bh - vp; } void updatebars() { - Monitor* m; - XSetWindowAttributes wa = { - .override_redirect = True, - .background_pixel = 0, - .border_pixel = 0, - .colormap = cmap, - .event_mask = ButtonPressMask | ExposureMask - }; - XClassHint ch = { "dwm", "dwm" }; + XClassHint ch = { "dwm", "dwm" }; + XSetWindowAttributes wa; + Monitor* m; + + wa.override_redirect = True; + wa.background_pixel = 0; + wa.border_pixel = 0; + wa.colormap = cmap; + wa.event_mask = ButtonPressMask | ExposureMask; for (m = mons; m; m = m->next) { if (m->barwin) continue; @@ -1968,43 +2138,48 @@ updatebars() } void -updatebarpos(Monitor* m) +unmapnotify(XEvent* e) { - m->wy = m->my; - m->wh = m->mh; - if (m->showbar) { - m->wh = m->wh - vertpad - bh; - m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad; - m->wy = m->topbar ? m->wy + bh + vp : m->wy; - } else - m->by = -bh - vp; + Client* c; + XUnmapEvent* ev; + + ev = &e->xunmap; + if ((c = wintoclient(ev->window))) { + if (ev->send_event) + setclientstate(c, WithdrawnState); + else + unmanage(c, 0); + } } void updateclientlist() { - Client* c; + Client* c; Monitor* m; XDeleteProperty(dpy, root, netatom[NetClientList]); for (m = mons; m; m = m->next) for (c = m->clients; c; c = c->next) XChangeProperty( - dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, (uchar*)&(c->win), 1); + dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, + (uchar*)&(c->win), 1 + ); } int updategeom() { - int dirty = 0; + int dirty; + dirty = 0; #ifdef XINERAMA if (XineramaIsActive(dpy)) { - int i, j, n, nn; - Client* c; - Monitor* m; XineramaScreenInfo* info; XineramaScreenInfo* unique; + Client* c; + Monitor* m; + int i, j, n, nn; info = XineramaQueryScreens(dpy, &nn); unique = NULL; @@ -2025,12 +2200,12 @@ updategeom() mons = createmon(); } for (i = 0, m = mons; i < nn && m; m = m->next, i++) - if ( - i >= n || - unique[i].x_org != m->mx || - unique[i].y_org != m->my || - unique[i].width != m->mw || - unique[i].height != m->mh) { + if (i >= n + || unique[i].x_org != m->mx + || unique[i].y_org != m->my + || unique[i].width != m->mw + || unique[i].height != m->mh + ) { dirty = 1; m->num = i; m->mx = m->wx = unique[i].x_org; @@ -2043,7 +2218,7 @@ updategeom() for (i = nn; i < n; i++) { for (m = mons; m && m->next; m = m->next); while ((c = m->clients)) { - dirty = 1; + dirty = 1; m->clients = c->next; detachstack(c); c->mon = mons; @@ -2062,7 +2237,7 @@ updategeom() if (!mons) mons = createmon(); if (mons->mw != sw || mons->mh != sh) { - dirty = 1; + dirty = 1; mons->mw = mons->ww = sw; mons->mh = mons->wh = sh; updatebarpos(mons); @@ -2078,14 +2253,16 @@ updategeom() void updatenumlockmask(void) { - uint i, j; XModifierKeymap* modmap; + uint i, j; numlockmask = 0; - modmap = XGetModifierMapping(dpy); - for (i = 0; i < 8; i++) - for (j = 0; j < modmap->max_keypermod; j++) - if (modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock)) + modmap = XGetModifierMapping(dpy); + for (i = 0; i < 8; ++i) + for (j = 0; j < modmap->max_keypermod; ++j) + if (modmap->modifiermap[i * modmap->max_keypermod + j] + == XKeysymToKeycode(dpy, XK_Num_Lock) + ) numlockmask = (1 << i); XFreeModifiermap(modmap); } @@ -2093,7 +2270,7 @@ updatenumlockmask(void) void updatesizehints(Client* c) { - long msize; + long msize; XSizeHints size; if (!XGetWMNormalHints(dpy, c->win, &size, &msize)) /* size is uninitialized, ensure that size.flags aren't used */ @@ -2152,11 +2329,14 @@ updatetitle(Client* c) void updatewindowtype(Client* c) { - Atom state = getatomprop(c, netatom[NetWMState]); - Atom wtype = getatomprop(c, netatom[NetWMWindowType]); + Atom state; + Atom wtype; + + state = getatomprop(c, netatom[NetWMState]); if (state == netatom[NetWMFullscreen]) setfullscreen(c, 1); + wtype = getatomprop(c, netatom[NetWMWindowType]); if (wtype == netatom[NetWMWindowTypeDialog]) c->isfloating = 1; } @@ -2183,6 +2363,10 @@ updatewmhints(Client* c) void view(const Arg* arg) { + if (!selmon->showbar) { + selmon->showbar = 1; + updatebar(); + } if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) return; selmon->seltags ^= 1; /* toggle sel tagset */ @@ -2195,37 +2379,34 @@ view(const Arg* arg) pid_t winpid(Window w) { - xcb_res_client_id_spec_t spec; - xcb_res_query_client_ids_cookie_t c; - xcb_generic_error_t *e; - xcb_res_query_client_ids_reply_t *r; - xcb_res_client_id_value_iterator_t i; - pid_t result; - ulong *t; + xcb_res_client_id_spec_t spec; + xcb_res_query_client_ids_cookie_t c; + xcb_generic_error_t* e; + xcb_res_query_client_ids_reply_t* r; + xcb_res_client_id_value_iterator_t i; + pid_t result; + ulong* t; - spec.client = w; - spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; - c = xcb_res_query_client_ids(xcon, 1, &spec); - e = NULL; - r = xcb_res_query_client_ids_reply(xcon, c, &e); + spec.client = w; + spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; + c = xcb_res_query_client_ids(xcon, 1, &spec); + e = NULL; + r = xcb_res_query_client_ids_reply(xcon, c, &e); if (!r) return 0; - - i = xcb_res_query_client_ids_ids_iterator(r); - result = 0; + i = xcb_res_query_client_ids_ids_iterator(r); + result = 0; for (; i.rem; xcb_res_client_id_value_next(&i)) { spec = i.data->spec; if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) { - t = (ulong*)xcb_res_client_id_value_value(i.data); - result = *t; + t = (ulong*)xcb_res_client_id_value_value(i.data); + result = *t; break; } } - free(r); - - if (result == (pid_t)-1) + if (result == (pid_t) - 1) result = 0; return result; } @@ -2233,15 +2414,15 @@ winpid(Window w) pid_t getparentprocess(pid_t p) { - FILE *f; - char buf[256]; - uint v; + FILE* f; + char buf[256]; + uint v; snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (uint)p); if (!(f = fopen(buf, "r"))) return 0; v = 0; -+ fscanf(f, "%*u %*s %*c %u", &v); + fscanf(f, "%*u %*s %*c %u", &v); fclose(f); return (pid_t)v; } @@ -2256,15 +2437,16 @@ isdescprocess(pid_t p, pid_t c) Client* termforwin(const Client* w) { - Client* c; + Client* c; Monitor* m; if (!w->pid || w->isterminal) return NULL; - for (m = mons; m; m = m->next) for (c = m->clients; c; c = c->next) - if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) + if (c->isterminal && !c->swallowing && c->pid + && isdescprocess(c->pid, w->pid) + ) return c; return NULL; } @@ -2272,7 +2454,7 @@ termforwin(const Client* w) Client* swallowingclient(Window w) { - Client* c; + Client* c; Monitor* m; for (m = mons; m; m = m->next) @@ -2282,8 +2464,9 @@ swallowingclient(Window w) return NULL; } -Client* wintoclient(Window w) { - Client* c; +Client* +wintoclient(Window w) { + Client* c; Monitor* m; for (m = mons; m; m = m->next) @@ -2294,15 +2477,15 @@ Client* wintoclient(Window w) { } Monitor* wintomon(Window w) { - int x, y; - Client* c; + int x, y; + Client* c; Monitor* m; if (w == root && getrootptr(&x, &y)) return recttomon(x, y, 1, 1); for (m = mons; m; m = m->next) if (w == m->barwin) - return m; + return m; if ((c = wintoclient(w))) return c->mon; return selmon; @@ -2314,19 +2497,29 @@ Monitor* wintomon(Window w) { int xerror(Display* dpy, XErrorEvent* error_event) { - if ( - error_event->error_code == BadWindow - || (error_event->request_code == X_SetInputFocus && error_event->error_code == BadMatch) - || (error_event->request_code == X_PolyText8 && error_event->error_code == BadDrawable) - || (error_event->request_code == X_PolyFillRectangle && error_event->error_code == BadDrawable) - || (error_event->request_code == X_PolySegment && error_event->error_code == BadDrawable) - || (error_event->request_code == X_ConfigureWindow && error_event->error_code == BadMatch) - || (error_event->request_code == X_GrabButton && error_event->error_code == BadAccess) - || (error_event->request_code == X_GrabKey && error_event->error_code == BadAccess) - || (error_event->request_code == X_CopyArea && error_event->error_code == BadDrawable) + if (error_event->error_code == BadWindow + || (error_event->request_code == X_SetInputFocus + && error_event->error_code == BadMatch) + || (error_event->request_code == X_PolyText8 + && error_event->error_code == BadDrawable) + || (error_event->request_code == X_PolyFillRectangle + && error_event->error_code == BadDrawable) + || (error_event->request_code == X_PolySegment + && error_event->error_code == BadDrawable) + || (error_event->request_code == X_ConfigureWindow + && error_event->error_code == BadMatch) + || (error_event->request_code == X_GrabButton + && error_event->error_code == BadAccess) + || (error_event->request_code == X_GrabKey + && error_event->error_code == BadAccess) + || (error_event->request_code == X_CopyArea + && error_event->error_code == BadDrawable) ) return 0; - fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", error_event->request_code, error_event->error_code); + fprintf( + stderr, "dwm: fatal error: request code=%d, error code=%d\n", + error_event->request_code, error_event->error_code + ); return xerrorxlib(dpy, error_event); /* may call exit */ } diff --git a/patches/dwm-holdbar-modkey-6.2.diff b/patches/dwm-holdbar-modkey-6.2.diff @@ -0,0 +1,146 @@ +From 1004b9406e4b89448cf9d3b18955dbd0d55a571d Mon Sep 17 00:00:00 2001 +From: bakkeby <bakkeby@gmail.com> +Date: Wed, 1 Jul 2020 08:05:35 +0200 +Subject: [PATCH] holdbar: variant of the patch where holdbar is only active + when the bar is toggled off + +Additionally this allows the use of the primary MOD key to be used as the holdbar key while +still allowing the bar to be toggled on and off using MOD+b. This gives a more intuitive and +flexible feel when using this functionality. + +Use xev to find the keysym for the key that you want to use and add/update the HOLDKEY +definition in config.h. + +E.g. using Alt_L as the HOLDKEY +--- + config.def.h | 2 ++ + dwm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 52 insertions(+), 1 deletion(-) + +diff --git a/config.def.h b/config.def.h +index 1c0b587..8611189 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -50,6 +50,7 @@ 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 0 // replace 0 with the keysym to activate holdbar + + /* helper for spawning shell commands in the pre dwm-5.0 fashion */ + #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } +@@ -94,6 +95,7 @@ static Key keys[] = { + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, ++ { 0, HOLDKEY, holdbar, {0} }, + }; + + /* button definitions */ +diff --git a/dwm.c b/dwm.c +index 4465af1..def5f66 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -176,6 +176,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); +@@ -210,6 +211,7 @@ static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *); + 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); +@@ -217,6 +219,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); +@@ -245,6 +248,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, +@@ -252,6 +256,7 @@ static void (*handler[LASTEvent]) (XEvent *) = { + [EnterNotify] = enternotify, + [Expose] = expose, + [FocusIn] = focusin, ++ [KeyRelease] = keyrelease, + [KeyPress] = keypress, + [MappingNotify] = mappingnotify, + [MapRequest] = maprequest, +@@ -275,6 +280,50 @@ static Window root, wmcheckwin; + 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) && selmon->showbar == 2) { ++ selmon->showbar = 0; ++ updateholdbarpos(selmon); ++ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); ++ arrange(selmon); ++ } ++} ++ ++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) + { +@@ -1699,7 +1748,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); +-- +2.19.1 +