-
-
Save udiboy1209/c4a47c3bb1bbfa5498032dee34bc144a to your computer and use it in GitHub Desktop.
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; | |
} | |
} | |
@HackedPixels this patch doesn't apply to dwm-6.1 and I apologize for the confusing naming. The patch applies cleanly to this commit in the development repo.
Also a recent bug has cropped up in statusbar and here is a fix which will apply over this patch.
when you are focused on a window, the selected item in the bar also changes color. but when changing tags/desktops the color does not refresh in the last few pixels at the end. did you manage to resolve this?
I have manually applied it to the current dwm 6.2 if you want my diff
The fix I had linked was for that bug I guess.
When drawing the triangle, the background rectangle draw does not take effect for some reason. The hack I had used was to draw two triangles instead of drawing one triangle over one rectangle. Will need to find this fix again though. Looks like the pastebin expired.
Triangle over rectangle
*----*
| *|
| /||
| / ||
|*--*|
*----*
Two triangles
*---*
| /*
| //|
|// |
*/ |
*---*
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.
@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.
First of all, great patch!
But, this patch fails against a clean dwm-6.1.
dwm.c does not get applied.
Also the code seems broken because ColBg, ColFg are nowhere defined.
Would much appreciate an updated version of this gist!