Created
May 7, 2018 10:59
-
-
Save udiboy1209/c4a47c3bb1bbfa5498032dee34bc144a to your computer and use it in GitHub Desktop.
DWM powerline statusbar, gaps, padding, no vacant tags, all titles patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/config.def.h b/config.def.h | |
index a9ac303..51e2ab0 100644 | |
--- a/config.def.h | |
+++ b/config.def.h | |
@@ -2,6 +2,7 @@ | |
/* appearance */ | |
static const unsigned int borderpx = 1; /* border pixel of windows */ | |
+static const unsigned int gappx = 1; /* gap pixel between windows */ | |
static const unsigned int snap = 32; /* snap pixel */ | |
static const int showbar = 1; /* 0 means no bar */ | |
static const int topbar = 1; /* 0 means bottom bar */ | |
diff --git a/drw.c b/drw.c | |
index c638323..7e794b1 100644 | |
--- a/drw.c | |
+++ b/drw.c | |
@@ -15,6 +15,7 @@ static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0} | |
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; | |
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; | |
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; | |
+Clr transcheme[3]; | |
static long | |
utf8decodebyte(const char c, size_t *i) | |
@@ -222,6 +223,15 @@ drw_setscheme(Drw *drw, Clr *scm) | |
drw->scheme = scm; | |
} | |
+void | |
+drw_settrans(Drw *drw, Clr *psc, Clr *nsc) | |
+{ | |
+ if (drw) { | |
+ transcheme[0] = psc[ColBg]; transcheme[1] = nsc[ColBg]; transcheme[2] = psc[ColBorder]; | |
+ drw->scheme = transcheme; | |
+ } | |
+} | |
+ | |
void | |
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) | |
{ | |
@@ -364,6 +374,30 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp | |
return x + (render ? w : 0); | |
} | |
+void | |
+drw_arrow(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direction, int slash) | |
+{ | |
+ if (!drw) | |
+ return; | |
+ | |
+ /* direction=1 draws right arrow */ | |
+ x = direction ? x : x + w; | |
+ w = direction ? w : -w; | |
+ /* slash=1 draws slash instead of arrow */ | |
+ unsigned int hh = slash ? (direction ? 0 : h) : h/2; | |
+ | |
+ XPoint points[] = { | |
+ {x , y }, | |
+ {x + w, y + hh }, | |
+ {x , y + h }, | |
+ }; | |
+ | |
+ XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel); | |
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | |
+ XSetForeground(drw->dpy, drw->gc, drw->scheme[ColFg].pixel); | |
+ XFillPolygon(drw->dpy, drw->drawable, drw->gc, points, 3, Nonconvex, CoordModeOrigin); | |
+} | |
+ | |
void | |
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) | |
{ | |
diff --git a/drw.h b/drw.h | |
index 4bcd5ad..fc4f3bb 100644 | |
--- a/drw.h | |
+++ b/drw.h | |
@@ -48,10 +48,12 @@ void drw_cur_free(Drw *drw, Cur *cursor); | |
/* Drawing context manipulation */ | |
void drw_setfontset(Drw *drw, Fnt *set); | |
void drw_setscheme(Drw *drw, Clr *scm); | |
+void drw_settrans(Drw *drw, Clr *psc, Clr *nsc); | |
/* Drawing functions */ | |
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); | |
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); | |
+void drw_arrow(Drw* drw, int x, int y, unsigned int w, unsigned int h, int direction, int slash); | |
/* Map functions */ | |
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); | |
diff --git a/dwm.c b/dwm.c | |
index c98678d..2ad914e 100644 | |
--- a/dwm.c | |
+++ b/dwm.c | |
@@ -59,7 +59,7 @@ | |
/* enums */ | |
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ | |
-enum { SchemeNorm, SchemeSel }; /* color schemes */ | |
+enum { SchemeNorm, SchemeSel, SchemeTitle, SchemeTitleSel }; /* color schemes */ | |
enum { NetSupported, NetWMName, NetWMState, NetWMCheck, | |
NetWMFullscreen, NetActiveWindow, NetWMWindowType, | |
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ | |
@@ -162,6 +162,7 @@ static void detach(Client *c); | |
static void detachstack(Client *c); | |
static Monitor *dirtomon(int dir); | |
static void drawbar(Monitor *m); | |
+static int drawstatus(Monitor *m); | |
static void drawbars(void); | |
static void enternotify(XEvent *e); | |
static void expose(XEvent *e); | |
@@ -239,7 +240,7 @@ static const char broken[] = "broken"; | |
static char stext[256]; | |
static int screen; | |
static int sw, sh; /* X display screen geometry width, height */ | |
-static int bh, blw = 0; /* bar geometry */ | |
+static int bh, plw, blw = 0; /* bar geometry */ | |
static int lrpad; /* sum of left and right padding for text */ | |
static int (*xerrorxlib)(Display *, XErrorEvent *); | |
static unsigned int numlockmask = 0; | |
@@ -263,6 +264,7 @@ static Atom wmatom[WMLast], netatom[NetLast]; | |
static int running = 1; | |
static Cur *cursor[CurLast]; | |
static Clr **scheme; | |
+static Clr **statusscheme; | |
static Display *dpy; | |
static Drw *drw; | |
static Monitor *mons, *selmon; | |
@@ -430,10 +432,16 @@ buttonpress(XEvent *e) | |
focus(NULL); | |
} | |
if (ev->window == selmon->barwin) { | |
- i = x = 0; | |
- do | |
- x += TEXTW(tags[i]); | |
- while (ev->x >= x && ++i < LENGTH(tags)); | |
+ i = 0; x = plw; | |
+ unsigned int occ = 0; | |
+ for(c = m->clients; c; c = c->next) | |
+ occ |= c->tags; | |
+ do { | |
+ /* do not reserve space for vacant tags */ | |
+ if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) | |
+ continue; | |
+ x += TEXTW(tags[i]) + plw; | |
+ } while (ev->x >= x && ++i < LENGTH(tags)); | |
if (i < LENGTH(tags)) { | |
click = ClkTagBar; | |
arg.ui = 1 << i; | |
@@ -695,51 +703,117 @@ dirtomon(int dir) | |
void | |
drawbar(Monitor *m) | |
{ | |
- int x, w, sw = 0; | |
- int boxs = drw->fonts->h / 9; | |
- int boxw = drw->fonts->h / 6 + 2; | |
- unsigned int i, occ = 0, urg = 0; | |
+ int x, w, wt, sw = 0; | |
+ unsigned int i, occ = 0, urg = 0, n = 0; | |
+ plw = drw->fonts->h / 2 + 1; | |
Client *c; | |
+ Clr *prevscheme, *nxtscheme; | |
/* draw status first so it can be overdrawn by tags later */ | |
if (m == selmon) { /* status is only drawn on selected monitor */ | |
drw_setscheme(drw, scheme[SchemeNorm]); | |
- sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ | |
- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); | |
+ sw = drawstatus(m); | |
} | |
for (c = m->clients; c; c = c->next) { | |
+ if (ISVISIBLE(c)) n++; | |
occ |= c->tags; | |
if (c->isurgent) | |
urg |= c->tags; | |
} | |
x = 0; | |
+ | |
+ prevscheme = scheme[SchemeNorm]; | |
for (i = 0; i < LENGTH(tags); i++) { | |
+ /* do not draw vacant tags */ | |
+ 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_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); | |
- x += w; | |
+ drw_settrans(drw, prevscheme, (nxtscheme = scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm])); | |
+ drw_arrow(drw, x, 0, plw, bh, 1, 0); | |
+ x += plw; | |
+ | |
+ drw_setscheme(drw, nxtscheme); | |
+ drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); | |
+ x += w; | |
+ | |
+ prevscheme = nxtscheme; | |
} | |
+ nxtscheme = scheme[SchemeNorm]; | |
+ | |
+ drw_settrans(drw, prevscheme, nxtscheme); | |
+ drw_arrow(drw, x, 0, plw, bh, 1, 0); | |
+ x += plw; | |
+ | |
w = blw = TEXTW(m->ltsymbol); | |
drw_setscheme(drw, scheme[SchemeNorm]); | |
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); | |
+ | |
+ if ((m->ww - sw - x) > bh && n > 0) { | |
+ wt = (m->ww - sw - x) / n - 2 * plw; | |
+ for (c = m->clients; c; c = c->next) { | |
+ if (!ISVISIBLE(c)) continue; /* only show titles of windows on current tag */ | |
- 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); | |
- } 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); | |
+ drw_setscheme(drw, c == m->sel ? scheme[SchemeTitleSel] : scheme[SchemeTitle]); | |
+ drw_text(drw, x + plw, 0, wt, bh, lrpad / 2, c->name, 0); | |
+ | |
+ drw_settrans(drw, c == m->sel ? scheme[SchemeTitleSel] : scheme[SchemeTitle], scheme[SchemeNorm]); | |
+ drw_arrow(drw, x, 0, plw, bh, 0, 1); | |
+ drw_arrow(drw, x + wt + plw, 0, plw, bh, 1, 1); | |
+ | |
+ x += wt + 2 * plw; | |
+ } | |
+ } else { /* when empty or not enough space to draw, clear out the title space */ | |
+ drw_setscheme(drw, scheme[SchemeNorm]); | |
+ drw_rect(drw, x, 0, m->ww - sw - x, bh, 1, 1); | |
+ } | |
+ drw_map(drw, m->barwin, 0, 0, m->ww, bh); | |
+} | |
+ | |
+int | |
+drawstatus(Monitor* m) | |
+{ | |
+ char status[256]; | |
+ int i, n = strlen(stext), cn = 0; | |
+ int x = m->ww, w = 0; | |
+ char *bs, bp = '|'; | |
+ Clr *prevscheme = statusscheme[0], *nxtscheme; | |
+ | |
+ strcpy(status, stext); | |
+ | |
+ for (i = n, bs = &status[n-1]; i >= 0; i--, bs--) { | |
+ if (*bs == '<' || *bs == '/' || *bs == '\\' || *bs == '|') { /* block start */ | |
+ cn = ((int) *(bs+1)) - 1; | |
+ | |
+ if (cn < LENGTH(statuscolors)) { | |
+ drw_settrans(drw, prevscheme, (nxtscheme = statusscheme[cn])); | |
+ } else { | |
+ drw_settrans(drw, prevscheme, (nxtscheme = statusscheme[0])); | |
+ } | |
+ | |
+ if (bp != '|') { | |
+ drw_arrow(drw, x - plw, 0, plw, bh, bp == '\\' ? 1 : 0, bp == '<' ? 0 : 1); | |
+ x -= plw; | |
+ } | |
+ | |
+ drw_setscheme(drw, nxtscheme); | |
+ w = TEXTW(bs+2); | |
+ drw_text(drw, x - w, 0, w, bh, lrpad / 2, bs+2, 0); | |
+ x -= w; | |
+ | |
+ bp = *bs; | |
+ *bs = 0; | |
+ prevscheme = nxtscheme; | |
+ } | |
+ } | |
+ if (bp != '|') { | |
+ drw_settrans(drw, prevscheme, scheme[SchemeNorm]); | |
+ drw_arrow(drw, x - plw, 0, plw, bh, bp == '\\' ? 1 : 0, bp == '<' ? 0 : 1); | |
+ drw_rect(drw, x - 2 * plw, 0, plw, bh, 1, 1); | |
+ x -= plw * 2; | |
+ } | |
+ | |
+ return m->ww - x; | |
} | |
void | |
@@ -1112,7 +1186,7 @@ monocle(Monitor *m) | |
if (n > 0) /* override layout symbol */ | |
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); | |
for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) | |
- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); | |
+ resize(c, m->wx + padpx, m->wy + padpx, m->ww - 2 * padpx - 2 * c->bw, m->wh - 2 * padpx - 2 * c->bw, 0); | |
} | |
void | |
@@ -1570,6 +1644,9 @@ setup(void) | |
scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); | |
for (i = 0; i < LENGTH(colors); i++) | |
scheme[i] = drw_scm_create(drw, colors[i], 3); | |
+ statusscheme = ecalloc(LENGTH(statuscolors), sizeof(Clr *)); | |
+ for (i = 0; i < LENGTH(statuscolors); i++) | |
+ statusscheme[i] = drw_scm_create(drw, statuscolors[i], 3); | |
/* init bars */ | |
updatebars(); | |
updatestatus(); | |
@@ -1673,26 +1750,29 @@ tagmon(const Arg *arg) | |
void | |
tile(Monitor *m) | |
{ | |
- unsigned int i, n, h, mw, my, ty; | |
+ unsigned int i, n, h, r, g = 0, mw, my, ty; | |
Client *c; | |
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); | |
if (n == 0) | |
return; | |
- if (n > m->nmaster) | |
- mw = m->nmaster ? m->ww * m->mfact : 0; | |
+ if(n > m->nmaster) | |
+ mw = m->nmaster ? (m->ww - (g = gappx) - 2*padpx) * m->mfact : 0; | |
else | |
- mw = m->ww; | |
- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) | |
- if (i < m->nmaster) { | |
- h = (m->wh - my) / (MIN(n, m->nmaster) - i); | |
- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); | |
- my += HEIGHT(c); | |
- } else { | |
- h = (m->wh - ty) / (n - i); | |
- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); | |
- ty += HEIGHT(c); | |
+ mw = m->ww - 2*padpx; | |
+ for(i = 0, my = ty = padpx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) | |
+ if(i < m->nmaster) { | |
+ r = MIN(n, m->nmaster) - i; | |
+ h = (m->wh - my - gappx * (r - 1) - 2*padpx) / r; | |
+ resize(c, m->wx + padpx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False); | |
+ my += HEIGHT(c) + gappx; | |
+ } | |
+ else { | |
+ r = n - i; | |
+ h = (m->wh - ty - gappx * (r - 1) - 2*padpx) / r; | |
+ resize(c, m->wx + padpx + mw + g, m->wy + ty, m->ww - 2*padpx - mw - g - (2*c->bw), h - (2*c->bw), False); | |
+ ty += HEIGHT(c) + gappx; | |
} | |
} | |
@Derevi you can refer to the updated patch here for powerline statusbar: https://gitlab.com/udiboy1209-suckless/dwm/-/commit/071f5063e8ac4280666828179f92788d893eea40
I manually applied your powerline patch from gitlab, but now the status won't show. Other than that, this patch is awesome! Thanks for sharing it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
That makes sense. post it if you find it. When you do I can patch it to the current version of dwm, and send you the diff to post if you want.