My configuration of sxmo fork of suckless dwm.

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

commit 13266efb0636d4ee1fa599a75001a3b3307e4c03
parent 8de4a21879f65e468f01e1d0920ab010811be09a
Author: Miles Alan <m@milesalan.com>
Date:   Sat, 25 Apr 2020 15:55:04 -0500

Add Bartabgroups when used on PBP

Diffstat:
Mconfig.def.h | 11+++++++++++
Mdwm.c | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 129 insertions(+), 13 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -19,6 +19,8 @@ static const char *colors[][3] = { /* fg bg border */ [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, [SchemeSel] = { col_gray4, col_cyan, col_cyan }, + [SchemeTabActive] = { col_gray2, col_gray3, col_gray2 }, + [SchemeTabInactive] = { col_gray1, col_gray3, col_gray1 } }; /* tagging */ @@ -35,6 +37,15 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95] static const int nmaster = 1; /* number of clients in master area */ static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ +/* Bartabgroups properties */ +#define BARTAB_BORDERS 1 // 0 = off, 1 = on +#define BARTAB_BOTTOMBORDER 1 // 0 = off, 1 = on +#define BARTAB_TAGSINDICATOR 1 // 0 = off, 1 = on if >1 client/view tag, 2 = always on +#define BARTAB_TAGSPX 5 // # pixels for tag grid boxes +#define BARTAB_TAGSROWS 3 // # rows in tag grid (9 tags, e.g. 3x3) +static void (*bartabmonfns[])(Monitor *) = { monocle /* , customlayoutfn */ }; +static void (*bartabfloatfns[])(Monitor *) = { NULL /* , customlayoutfn */ }; + static const Layout layouts[] = { /* symbol arrange function */ { "[]=", tile }, /* first entry is default */ diff --git a/dwm.c b/dwm.c @@ -62,7 +62,7 @@ /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ -enum { SchemeNorm, SchemeSel }; /* color schemes */ +enum { SchemeNorm, SchemeSel, SchemeTabActive, SchemeTabInactive }; /* color schemes */ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, NetWMFullscreen, NetActiveWindow, NetWMWindowType, NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ @@ -415,6 +415,98 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) } void +bartabdraw(Monitor *m, Client *c, int unused, int x, int w, int groupactive) { + if (!c) return; + int i, nclienttags = 0, nviewtags = 0; + + drw_setscheme(drw, scheme[ + m->sel == c ? SchemeSel : (groupactive ? SchemeTabActive: SchemeTabInactive) + ]); + drw_text(drw, x, 0, w, bh, lrpad / 2, c->name, 0); + + // Floating win indicator + if (c->isfloating) drw_rect(drw, x + 2, 2, 5, 5, 0, 0); + + // Optional borders between tabs + if (BARTAB_BORDERS) { + XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBorder].pixel); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, 0, 1, bh); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x + w, 0, 1, bh); + } + + // Optional tags icons + for (i = 0; i < LENGTH(tags); i++) { + if ((m->tagset[m->seltags] >> i) & 1) { nviewtags++; } + if ((c->tags >> i) & 1) { nclienttags++; } + } + if (BARTAB_TAGSINDICATOR == 2 || nclienttags > 1 || nviewtags > 1) { + for (i = 0; i < LENGTH(tags); i++) { + drw_rect(drw, + ( x + w - 2 - ((LENGTH(tags) / BARTAB_TAGSROWS) * BARTAB_TAGSPX) + - (i % (LENGTH(tags)/BARTAB_TAGSROWS)) + ((i % (LENGTH(tags) / BARTAB_TAGSROWS)) * BARTAB_TAGSPX) + ), + ( 2 + ((i / (LENGTH(tags)/BARTAB_TAGSROWS)) * BARTAB_TAGSPX) + - ((i / (LENGTH(tags)/BARTAB_TAGSROWS))) + ), + BARTAB_TAGSPX, BARTAB_TAGSPX, (c->tags >> i) & 1, 0 + ); + } + } +} + +void +battabclick(Monitor *m, Client *c, int passx, int x, int w, int unused) { + if (passx >= x && passx <= x + w) { + focus(c); + restack(selmon); + } +} + +void +bartabcalculate( + Monitor *m, int offx, int sw, int passx, + void(*tabfn)(Monitor *, Client *, int, int, int, int) +) { + Client *c; + int + i, clientsnmaster = 0, clientsnstack = 0, clientsnfloating = 0, + masteractive = 0, fulllayout = 0, floatlayout = 0, + x, w, tgactive; + + for (i = 0, c = m->clients; c; c = c->next) { + if (!ISVISIBLE(c)) continue; + if (c->isfloating) { clientsnfloating++; continue; } + if (m->sel == c) { masteractive = i < m->nmaster; } + if (i < m->nmaster) { clientsnmaster++; } else { clientsnstack++; } + i++; + } + for (i = 0; i < LENGTH(bartabfloatfns); i++) if (m ->lt[m->sellt]->arrange == bartabfloatfns[i]) { floatlayout = 1; break; } + for (i = 0; i < LENGTH(bartabmonfns); i++) if (m ->lt[m->sellt]->arrange == bartabmonfns[i]) { fulllayout = 1; break; } + for (c = m->clients, i = 0; c; c = c->next) { + if (!ISVISIBLE(c)) continue; + if (clientsnmaster + clientsnstack == 0 || floatlayout) { + x = offx + (((m->mw - offx - sw) / (clientsnmaster + clientsnstack + clientsnfloating)) * i); + w = (m->mw - offx - sw) / (clientsnmaster + clientsnstack + clientsnfloating); + tgactive = 1; + } else if (!c->isfloating && (fulllayout || ((clientsnmaster == 0) ^ (clientsnstack == 0)))) { + x = offx + (((m->mw - offx - sw) / (clientsnmaster + clientsnstack)) * i); + w = (m->mw - offx - sw) / (clientsnmaster + clientsnstack); + tgactive = 1; + } else if (i < m->nmaster && !c->isfloating) { + x = offx + ((((m->mw * m->mfact) - offx) /clientsnmaster) * i); + w = ((m->mw * m->mfact) - offx) / clientsnmaster; + tgactive = masteractive; + } else if (!c->isfloating) { + x = (m->mw * m->mfact) + ((((m->mw * (1 - m->mfact)) - sw) / clientsnstack) * (i - m->nmaster)); + w = ((m->mw * (1 - m->mfact)) - sw) / clientsnstack; + tgactive = !masteractive; + } else continue; + tabfn(m, c, passx, x, w, tgactive); + i++; + } +} + +void arrange(Monitor *m) { if (m) @@ -519,8 +611,8 @@ buttonpress(XEvent *e) click = ClkLtSymbol; else if (ev->x > selmon->ww - TEXTW(stext)) click = ClkStatusText; - else - click = ClkWinTitle; + else // Focus clicked tab bar item + bartabcalculate(selmon, x, TEXTW(stext) - lrpad + 2, ev->x, battabclick); } else if ((c = wintoclient(ev->window))) { focus(c); restack(selmon); @@ -829,15 +921,26 @@ drawbar(Monitor *m) drw_setscheme(drw, scheme[SchemeNorm]); x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); + drw_rect(drw, x, 0, m->ww - sw - x, bh, 1, 1); if ((w = m->ww - sw - x) > bh) { - if (m->sel) { - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); - if (m->sel->isfloating) - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); + if (iswide()) { + // Draw bartabgroups for wide PB + bartabcalculate(m, x, sw, -1, bartabdraw); + if (BARTAB_BOTTOMBORDER) { + drw_setscheme(drw, scheme[SchemeTabActive]); + drw_rect(drw, 0, bh - 1, m->ww, 1, 1, 0); + } } else { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x, 0, w, bh, 1, 1); + // Draw normalbar for PP + if (m->sel) { + drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); + if (m->sel->isfloating) + drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); + } else { + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, x, 0, w, bh, 1, 1); + } } } drw_map(drw, m->barwin, 0, 0, m->ww, bh); @@ -1105,6 +1208,10 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) } #endif /* XINERAMA */ +int +iswide() { + return sw > 1000 ? 1 : 0; +} void keypresstimerdonesync(int idx) { int i, maxidx; @@ -1801,9 +1908,7 @@ setup(void) root = RootWindow(dpy, screen); drw = drw_create(dpy, screen, root, sw, sh); - int fontoffset = sw > 1000 ? 1 : 0; - fprintf(stderr, "WIDTH %d %d\n", sw, fontoffset); - if (!drw_fontset_create(drw, fonts + fontoffset, LENGTH(fonts) - fontoffset)) + if (!drw_fontset_create(drw, fonts + (iswide() ? 1: 0), LENGTH(fonts) - (iswide() ? 1 : 0))) die("no fonts could be loaded."); lrpad = drw->fonts->h; bh = drw->fonts->h + 2;