dwm

My fork of https://dwm.suckless.org/
git clone https://git.inz.fi/dwm/
Log | Files | Refs | README | LICENSE

commit 7505368614ea11a69be4fac7e5b61d4fd4e27161
parent cb88d225e2d3195dd43eb8090d2fe4190242dbe2
Author: Santtu Lakkala <inz@inz.fi>
Date:   Wed, 23 Feb 2022 11:55:19 +0200

Allow CSI SGR in status bar

Diffstat:
Mconfig.def.h | 19+++++++++++++++++++
Mdwm.c | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 203 insertions(+), 3 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -23,6 +23,25 @@ static const char *colors[][3] = { [SchemeSel] = { col_gray4, col_cyan, col_cyan }, }; +static const char *barcolors[] = { + "#000000", + "#7f0000", + "#007f00", + "#7f7f00", + "#00007f", + "#7f007f", + "#007f7f", + "#cccccc", + "#333333", + "#ff0000", + "#00ff00", + "#ffff00", + "#0000ff", + "#ff00ff", + "#00ffff", + "#ffffff", +}; + /* tagging */ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; diff --git a/dwm.c b/dwm.c @@ -267,7 +267,7 @@ static void zoom(const Arg *arg); /* variables */ static Systray *systray = NULL; static const char broken[] = "broken"; -static char stext[256]; +static char stext[512]; static int screen; static int sw, sh; /* X display screen geometry width, height */ static int bh; /* bar height */ @@ -295,6 +295,7 @@ static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; static int running = 1; static Cur *cursor[CurLast]; static Clr **scheme; +static Clr *barclrs; static Display *dpy; static Drw *drw; static Monitor *mons, *selmon; @@ -789,6 +790,25 @@ dirtomon(int dir) } void +resetfntlist(Fnt *orighead, Fnt *curhead) +{ + if (orighead != curhead) { + Fnt *f; + for (f = orighead; f->next; f = f->next); + f->next = curhead; + for (f = f->next; f->next != orighead; f = f->next); + f->next = NULL; + } +} + +enum SgrFlags { + REVERSE = 1 << 0, + UNDERLINE = 1 << 1, + STRIKETHROUGH = 1 << 2, + OVERLINE = 1 << 3 +}; + +void drawbar(Monitor *m) { int x, w, tw = 0, stw = 0; @@ -805,9 +825,165 @@ drawbar(Monitor *m) /* draw status first so it can be overdrawn by tags later */ if (m == selmon) { /* status is only drawn on selected monitor */ + char buffer[sizeof(stext)]; + Clr scm[3]; + int wr, rd; + int pw; + int fg = 7; + int bg = 0; + int fmt = 0; + int lp = lrpad / 2 - 2; + Fnt *fset = drw->fonts; + + memcpy(scm, scheme[SchemeNorm], sizeof(scm)); + + drw_setscheme(drw, scm); + + for (tw = 0, wr = 0, rd = 0; stext[rd]; rd++) { + if (stext[rd] == '\033' && stext[rd + 1] == '[') { + size_t alen = strspn(stext + rd + 2, + "0123456789;"); + if (stext[rd + alen + 2] == 'm') { + if (wr) { + buffer[wr] = '\0'; + tw += TEXTW(buffer) - lrpad; + wr = 0; + } + + char *ep = stext + rd + 1; + while (*ep != 'm') { + unsigned v = strtoul(ep + 1, &ep, 10); + if (v == 0 || (v >= 10 && v <= 19)) { + int fi = v % 10; + Fnt *f; + Fnt *p; + resetfntlist(fset, drw->fonts); + for (p = NULL, f = fset; f && fi--; p = f, f = f->next); + if (f) { + if (p) { + p->next = NULL; + for (p = f; p->next; p = p->next); + p->next = fset; + } + drw_setfontset(drw, f); + } else { + drw_setfontset(drw, fset); + } + } + } + + rd += alen + 2; + continue; + } + } + buffer[wr++] = stext[rd]; + } + buffer[wr] = '\0'; + + tw += TEXTW(buffer) - lrpad / 2 + 2; + x = m->ww - tw - stw; + + resetfntlist(fset, drw->fonts); + drw_setfontset(drw, fset); + + for (wr = 0, rd = 0; stext[rd]; rd++) { + if (stext[rd] == '' && stext[rd + 1] == '[') { + size_t alen = strspn(stext + rd + 2, + "0123456789;"); + if (stext[rd + alen + 2] == 'm') { + if (wr) { + buffer[wr] = '\0'; + pw = TEXTW(buffer) - lrpad + lp; + drw_text(drw, x, 0, pw, bh, lp, buffer, fmt & REVERSE); + if (fmt & UNDERLINE) + drw_rect(drw, x, (bh + drw->fonts->h) / 2, pw, 1, 1, fmt & REVERSE); + if (fmt & STRIKETHROUGH) + drw_rect(drw, x, bh / 2, pw, 1, 1, fmt & REVERSE); + if (fmt & OVERLINE) + drw_rect(drw, x, (bh - drw->fonts->h) / 2, pw, 1, 1, fmt & REVERSE); + x += pw; + lp = 0; + } + + char *ep = stext + rd + 1; + while (*ep != 'm') { + unsigned v = strtoul(ep + 1, &ep, 10); + if (v == 0) { + memcpy(scm, scheme[SchemeNorm], sizeof(scm)); + fg = 7; + bg = 0; + fmt = 0; + resetfntlist(fset, drw->fonts); + drw_setfontset(drw, fset); + } else if (v == 1) { + fg |= 8; + scm[0] = barclrs[fg]; + } else if (v == 4) { + fmt |= UNDERLINE; + } else if (v == 7) { + fmt |= REVERSE; + } else if (v == 9) { + fmt |= STRIKETHROUGH; + } else if (v >= 10 && v <= 19) { + int fi = v % 10; + Fnt *f; + Fnt *p; + resetfntlist(fset, drw->fonts); + for (p = NULL, f = fset; f && fi--; p = f, f = f->next); + if (f) { + if (p) { + p->next = NULL; + for (p = f; p->next; p = p->next); + p->next = fset; + } + drw_setfontset(drw, f); + } else { + drw_setfontset(drw, fset); + } + } else if (v == 22) { + fg &= ~8; + scm[0] = barclrs[fg]; + } else if (v == 24) { + fmt &= ~UNDERLINE; + } else if (v == 27) { + fmt &= ~REVERSE; + } else if (v == 29) { + fmt &= ~STRIKETHROUGH; + } else if (v >= 30 && v <= 37) { + fg = v % 10 | (fg & 8); + scm[0] = barclrs[fg]; + } else if (v >= 40 && v <= 47) { + bg = v % 10; + scm[1] = barclrs[bg]; + } else if (v == 53) { + fmt |= OVERLINE; + } else if (v == 55) { + fmt &= ~OVERLINE; + } + } + + rd += alen + 2; + wr = 0; + + drw_setscheme(drw, scm); + continue; + } + } + buffer[wr++] = stext[rd]; + } + + buffer[wr] = '\0'; + pw = TEXTW(buffer) - lrpad + lp + (lrpad & 1); + drw_text(drw, x, 0, pw + 4, bh, lp, buffer, fmt & REVERSE); + if (fmt & UNDERLINE) + drw_rect(drw, x, (bh + drw->fonts->h) / 2, pw, 1, 1, fmt & REVERSE); + if (fmt & STRIKETHROUGH) + drw_rect(drw, x, bh / 2, pw, 1, 1, fmt & REVERSE); + if (fmt & OVERLINE) + drw_rect(drw, x, (bh - drw->fonts->h) / 2, pw, 1, 1, fmt & REVERSE); + + resetfntlist(fset, drw->fonts); drw_setscheme(drw, scheme[SchemeNorm]); - tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px extra right padding */ - drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0); } resizebarwin(m); @@ -1776,6 +1952,11 @@ setup(void) scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); for (i = 0; i < LENGTH(colors); i++) scheme[i] = drw_scm_create(drw, colors[i], 3); + + barclrs = ecalloc(LENGTH(barcolors), sizeof(Clr)); + for (i = 0; i < LENGTH(barcolors); i++) + drw_clr_create(drw, &barclrs[i], barcolors[i]); + /* init system tray */ updatesystray(); /* init bars */