diff --git a/dwm/dwm-barmodules-fancybar-6.2.diff b/dwm/dwm-barmodules-fancybar-6.2.diff new file mode 100644 index 0000000..111f674 --- /dev/null +++ b/dwm/dwm-barmodules-fancybar-6.2.diff @@ -0,0 +1,157 @@ +From ee60db4461820fbc670338ed1cddbdc2ea5c0fd3 Mon Sep 17 00:00:00 2001 +From: bakkeby +Date: Mon, 20 Jul 2020 10:16:30 +0200 +Subject: [PATCH 2/2] Adding fancybar module + +--- + config.def.h | 2 +- + patch/bar_fancybar.c | 84 ++++++++++++++++++++++++++++++++++++++++++++ + patch/bar_fancybar.h | 3 ++ + patch/include.c | 3 +- + patch/include.h | 3 +- + 5 files changed, 92 insertions(+), 3 deletions(-) + create mode 100644 patch/bar_fancybar.c + create mode 100644 patch/bar_fancybar.h + +diff --git a/config.def.h b/config.def.h +index 2534eac..40cb38c 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -48,7 +48,7 @@ static const BarRule barrules[] = { + { -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, "tags" }, + { -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, "layout" }, + { 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" }, +- { -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, "wintitle" }, ++ { -1, 0, BAR_ALIGN_NONE, width_fancybar, draw_fancybar, click_fancybar, "fancybar" }, + }; + + /* layout(s) */ +diff --git a/patch/bar_fancybar.c b/patch/bar_fancybar.c +new file mode 100644 +index 0000000..810026d +--- /dev/null ++++ b/patch/bar_fancybar.c +@@ -0,0 +1,84 @@ ++int ++width_fancybar(Bar *bar, BarWidthArg *a) ++{ ++ return a->max_width; ++} ++ ++int ++draw_fancybar(Bar *bar, BarDrawArg *a) ++{ ++ int ftw, mw, ew = 0, n = 0; ++ unsigned int i; ++ Client *c; ++ Monitor *m = bar->mon; ++ ++ int boxs = drw->fonts->h / 9; ++ int boxw = drw->fonts->h / 6 + 2; ++ #if BAR_TITLE_LEFT_PAD && BAR_TITLE_RIGHT_PAD ++ int x = a->x + lrpad / 2, w = a->w - lrpad; ++ #elif BAR_TITLE_LEFT_PAD ++ int x = a->x + lrpad / 2, w = a->w - lrpad / 2; ++ #elif BAR_TITLE_RIGHT_PAD ++ int x = a->x, w = a->w - lrpad / 2; ++ #else ++ int x = a->x, w = a->w; ++ #endif // BAR_TITLE_LEFT_PAD | BAR_TITLE_RIGHT_PAD ++ ++ for (c = m->clients; c; c = c->next) { ++ if (ISVISIBLE(c)) ++ n++; ++ } ++ ++ if (n > 0) { ++ ftw = TEXTW(m->sel->name); ++ mw = (ftw >= w || n == 1) ? 0 : (w - ftw) / (n - 1); ++ ++ i = 0; ++ ++ for (c = m->clients; c; c = c->next) { ++ if (!ISVISIBLE(c) || c == m->sel) ++ continue; ++ ftw = TEXTW(c->name); ++ if (ftw < mw) ++ ew += (mw - ftw); ++ else ++ i++; ++ } ++ ++ if (i > 0) ++ mw += ew / i; ++ ++ for (c = m->clients; c; c = c->next) { ++ if (!ISVISIBLE(c)) ++ continue; ++ ftw = MIN(m->sel == c ? w : mw, TEXTW(c->name)); ++ ++ #if BAR_VTCOLORS_PATCH ++ drw_setscheme(drw, scheme[m->sel == c ? SchemeTitleSel : SchemeTitleNorm]); ++ #elif BAR_TITLECOLOR_PATCH ++ drw_setscheme(drw, scheme[m->sel == c ? SchemeTitle : SchemeNorm]); ++ #else ++ drw_setscheme(drw, scheme[m->sel == c ? SchemeSel : SchemeNorm]); ++ #endif // BAR_VTCOLORS_PATCH / BAR_TITLECOLOR_PATCH ++ if (ftw > 0) /* trap special handling of 0 in drw_text */ ++ #if BAR_PANGO_PATCH ++ drw_text(drw, x, 0, ftw, bh, lrpad / 2, c->name, 0, False); ++ #else ++ drw_text(drw, x, 0, ftw, bh, lrpad / 2, c->name, 0); ++ #endif // BAR_PANGO_PATCH ++ if (c->isfloating) ++ drw_rect(drw, x + boxs, boxs, boxw, boxw, c->isfixed, 0); ++ x += ftw; ++ w -= ftw; ++ } ++ } ++ return x + w; ++} ++ ++int ++click_fancybar(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ return ClkWinTitle; ++} ++ ++ +diff --git a/patch/bar_fancybar.h b/patch/bar_fancybar.h +new file mode 100644 +index 0000000..c90d189 +--- /dev/null ++++ b/patch/bar_fancybar.h +@@ -0,0 +1,3 @@ ++static int width_fancybar(Bar *bar, BarWidthArg *a); ++static int draw_fancybar(Bar *bar, BarDrawArg *a); ++static int click_fancybar(Bar *bar, Arg *arg, BarClickArg *a); +\ No newline at end of file +diff --git a/patch/include.c b/patch/include.c +index d422f56..2ab4594 100644 +--- a/patch/include.c ++++ b/patch/include.c +@@ -2,4 +2,5 @@ + #include "bar_ltsymbol.c" + #include "bar_status.c" + #include "bar_tags.c" +-#include "bar_wintitle.c" +\ No newline at end of file ++//#include "bar_wintitle.c" ++#include "bar_fancybar.c" +\ No newline at end of file +diff --git a/patch/include.h b/patch/include.h +index 5f9a3fe..4eab55d 100644 +--- a/patch/include.h ++++ b/patch/include.h +@@ -2,4 +2,5 @@ + #include "bar_ltsymbol.h" + #include "bar_status.h" + #include "bar_tags.h" +-#include "bar_wintitle.h" +\ No newline at end of file ++//#include "bar_wintitle.h" ++#include "bar_fancybar.h" +\ No newline at end of file +-- +2.19.1 + diff --git a/dwm/dwm-barmodules-powerline-6.2.diff b/dwm/dwm-barmodules-powerline-6.2.diff new file mode 100644 index 0000000..f423636 --- /dev/null +++ b/dwm/dwm-barmodules-powerline-6.2.diff @@ -0,0 +1,479 @@ +From de9e4c3cd933812c12b217c46f97b314584ed507 Mon Sep 17 00:00:00 2001 +From: bakkeby +Date: Mon, 20 Jul 2020 10:35:17 +0200 +Subject: [PATCH 2/2] Adding powerline module + +--- + config.def.h | 10 ++- + drw.c | 41 +++++++++++ + drw.h | 2 + + dwm.c | 7 ++ + patch/bar_powerline_status.c | 121 +++++++++++++++++++++++++++++++++ + patch/bar_powerline_status.h | 11 +++ + patch/bar_powerline_tags.c | 127 +++++++++++++++++++++++++++++++++++ + patch/bar_powerline_tags.h | 3 + + patch/include.c | 8 ++- + patch/include.h | 8 ++- + 10 files changed, 330 insertions(+), 8 deletions(-) + create mode 100644 patch/bar_powerline_status.c + create mode 100644 patch/bar_powerline_status.h + create mode 100644 patch/bar_powerline_tags.c + create mode 100644 patch/bar_powerline_tags.h + +diff --git a/config.def.h b/config.def.h +index 2534eac..08bc30d 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -18,6 +18,12 @@ static const char *colors[][3] = { + [SchemeSel] = { col_gray4, col_cyan, col_cyan }, + }; + ++static const char *statuscolors[][3] = { ++ /* fg bg border */ ++ [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, ++ [SchemeSel] = { col_gray4, col_cyan, col_cyan }, ++}; ++ + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + +@@ -45,9 +51,9 @@ static const Rule rules[] = { + */ + static const BarRule barrules[] = { + /* monitor bar alignment widthfunc drawfunc clickfunc name */ +- { -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, "tags" }, ++ { -1, 0, BAR_ALIGN_LEFT, width_pwrl_tags, draw_pwrl_tags, click_pwrl_tags, "powerline_tags" }, + { -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, "layout" }, +- { 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" }, ++ { 'A', 0, BAR_ALIGN_RIGHT, width_pwrl_status, draw_pwrl_status, click_pwrl_status, "powerline_status" }, + { -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, "wintitle" }, + }; + +diff --git a/drw.c b/drw.c +index 8fd1ca4..fc449c5 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) +@@ -235,6 +236,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) + { +@@ -378,6 +388,37 @@ 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 || !drw->scheme) ++ 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 }, ++ }; ++ ++ XPoint bg[] = { ++ {x , y }, ++ {x + w, y }, ++ {x + w, y + h}, ++ {x , y + h}, ++ }; ++ ++ XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel); ++ XFillPolygon(drw->dpy, drw->drawable, drw->gc, bg, 4, Convex, CoordModeOrigin); ++ 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..4a42557 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 03dccfb..0e147de 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -1729,6 +1729,13 @@ 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++) ++ #if BAR_ALPHA_PATCH ++ statusscheme[i] = drw_scm_create(drw, statuscolors[i], alphas[0], ColCount); ++ #else ++ statusscheme[i] = drw_scm_create(drw, statuscolors[i], 3); ++ #endif // BAR_ALPHA_PATCH + /* init bars */ + updatebars(); + updatestatus(); +diff --git a/patch/bar_powerline_status.c b/patch/bar_powerline_status.c +new file mode 100644 +index 0000000..3e2ee6a +--- /dev/null ++++ b/patch/bar_powerline_status.c +@@ -0,0 +1,121 @@ ++static Clr **statusscheme; ++ ++int ++width_pwrl_status(Bar *bar, BarWidthArg *a) ++{ ++ #if BAR_STATUSCMD_PATCH ++ return widthpowerlinestatus(rawstext); ++ #else ++ return widthpowerlinestatus(stext); ++ #endif // BAR_STATUSCMD_PATCH ++} ++ ++#if BAR_EXTRASTATUS_PATCH ++int ++width_pwrl_status_es(Bar *bar, BarWidthArg *a) ++{ ++ #if BAR_STATUSCMD_PATCH ++ return widthpowerlinestatus(rawestext); ++ #else ++ return widthpowerlinestatus(estext); ++ #endif // BAR_STATUSCMD_PATCH ++} ++#endif // BAR_EXTRASTATUS_PATCH ++ ++int ++draw_pwrl_status(Bar *bar, BarDrawArg *a) ++{ ++ #if BAR_STATUSCMD_PATCH ++ return drawpowerlinestatus(a->x + a->w, rawstext); ++ #else ++ return drawpowerlinestatus(a->x + a->w, stext); ++ #endif // BAR_STATUSCMD_PATCH ++} ++ ++#if BAR_EXTRASTATUS_PATCH ++int ++draw_pwrl_status_es(Bar *bar, BarDrawArg *a) ++{ ++ #if BAR_STATUSCMD_PATCH ++ return drawpowerlinestatus(a->x + a->w, rawestext); ++ #else ++ return drawpowerlinestatus(a->x + a->w, estext); ++ #endif // BAR_STATUSCMD_PATCH ++} ++#endif // BAR_EXTRASTATUS_PATCH ++ ++int ++click_pwrl_status(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ return ClkStatusText; ++} ++ ++int ++widthpowerlinestatus(char *stext) ++{ ++ char status[512]; ++ int w = 0, i, n = strlen(stext); ++ int plw = drw->fonts->h / 2 + 1; ++ char *bs, bp = '|'; ++ strcpy(status, stext); ++ ++ for (i = n, bs = &status[n-1]; i >= 0; i--, bs--) { ++ if (*bs == '<' || *bs == '/' || *bs == '\\' || *bs == '>' || *bs == '|') { /* block start */ ++ if (bp != '|') ++ w += plw; ++ w += TEXTW(bs+2); ++ bp = *bs; ++ *bs = 0; ++ } ++ } ++ if (bp != '|') ++ w += plw * 2; ++ ++ return w; ++} ++ ++int ++drawpowerlinestatus(int xpos, char *stext) ++{ ++ char status[512]; ++ int i, n = strlen(stext), cn = 0; ++ int x = xpos, w = 0; ++ int plw = drw->fonts->h / 2 + 1; ++ 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 == '>' || *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 == '\\' || 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 == '\\' || bp == '>' ? 1 : 0, bp == '<' ? 0 : 1); ++ drw_rect(drw, x - 2 * plw, 0, plw, bh, 1, 1); ++ x -= plw * 2; ++ } ++ ++ return xpos - x; ++} +\ No newline at end of file +diff --git a/patch/bar_powerline_status.h b/patch/bar_powerline_status.h +new file mode 100644 +index 0000000..2ff5ad2 +--- /dev/null ++++ b/patch/bar_powerline_status.h +@@ -0,0 +1,11 @@ ++static int width_pwrl_status(Bar *bar, BarWidthArg *a); ++#if BAR_EXTRASTATUS_PATCH ++static int width_pwrl_status_es(Bar *bar, BarWidthArg *a); ++#endif // BAR_EXTRASTATUS_PATCH ++static int draw_pwrl_status(Bar *bar, BarDrawArg *a); ++#if BAR_EXTRASTATUS_PATCH ++static int draw_pwrl_status_es(Bar *bar, BarDrawArg *a); ++#endif // BAR_EXTRASTATUS_PATCH ++static int click_pwrl_status(Bar *bar, Arg *arg, BarClickArg *a); ++static int drawpowerlinestatus(int x, char *stext); ++static int widthpowerlinestatus(char *stext); +\ No newline at end of file +diff --git a/patch/bar_powerline_tags.c b/patch/bar_powerline_tags.c +new file mode 100644 +index 0000000..a85559b +--- /dev/null ++++ b/patch/bar_powerline_tags.c +@@ -0,0 +1,127 @@ ++int ++width_pwrl_tags(Bar *bar, BarWidthArg *a) ++{ ++ int w, i; ++ int plw = drw->fonts->h / 2 + 1; ++ #if BAR_HIDEVACANTTAGS_PATCH ++ Client *c; ++ unsigned int occ = 0; ++ for (c = bar->mon->clients; c; c = c->next) ++ occ |= c->tags == 255 ? 0 : c->tags; ++ #endif // BAR_HIDEVACANTTAGS_PATCH ++ ++ for (w = 0, i = 0; i < LENGTH(tags); i++) { ++ #if BAR_HIDEVACANTTAGS_PATCH ++ if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) ++ continue; ++ #endif // BAR_HIDEVACANTTAGS_PATCH ++ #if BAR_ALTERNATIVE_TAGS_PATCH ++ w += selmon->alttag ? TEXTW(tagsalt[i]) : TEXTW(tags[i]) + plw; ++ #else ++ w += TEXTW(tags[i]) + plw; ++ #endif // BAR_ALTERNATIVE_TAGS_PATCH ++ } ++ return w + lrpad; ++} ++ ++int ++draw_pwrl_tags(Bar *bar, BarDrawArg *a) ++{ ++ int x, w; ++ int invert; ++ int plw = drw->fonts->h / 2 + 1; ++ unsigned int i, occ = 0, urg = 0; ++ Client *c; ++ Clr *prevscheme, *nxtscheme; ++ #if !BAR_HIDEVACANTTAGS_PATCH ++ #if !BAR_ACTIVETAGINDICATORBAR_PATCH && !BAR_ACTIVETAGINDICATORBAR_ALT1_PATCH ++ int boxs = drw->fonts->h / 9; ++ #endif // BAR_ACTIVETAGINDICATORBAR_PATCH | BAR_ACTIVETAGINDICATORBAR_ALT1_PATCH ++ int boxw = drw->fonts->h / 6 + 2; ++ #endif // BAR_HIDEVACANTTAGS_PATCH ++ ++ for (c = bar->mon->clients; c; c = c->next) { ++ #if BAR_HIDEVACANTTAGS_PATCH ++ occ |= c->tags == 255 ? 0 : c->tags; ++ #else ++ occ |= c->tags; ++ #endif // BAR_HIDEVACANTTAGS_PATCH ++ if (c->isurgent) ++ urg |= c->tags; ++ } ++ x = a->x; ++ prevscheme = scheme[SchemeNorm]; ++ for (i = 0; i < LENGTH(tags); i++) { ++ #if BAR_HIDEVACANTTAGS_PATCH ++ /* do not draw vacant tags */ ++ if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) ++ continue; ++ #endif // BAR_HIDEVACANTTAGS_PATCH ++ #if URGENTBORDER_PATCH ++ invert = 0; ++ #else ++ invert = urg & 1 << i; ++ #endif // URGENTBORDER_PATCH ++ w = TEXTW(tags[i]); ++ drw_settrans(drw, prevscheme, (nxtscheme = scheme[bar->mon->tagset[bar->mon->seltags] & 1 << i ? SchemeSel : SchemeNorm])); ++ #if BAR_POWERLINE_TAGS_SLASH_PATCH ++ drw_arrow(drw, x, 0, plw, bh, 1, 1); ++ #else ++ drw_arrow(drw, x, 0, plw, bh, 1, 1); ++ #endif // BAR_POWERLINE_TAGS_SLASH_PATCH ++ x += plw; ++ drw_setscheme(drw, nxtscheme); ++ drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], invert); ++ #if !BAR_HIDEVACANTTAGS_PATCH ++ if (occ & 1 << i) ++ #if BAR_ACTIVETAGINDICATORBAR_PATCH ++ drw_rect(drw, x + boxw, 0, w - ( 2 * boxw + 1), boxw, ++ #elif BAR_ACTIVETAGINDICATORBAR_ALT1_PATCH ++ drw_rect(drw, x + boxw, bh - boxw/2, w - ( 2 * boxw + 1), boxw/2, ++ #else ++ drw_rect(drw, x + boxs, boxs, boxw, boxw, ++ #endif // BAR_ACTIVETAGINDICATORBAR_PATCH ++ bar->mon == selmon && selmon->sel && selmon->sel->tags & 1 << i, invert); ++ #endif // BAR_HIDEVACANTTAGS_PATCH ++ x += w; ++ prevscheme = nxtscheme; ++ } ++ nxtscheme = scheme[SchemeNorm]; ++ ++ drw_settrans(drw, prevscheme, nxtscheme); ++ #if BAR_POWERLINE_TAGS_SLASH_PATCH ++ drw_arrow(drw, x, 0, plw, bh, 1, 1); ++ #else ++ drw_arrow(drw, x, 0, plw, bh, 1, 0); ++ #endif // BAR_POWERLINE_TAGS_SLASH_PATCH ++ return a->x + a->w; ++} ++ ++int ++click_pwrl_tags(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ int i = 0, x = lrpad / 2; ++ int plw = drw->fonts->h / 2 + 1; ++ #if BAR_HIDEVACANTTAGS_PATCH ++ Client *c; ++ unsigned int occ = 0; ++ for (c = bar->mon->clients; c; c = c->next) ++ occ |= c->tags == 255 ? 0 : c->tags; ++ #endif // BAR_HIDEVACANTTAGS_PATCH ++ ++ do { ++ #if BAR_HIDEVACANTTAGS_PATCH ++ if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) ++ continue; ++ #endif // BAR_HIDEVACANTTAGS_PATCH ++ #if BAR_ALTERNATIVE_TAGS_PATCH ++ x += selmon->alttag ? TEXTW(tagsalt[i]) : TEXTW(tags[i]) + plw; ++ #else ++ x += TEXTW(tags[i]) + plw; ++ #endif ++ } while (a->rel_x >= x && ++i < LENGTH(tags)); ++ if (i < LENGTH(tags)) { ++ arg->ui = 1 << i; ++ } ++ return ClkTagBar; ++} +\ No newline at end of file +diff --git a/patch/bar_powerline_tags.h b/patch/bar_powerline_tags.h +new file mode 100644 +index 0000000..b1e0389 +--- /dev/null ++++ b/patch/bar_powerline_tags.h +@@ -0,0 +1,3 @@ ++static int width_pwrl_tags(Bar *bar, BarWidthArg *a); ++static int draw_pwrl_tags(Bar *bar, BarDrawArg *a); ++static int click_pwrl_tags(Bar *bar, Arg *arg, BarClickArg *a); +\ No newline at end of file +diff --git a/patch/include.c b/patch/include.c +index d422f56..48ce1cb 100644 +--- a/patch/include.c ++++ b/patch/include.c +@@ -1,5 +1,7 @@ + /* Bar functionality */ + #include "bar_ltsymbol.c" +-#include "bar_status.c" +-#include "bar_tags.c" +-#include "bar_wintitle.c" +\ No newline at end of file ++//#include "bar_status.c" ++//#include "bar_tags.c" ++#include "bar_wintitle.c" ++#include "bar_powerline_tags.c" ++#include "bar_powerline_status.c" +\ No newline at end of file +diff --git a/patch/include.h b/patch/include.h +index 5f9a3fe..b313ca4 100644 +--- a/patch/include.h ++++ b/patch/include.h +@@ -1,5 +1,7 @@ + /* Bar functionality */ + #include "bar_ltsymbol.h" +-#include "bar_status.h" +-#include "bar_tags.h" +-#include "bar_wintitle.h" +\ No newline at end of file ++//#include "bar_status.h" ++//#include "bar_tags.h" ++#include "bar_wintitle.h" ++#include "bar_powerline_tags.h" ++#include "bar_powerline_status.h" +\ No newline at end of file +-- +2.19.1 + diff --git a/dwm/dwm-barmodules-status2d-6.2.diff b/dwm/dwm-barmodules-status2d-6.2.diff new file mode 100644 index 0000000..44b5fcf --- /dev/null +++ b/dwm/dwm-barmodules-status2d-6.2.diff @@ -0,0 +1,338 @@ +From 93edaff15965265341286bf6f3da34c444a94839 Mon Sep 17 00:00:00 2001 +From: bakkeby +Date: Mon, 20 Jul 2020 15:17:52 +0200 +Subject: [PATCH 2/2] Adding status2d module + +--- + config.def.h | 2 +- + dwm.c | 6 +- + patch/bar_status2d.c | 218 +++++++++++++++++++++++++++++++++++++++++++ + patch/bar_status2d.h | 13 +++ + patch/include.c | 5 +- + patch/include.h | 5 +- + 6 files changed, 241 insertions(+), 8 deletions(-) + create mode 100644 patch/bar_status2d.c + create mode 100644 patch/bar_status2d.h + +diff --git a/config.def.h b/config.def.h +index 2534eac..5acf4e5 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -47,7 +47,7 @@ static const BarRule barrules[] = { + /* monitor bar alignment widthfunc drawfunc clickfunc name */ + { -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, "tags" }, + { -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, "layout" }, +- { 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" }, ++ { 'A', 0, BAR_ALIGN_RIGHT, width_status2d, draw_status2d, click_status2d, "status2d" }, + { -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, "wintitle" }, + }; + +diff --git a/dwm.c b/dwm.c +index 03dccfb..49eaccb 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -289,7 +289,7 @@ static void zoom(const Arg *arg); + #include "patch/include.h" + /* variables */ + static const char broken[] = "broken"; +-static char stext[256]; ++static char stext[1024]; + static int screen; + static int sw, sh; /* X display screen geometry width, height */ + static int bh; /* bar geometry */ +@@ -557,7 +557,7 @@ cleanup(void) + cleanupmon(mons); + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); +- for (i = 0; i < LENGTH(colors); i++) ++ for (i = 0; i < LENGTH(colors) + 1; i++) + free(scheme[i]); + XDestroyWindow(dpy, wmcheckwin); + drw_free(drw); +@@ -1726,7 +1726,7 @@ setup(void) + cursor[CurResize] = drw_cur_create(drw, XC_sizing); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); + /* init appearance */ +- scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); ++ scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); + for (i = 0; i < LENGTH(colors); i++) + scheme[i] = drw_scm_create(drw, colors[i], 3); + /* init bars */ +diff --git a/patch/bar_status2d.c b/patch/bar_status2d.c +new file mode 100644 +index 0000000..06944c4 +--- /dev/null ++++ b/patch/bar_status2d.c +@@ -0,0 +1,218 @@ ++int ++width_status2d(Bar *bar, BarWidthArg *a) ++{ ++ #if BAR_STATUSCMD_PATCH ++ return status2dtextlength(rawstext) + lrpad; ++ #else ++ return status2dtextlength(stext) + lrpad; ++ #endif // BAR_STATUSCMD_PATCH ++} ++ ++#if BAR_EXTRASTATUS_PATCH ++int ++width_status2d_es(Bar *bar, BarWidthArg *a) ++{ ++ #if BAR_STATUSCMD_PATCH ++ return status2dtextlength(rawestext); ++ #else ++ return status2dtextlength(estext); ++ #endif // BAR_STATUSCMD_PATCH ++} ++#endif // BAR_EXTRASTATUS_PATCH ++ ++int ++draw_status2d(Bar *bar, BarDrawArg *a) ++{ ++ #if BAR_STATUSCMD_PATCH ++ return drawstatusbar(a->x, rawstext); ++ #else ++ return drawstatusbar(a->x, stext); ++ #endif // BAR_STATUSCMD_PATCH ++} ++ ++#if BAR_EXTRASTATUS_PATCH ++int ++draw_status2d_es(Bar *bar, BarDrawArg *a) ++{ ++ #if BAR_STATUSCMD_PATCH ++ return drawstatusbar(a->x, rawestext); ++ #else ++ return drawstatusbar(a->x, estext); ++ #endif // BAR_STATUSCMD_PATCH ++} ++#endif // BAR_EXTRASTATUS_PATCH ++ ++#if !BAR_STATUSCMD_PATCH ++int ++click_status2d(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ return ClkStatusText; ++} ++#endif // BAR_STATUSCMD_PATCH ++ ++int ++drawstatusbar(int x, char* stext) ++{ ++ int i, w, len; ++ short isCode = 0; ++ char *text; ++ char *p; ++ ++ len = strlen(stext) + 1; ++ if (!(text = (char*) malloc(sizeof(char)*len))) ++ die("malloc"); ++ p = text; ++ #if BAR_STATUSCMD_PATCH ++ copyvalidchars(text, stext); ++ #else ++ memcpy(text, stext, len); ++ #endif // BAR_STATUSCMD_PATCH ++ ++ x += lrpad / 2; ++ ++ /* process status text */ ++ i = -1; ++ while (text[++i]) { ++ if (text[i] == '^' && !isCode) { ++ isCode = 1; ++ ++ text[i] = '\0'; ++ #if BAR_PANGO_PATCH ++ w = TEXTWM(text) - lrpad; ++ drw_text(drw, x, 0, w, bh, 0, text, 0, True); ++ #else ++ w = TEXTW(text) - lrpad; ++ drw_text(drw, x, 0, w, bh, 0, text, 0); ++ #endif // BAR_PANGO_PATCH ++ ++ x += w; ++ ++ /* process code */ ++ while (text[++i] != '^') { ++ if (text[i] == 'c') { ++ char buf[8]; ++ if (i + 7 > len) { ++ i += 7; ++ break; ++ } ++ memcpy(buf, (char*)text+i+1, 7); ++ buf[7] = '\0'; ++ #if BAR_ALPHA_PATCH && BAR_STATUS2D_NO_ALPHA_PATCH ++ drw_clr_create(drw, &drw->scheme[ColFg], buf, 0xff); ++ #elif BAR_ALPHA_PATCH ++ drw_clr_create(drw, &drw->scheme[ColFg], buf, alphas[SchemeNorm][ColFg]); ++ #else ++ drw_clr_create(drw, &drw->scheme[ColFg], buf); ++ #endif // BAR_ALPHA_PATCH ++ i += 7; ++ } else if (text[i] == 'b') { ++ char buf[8]; ++ if (i + 7 > len) { ++ i += 7; ++ break; ++ } ++ memcpy(buf, (char*)text+i+1, 7); ++ buf[7] = '\0'; ++ #if BAR_ALPHA_PATCH && BAR_STATUS2D_NO_ALPHA_PATCH ++ drw_clr_create(drw, &drw->scheme[ColBg], buf, 0xff); ++ #elif BAR_ALPHA_PATCH ++ drw_clr_create(drw, &drw->scheme[ColBg], buf, alphas[SchemeNorm][ColBg]); ++ #else ++ drw_clr_create(drw, &drw->scheme[ColBg], buf); ++ #endif // BAR_ALPHA_PATCH ++ i += 7; ++ } else if (text[i] == 'd') { ++ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; ++ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; ++ } else if (text[i] == 'r') { ++ int rx = atoi(text + ++i); ++ while (text[++i] != ','); ++ int ry = atoi(text + ++i); ++ while (text[++i] != ','); ++ int rw = atoi(text + ++i); ++ while (text[++i] != ','); ++ int rh = atoi(text + ++i); ++ ++ if (ry < 0) ++ ry = 0; ++ if (rx < 0) ++ rx = 0; ++ ++ drw_rect(drw, rx + x, ry, rw, rh, 1, 0); ++ } else if (text[i] == 'f') { ++ x += atoi(text + ++i); ++ } ++ } ++ ++ text = text + i + 1; ++ i=-1; ++ isCode = 0; ++ } ++ } ++ if (!isCode) { ++ #if BAR_PANGO_PATCH ++ w = TEXTWM(text) - lrpad; ++ drw_text(drw, x, 0, w, bh, 0, text, 0, True); ++ #else ++ w = TEXTW(text) - lrpad; ++ drw_text(drw, x, 0, w, bh, 0, text, 0); ++ #endif // BAR_PANGO_PATCH ++ x += w; ++ } ++ free(p); ++ ++ drw_setscheme(drw, scheme[SchemeNorm]); ++ ++ return x; ++} ++ ++int ++status2dtextlength(char* stext) ++{ ++ int i, w, len; ++ short isCode = 0; ++ char *text; ++ char *p; ++ ++ len = strlen(stext) + 1; ++ if (!(text = (char*) malloc(sizeof(char)*len))) ++ die("malloc"); ++ p = text; ++ #if BAR_STATUSCMD_PATCH ++ copyvalidchars(text, stext); ++ #else ++ memcpy(text, stext, len); ++ #endif // BAR_STATUSCMD_PATCH ++ ++ /* compute width of the status text */ ++ w = 0; ++ i = -1; ++ while (text[++i]) { ++ if (text[i] == '^') { ++ if (!isCode) { ++ isCode = 1; ++ text[i] = '\0'; ++ #if BAR_PANGO_PATCH ++ w += TEXTWM(text) - lrpad; ++ #else ++ w += TEXTW(text) - lrpad; ++ #endif // BAR_PANGO_PATCH ++ text[i] = '^'; ++ if (text[++i] == 'f') ++ w += atoi(text + ++i); ++ } else { ++ isCode = 0; ++ text = text + i + 1; ++ i = -1; ++ } ++ } ++ } ++ if (!isCode) ++ #if BAR_PANGO_PATCH ++ w += TEXTWM(text) - lrpad; ++ #else ++ w += TEXTW(text) - lrpad; ++ #endif // BAR_PANGO_PATCH ++ free(p); ++ return w; ++} +\ No newline at end of file +diff --git a/patch/bar_status2d.h b/patch/bar_status2d.h +new file mode 100644 +index 0000000..ea48dd3 +--- /dev/null ++++ b/patch/bar_status2d.h +@@ -0,0 +1,13 @@ ++static int width_status2d(Bar *bar, BarWidthArg *a); ++#if BAR_EXTRASTATUS_PATCH ++static int width_status2d_es(Bar *bar, BarWidthArg *a); ++#endif // BAR_EXTRASTATUS_PATCH ++static int draw_status2d(Bar *bar, BarDrawArg *a); ++#if BAR_EXTRASTATUS_PATCH ++static int draw_status2d_es(Bar *bar, BarDrawArg *a); ++#endif // BAR_EXTRASTATUS_PATCH ++#if !BAR_STATUSCMD_PATCH ++static int click_status2d(Bar *bar, Arg *arg, BarClickArg *a); ++#endif // BAR_STATUSCMD_PATCH ++static int drawstatusbar(int x, char *text); ++static int status2dtextlength(char *stext); +\ No newline at end of file +diff --git a/patch/include.c b/patch/include.c +index d422f56..77eafa3 100644 +--- a/patch/include.c ++++ b/patch/include.c +@@ -1,5 +1,6 @@ + /* Bar functionality */ + #include "bar_ltsymbol.c" +-#include "bar_status.c" ++//#include "bar_status.c" + #include "bar_tags.c" +-#include "bar_wintitle.c" +\ No newline at end of file ++#include "bar_wintitle.c" ++#include "bar_status2d.c" +\ No newline at end of file +diff --git a/patch/include.h b/patch/include.h +index 5f9a3fe..2927238 100644 +--- a/patch/include.h ++++ b/patch/include.h +@@ -1,5 +1,6 @@ + /* Bar functionality */ + #include "bar_ltsymbol.h" +-#include "bar_status.h" ++//#include "bar_status.h" + #include "bar_tags.h" +-#include "bar_wintitle.h" +\ No newline at end of file ++#include "bar_wintitle.h" ++#include "bar_status2d.h" +\ No newline at end of file +-- +2.19.1 + diff --git a/dwm/dwm-barmodules-status2d-statuscmd-dwmblocks-extrastatus-6.2.diff b/dwm/dwm-barmodules-status2d-statuscmd-dwmblocks-extrastatus-6.2.diff new file mode 100644 index 0000000..64ce744 --- /dev/null +++ b/dwm/dwm-barmodules-status2d-statuscmd-dwmblocks-extrastatus-6.2.diff @@ -0,0 +1,451 @@ +From 7137e20390f314b6b561c1c26ae943ccd8981006 Mon Sep 17 00:00:00 2001 +From: bakkeby +Date: Mon, 20 Jul 2020 15:17:52 +0200 +Subject: [PATCH 2/2] Adding status2d + statuscmd + dwmblocks + extrastatus + module + +--- + config.def.h | 11 ++- + dwm.c | 22 ++++-- + patch/bar_dwmblocks.c | 31 ++++++++ + patch/bar_dwmblocks.h | 2 + + patch/bar_status2d.c | 164 ++++++++++++++++++++++++++++++++++++++++++ + patch/bar_status2d.h | 6 ++ + patch/bar_statuscmd.c | 49 +++++++++++++ + patch/bar_statuscmd.h | 4 ++ + patch/include.c | 7 +- + patch/include.h | 7 +- + 10 files changed, 293 insertions(+), 10 deletions(-) + create mode 100644 patch/bar_dwmblocks.c + create mode 100644 patch/bar_dwmblocks.h + create mode 100644 patch/bar_status2d.c + create mode 100644 patch/bar_status2d.h + create mode 100644 patch/bar_statuscmd.c + create mode 100644 patch/bar_statuscmd.h + +diff --git a/config.def.h b/config.def.h +index 2534eac..40541cb 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -5,6 +5,7 @@ static const unsigned int borderpx = 1; /* border pixel of 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 */ ++static const char statussep = ';'; /* separator between status bars */ + static const char *fonts[] = { "monospace:size=10" }; + static const char dmenufont[] = "monospace:size=10"; + static const char col_gray1[] = "#222222"; +@@ -47,8 +48,10 @@ static const BarRule barrules[] = { + /* monitor bar alignment widthfunc drawfunc clickfunc name */ + { -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, "tags" }, + { -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, "layout" }, +- { 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" }, ++ { 'A', 0, BAR_ALIGN_RIGHT, width_status2d, draw_status2d, click_statuscmd, "status2d" }, + { -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, "wintitle" }, ++ { 0, 1, BAR_ALIGN_CENTER, width_status2d_es, draw_status2d_es, click_statuscmd_es, "status2d_es" }, ++ + }; + + /* layout(s) */ +@@ -123,7 +126,11 @@ static Button buttons[] = { + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, +- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, ++ { ClkStatusText, 0, Button1, sigdwmblocks, {.i = 1 } }, ++ { ClkStatusText, 0, Button2, sigdwmblocks, {.i = 2 } }, ++ { ClkStatusText, 0, Button3, sigdwmblocks, {.i = 3 } }, ++ { ClkStatusText, 0, Button4, sigdwmblocks, {.i = 4 } }, ++ { ClkStatusText, 0, Button5, sigdwmblocks, {.i = 5 } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, +diff --git a/dwm.c b/dwm.c +index 03dccfb..030c8a3 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -289,7 +289,10 @@ static void zoom(const Arg *arg); + #include "patch/include.h" + /* variables */ + static const char broken[] = "broken"; +-static char stext[256]; ++static char stext[1024]; ++static char rawstext[1024]; ++static char estext[1024]; ++static char rawestext[1024]; + static int screen; + static int sw, sh; /* X display screen geometry width, height */ + static int bh; /* bar geometry */ +@@ -557,7 +560,7 @@ cleanup(void) + cleanupmon(mons); + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); +- for (i = 0; i < LENGTH(colors); i++) ++ for (i = 0; i < LENGTH(colors) + 1; i++) + free(scheme[i]); + XDestroyWindow(dpy, wmcheckwin); + drw_free(drw); +@@ -1726,7 +1729,7 @@ setup(void) + cursor[CurResize] = drw_cur_create(drw, XC_sizing); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); + /* init appearance */ +- scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); ++ scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); + for (i = 0; i < LENGTH(colors); i++) + scheme[i] = drw_scm_create(drw, colors[i], 3); + /* init bars */ +@@ -2169,8 +2172,19 @@ void + updatestatus(void) + { + Monitor *m; +- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) ++ if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext))) { + strcpy(stext, "dwm-"VERSION); ++ estext[0] = '\0'; ++ } else { ++ char *e = strchr(rawstext, statussep); ++ if (e) { ++ *e = '\0'; e++; ++ strncpy(rawestext, e, sizeof(estext) - 1); ++ copyvalidchars(estext, rawestext); ++ } else ++ estext[0] = '\0'; ++ copyvalidchars(stext, rawstext); ++ } + for (m = mons; m; m = m->next) + drawbar(m); + } +diff --git a/patch/bar_dwmblocks.c b/patch/bar_dwmblocks.c +new file mode 100644 +index 0000000..442b0bc +--- /dev/null ++++ b/patch/bar_dwmblocks.c +@@ -0,0 +1,31 @@ ++static int dwmblockssig; ++pid_t dwmblockspid = 0; ++ ++int ++getdwmblockspid() ++{ ++ char buf[16]; ++ FILE *fp = popen("pidof -s dwmblocks", "r"); ++ if (fgets(buf, sizeof(buf), fp)); ++ pid_t pid = strtoul(buf, NULL, 10); ++ pclose(fp); ++ dwmblockspid = pid; ++ return pid != 0 ? 0 : -1; ++} ++ ++void ++sigdwmblocks(const Arg *arg) ++{ ++ union sigval sv; ++ sv.sival_int = (dwmblockssig << 8) | arg->i; ++ if (!dwmblockspid) ++ if (getdwmblockspid() == -1) ++ return; ++ ++ if (sigqueue(dwmblockspid, SIGUSR1, sv) == -1) { ++ if (errno == ESRCH) { ++ if (!getdwmblockspid()) ++ sigqueue(dwmblockspid, SIGUSR1, sv); ++ } ++ } ++} +\ No newline at end of file +diff --git a/patch/bar_dwmblocks.h b/patch/bar_dwmblocks.h +new file mode 100644 +index 0000000..f08f1d5 +--- /dev/null ++++ b/patch/bar_dwmblocks.h +@@ -0,0 +1,2 @@ ++static int getdwmblockspid(); ++static void sigdwmblocks(const Arg *arg); +\ No newline at end of file +diff --git a/patch/bar_status2d.c b/patch/bar_status2d.c +new file mode 100644 +index 0000000..e8d72aa +--- /dev/null ++++ b/patch/bar_status2d.c +@@ -0,0 +1,164 @@ ++int ++width_status2d(Bar *bar, BarWidthArg *a) ++{ ++ return status2dtextlength(rawstext) + lrpad; ++} ++ ++int ++width_status2d_es(Bar *bar, BarWidthArg *a) ++{ ++ return status2dtextlength(rawestext); ++} ++ ++int ++draw_status2d(Bar *bar, BarDrawArg *a) ++{ ++ return drawstatusbar(a->x, rawstext); ++} ++ ++int ++draw_status2d_es(Bar *bar, BarDrawArg *a) ++{ ++ return drawstatusbar(a->x, rawestext); ++} ++ ++int ++drawstatusbar(int x, char* stext) ++{ ++ int i, w, len; ++ short isCode = 0; ++ char *text; ++ char *p; ++ ++ len = strlen(stext) + 1; ++ if (!(text = (char*) malloc(sizeof(char)*len))) ++ die("malloc"); ++ p = text; ++ copyvalidchars(text, stext); ++ ++ x += lrpad / 2; ++ ++ /* process status text */ ++ i = -1; ++ while (text[++i]) { ++ if (text[i] == '^' && !isCode) { ++ isCode = 1; ++ ++ text[i] = '\0'; ++ w = TEXTW(text) - lrpad; ++ drw_text(drw, x, 0, w, bh, 0, text, 0); ++ ++ x += w; ++ ++ /* process code */ ++ while (text[++i] != '^') { ++ if (text[i] == 'c') { ++ char buf[8]; ++ if (i + 7 > len) { ++ i += 7; ++ break; ++ } ++ memcpy(buf, (char*)text+i+1, 7); ++ buf[7] = '\0'; ++ #if BAR_ALPHA_PATCH && BAR_STATUS2D_NO_ALPHA_PATCH ++ drw_clr_create(drw, &drw->scheme[ColFg], buf, 0xff); ++ #elif BAR_ALPHA_PATCH ++ drw_clr_create(drw, &drw->scheme[ColFg], buf, alphas[SchemeNorm][ColFg]); ++ #else ++ drw_clr_create(drw, &drw->scheme[ColFg], buf); ++ #endif // BAR_ALPHA_PATCH ++ i += 7; ++ } else if (text[i] == 'b') { ++ char buf[8]; ++ if (i + 7 > len) { ++ i += 7; ++ break; ++ } ++ memcpy(buf, (char*)text+i+1, 7); ++ buf[7] = '\0'; ++ #if BAR_ALPHA_PATCH && BAR_STATUS2D_NO_ALPHA_PATCH ++ drw_clr_create(drw, &drw->scheme[ColBg], buf, 0xff); ++ #elif BAR_ALPHA_PATCH ++ drw_clr_create(drw, &drw->scheme[ColBg], buf, alphas[SchemeNorm][ColBg]); ++ #else ++ drw_clr_create(drw, &drw->scheme[ColBg], buf); ++ #endif // BAR_ALPHA_PATCH ++ i += 7; ++ } else if (text[i] == 'd') { ++ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; ++ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; ++ } else if (text[i] == 'r') { ++ int rx = atoi(text + ++i); ++ while (text[++i] != ','); ++ int ry = atoi(text + ++i); ++ while (text[++i] != ','); ++ int rw = atoi(text + ++i); ++ while (text[++i] != ','); ++ int rh = atoi(text + ++i); ++ ++ if (ry < 0) ++ ry = 0; ++ if (rx < 0) ++ rx = 0; ++ ++ drw_rect(drw, rx + x, ry, rw, rh, 1, 0); ++ } else if (text[i] == 'f') { ++ x += atoi(text + ++i); ++ } ++ } ++ ++ text = text + i + 1; ++ i=-1; ++ isCode = 0; ++ } ++ } ++ if (!isCode) { ++ w = TEXTW(text) - lrpad; ++ drw_text(drw, x, 0, w, bh, 0, text, 0); ++ x += w; ++ } ++ free(p); ++ ++ drw_setscheme(drw, scheme[SchemeNorm]); ++ ++ return x; ++} ++ ++int ++status2dtextlength(char* stext) ++{ ++ int i, w, len; ++ short isCode = 0; ++ char *text; ++ char *p; ++ ++ len = strlen(stext) + 1; ++ if (!(text = (char*) malloc(sizeof(char)*len))) ++ die("malloc"); ++ p = text; ++ copyvalidchars(text, stext); ++ ++ /* compute width of the status text */ ++ w = 0; ++ i = -1; ++ while (text[++i]) { ++ if (text[i] == '^') { ++ if (!isCode) { ++ isCode = 1; ++ text[i] = '\0'; ++ w += TEXTW(text) - lrpad; ++ text[i] = '^'; ++ if (text[++i] == 'f') ++ w += atoi(text + ++i); ++ } else { ++ isCode = 0; ++ text = text + i + 1; ++ i = -1; ++ } ++ } ++ } ++ if (!isCode) ++ w += TEXTW(text) - lrpad; ++ free(p); ++ return w; ++} +\ No newline at end of file +diff --git a/patch/bar_status2d.h b/patch/bar_status2d.h +new file mode 100644 +index 0000000..0830025 +--- /dev/null ++++ b/patch/bar_status2d.h +@@ -0,0 +1,6 @@ ++static int width_status2d(Bar *bar, BarWidthArg *a); ++static int width_status2d_es(Bar *bar, BarWidthArg *a); ++static int draw_status2d(Bar *bar, BarDrawArg *a); ++static int draw_status2d_es(Bar *bar, BarDrawArg *a); ++static int drawstatusbar(int x, char *text); ++static int status2dtextlength(char *stext); +\ No newline at end of file +diff --git a/patch/bar_statuscmd.c b/patch/bar_statuscmd.c +new file mode 100644 +index 0000000..28ce120 +--- /dev/null ++++ b/patch/bar_statuscmd.c +@@ -0,0 +1,49 @@ ++int ++click_statuscmd(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ return click_statuscmd_text(arg, a->rel_x, rawstext); ++} ++ ++int ++click_statuscmd_es(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ return click_statuscmd_text(arg, a->rel_x, rawestext); ++} ++ ++int ++click_statuscmd_text(Arg *arg, int rel_x, char *text) ++{ ++ int i = -1; ++ int x = 0; ++ char ch; ++ dwmblockssig = -1; ++ while (text[++i]) { ++ if ((unsigned char)text[i] < ' ') { ++ ch = text[i]; ++ text[i] = '\0'; ++ x += status2dtextlength(text); ++ text[i] = ch; ++ text += i+1; ++ i = -1; ++ if (x >= rel_x && dwmblockssig != -1) ++ break; ++ dwmblockssig = ch; ++ } ++ } ++ if (dwmblockssig == -1) ++ dwmblockssig = 0; ++ return ClkStatusText; ++} ++ ++void ++copyvalidchars(char *text, char *rawtext) ++{ ++ int i = -1, j = 0; ++ ++ while (rawtext[++i]) { ++ if ((unsigned char)rawtext[i] >= ' ') { ++ text[j++] = rawtext[i]; ++ } ++ } ++ text[j] = '\0'; ++} +diff --git a/patch/bar_statuscmd.h b/patch/bar_statuscmd.h +new file mode 100644 +index 0000000..d6d428e +--- /dev/null ++++ b/patch/bar_statuscmd.h +@@ -0,0 +1,4 @@ ++static int click_statuscmd(Bar *bar, Arg *arg, BarClickArg *a); ++static int click_statuscmd_es(Bar *bar, Arg *arg, BarClickArg *a); ++static int click_statuscmd_text(Arg *arg, int rel_x, char *text); ++static void copyvalidchars(char *text, char *rawtext); +\ No newline at end of file +diff --git a/patch/include.c b/patch/include.c +index d422f56..84bbd19 100644 +--- a/patch/include.c ++++ b/patch/include.c +@@ -1,5 +1,8 @@ + /* Bar functionality */ + #include "bar_ltsymbol.c" +-#include "bar_status.c" ++//#include "bar_status.c" + #include "bar_tags.c" +-#include "bar_wintitle.c" +\ No newline at end of file ++#include "bar_wintitle.c" ++#include "bar_status2d.c" ++#include "bar_dwmblocks.c" ++#include "bar_statuscmd.c" +\ No newline at end of file +diff --git a/patch/include.h b/patch/include.h +index 5f9a3fe..78f7520 100644 +--- a/patch/include.h ++++ b/patch/include.h +@@ -1,5 +1,8 @@ + /* Bar functionality */ + #include "bar_ltsymbol.h" +-#include "bar_status.h" ++//#include "bar_status.h" + #include "bar_tags.h" +-#include "bar_wintitle.h" +\ No newline at end of file ++#include "bar_wintitle.h" ++#include "bar_status2d.h" ++#include "bar_dwmblocks.h" ++#include "bar_statuscmd.h" +\ No newline at end of file +-- +2.19.1 + diff --git a/dwm/dwm-barmodules-statusbutton-6.2.diff b/dwm/dwm-barmodules-statusbutton-6.2.diff new file mode 100644 index 0000000..861cf43 --- /dev/null +++ b/dwm/dwm-barmodules-statusbutton-6.2.diff @@ -0,0 +1,127 @@ +From 54297429dcf490511076ebc738c9688e113c7731 Mon Sep 17 00:00:00 2001 +From: bakkeby +Date: Mon, 20 Jul 2020 11:48:07 +0200 +Subject: [PATCH 2/2] Adding statusbutton module + +--- + config.def.h | 5 ++++- + dwm.c | 2 +- + patch/bar_statusbutton.c | 21 +++++++++++++++++++++ + patch/bar_statusbutton.h | 3 +++ + patch/include.c | 3 ++- + patch/include.h | 3 ++- + 6 files changed, 33 insertions(+), 4 deletions(-) + create mode 100644 patch/bar_statusbutton.c + create mode 100644 patch/bar_statusbutton.h + +diff --git a/config.def.h b/config.def.h +index 2534eac..b70c552 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -5,6 +5,7 @@ static const unsigned int borderpx = 1; /* border pixel of 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 */ ++static const char buttonbar[] = ""; + static const char *fonts[] = { "monospace:size=10" }; + static const char dmenufont[] = "monospace:size=10"; + static const char col_gray1[] = "#222222"; +@@ -45,6 +46,7 @@ static const Rule rules[] = { + */ + static const BarRule barrules[] = { + /* monitor bar alignment widthfunc drawfunc clickfunc name */ ++ { -1, 0, BAR_ALIGN_LEFT, width_stbutton, draw_stbutton, click_stbutton, "statusbutton" }, + { -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, "tags" }, + { -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, "layout" }, + { 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" }, +@@ -117,9 +119,10 @@ static Key keys[] = { + }; + + /* button definitions */ +-/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ ++/* click can be ClkButton, ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ + static Button buttons[] = { + /* click event mask button function argument */ ++ { ClkButton, 0, Button1, spawn, {.v = dmenucmd } }, + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, +diff --git a/dwm.c b/dwm.c +index 03dccfb..048221b 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -65,7 +65,7 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, + NetWMFullscreen, NetActiveWindow, NetWMWindowType, + NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ + enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ +-enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ++enum { ClkButton, ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, + ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ + enum { + BAR_ALIGN_LEFT, +diff --git a/patch/bar_statusbutton.c b/patch/bar_statusbutton.c +new file mode 100644 +index 0000000..f5c9c9d +--- /dev/null ++++ b/patch/bar_statusbutton.c +@@ -0,0 +1,21 @@ ++int ++width_stbutton(Bar *bar, BarWidthArg *a) ++{ ++ return TEXTW(buttonbar); ++} ++ ++int ++draw_stbutton(Bar *bar, BarDrawArg *a) ++{ ++ #if BAR_PANGO_PATCH ++ return drw_text(drw, a->x, 0, a->w, bh, lrpad / 2, buttonbar, 0, False); ++ #else ++ return drw_text(drw, a->x, 0, a->w, bh, lrpad / 2, buttonbar, 0); ++ #endif // BAR_PANGO_PATCH ++} ++ ++int ++click_stbutton(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ return ClkButton; ++} +diff --git a/patch/bar_statusbutton.h b/patch/bar_statusbutton.h +new file mode 100644 +index 0000000..8e9d6fe +--- /dev/null ++++ b/patch/bar_statusbutton.h +@@ -0,0 +1,3 @@ ++static int width_stbutton(Bar *bar, BarWidthArg *a); ++static int draw_stbutton(Bar *bar, BarDrawArg *a); ++static int click_stbutton(Bar *bar, Arg *arg, BarClickArg *a); +\ No newline at end of file +diff --git a/patch/include.c b/patch/include.c +index d422f56..b731f2e 100644 +--- a/patch/include.c ++++ b/patch/include.c +@@ -2,4 +2,5 @@ + #include "bar_ltsymbol.c" + #include "bar_status.c" + #include "bar_tags.c" +-#include "bar_wintitle.c" +\ No newline at end of file ++#include "bar_wintitle.c" ++#include "bar_statusbutton.c" +\ No newline at end of file +diff --git a/patch/include.h b/patch/include.h +index 5f9a3fe..c2a1127 100644 +--- a/patch/include.h ++++ b/patch/include.h +@@ -2,4 +2,5 @@ + #include "bar_ltsymbol.h" + #include "bar_status.h" + #include "bar_tags.h" +-#include "bar_wintitle.h" +\ No newline at end of file ++#include "bar_wintitle.h" ++#include "bar_statusbutton.h" +\ No newline at end of file +-- +2.19.1 + diff --git a/dwm/dwm-barmodules-systray-6.2.diff b/dwm/dwm-barmodules-systray-6.2.diff new file mode 100644 index 0000000..70ebd0f --- /dev/null +++ b/dwm/dwm-barmodules-systray-6.2.diff @@ -0,0 +1,556 @@ +From 91f2f27ff5fd351261b33506ed7c755341bedbbb Mon Sep 17 00:00:00 2001 +From: bakkeby +Date: Mon, 20 Jul 2020 11:19:12 +0200 +Subject: [PATCH 2/2] Adding systray module + +--- + config.def.h | 3 + + dwm.c | 128 ++++++++++++++++++++++++++---- + patch/bar_systray.c | 187 ++++++++++++++++++++++++++++++++++++++++++++ + patch/bar_systray.h | 40 ++++++++++ + patch/include.c | 3 +- + patch/include.h | 3 +- + 6 files changed, 347 insertions(+), 17 deletions(-) + create mode 100644 patch/bar_systray.c + create mode 100644 patch/bar_systray.h + +diff --git a/config.def.h b/config.def.h +index 2534eac..d17b65c 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -5,6 +5,8 @@ static const unsigned int borderpx = 1; /* border pixel of 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 */ ++static const unsigned int systrayspacing = 2; /* systray spacing */ ++static const int showsystray = 1; /* 0 means no systray */ + static const char *fonts[] = { "monospace:size=10" }; + static const char dmenufont[] = "monospace:size=10"; + static const char col_gray1[] = "#222222"; +@@ -47,6 +49,7 @@ static const BarRule barrules[] = { + /* monitor bar alignment widthfunc drawfunc clickfunc name */ + { -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, "tags" }, + { -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, "layout" }, ++ { 'A', 0, BAR_ALIGN_RIGHT, width_systray, draw_systray, click_systray, "systray" }, + { 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" }, + { -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, "wintitle" }, + }; +diff --git a/dwm.c b/dwm.c +index 03dccfb..ce6c4fe 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -63,6 +63,8 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ + enum { SchemeNorm, SchemeSel }; /* color schemes */ + enum { NetSupported, NetWMName, NetWMState, NetWMCheck, + NetWMFullscreen, NetActiveWindow, NetWMWindowType, ++ NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, ++ NetSystemTrayVisual, NetWMWindowTypeDock, NetSystemTrayOrientationHorz, + NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ + enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ + enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, +@@ -246,7 +248,7 @@ static void resizemouse(const Arg *arg); + static void restack(Monitor *m); + static void run(void); + static void scan(void); +-static int sendevent(Client *c, Atom proto); ++static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); + static void sendmon(Client *c, Monitor *m); + static void setclientstate(Client *c, long state); + static void setfocus(Client *c); +@@ -310,9 +312,10 @@ static void (*handler[LASTEvent]) (XEvent *) = { + [MapRequest] = maprequest, + [MotionNotify] = motionnotify, + [PropertyNotify] = propertynotify, ++ [ResizeRequest] = resizerequest, + [UnmapNotify] = unmapnotify + }; +-static Atom wmatom[WMLast], netatom[NetLast]; ++static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; + static int running = 1; + static Cur *cursor[CurLast]; + static Clr **scheme; +@@ -555,6 +558,11 @@ cleanup(void) + XUngrabKey(dpy, AnyKey, AnyModifier, root); + while (mons) + cleanupmon(mons); ++ if (showsystray) { ++ XUnmapWindow(dpy, systray->win); ++ XDestroyWindow(dpy, systray->win); ++ free(systray); ++ } + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); + for (i = 0; i < LENGTH(colors); i++) +@@ -590,9 +598,48 @@ cleanupmon(Monitor *mon) + void + clientmessage(XEvent *e) + { ++ XWindowAttributes wa; ++ XSetWindowAttributes swa; + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); + ++ if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { ++ /* add systray icons */ ++ if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { ++ if (!(c = (Client *)calloc(1, sizeof(Client)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Client)); ++ if (!(c->win = cme->data.l[2])) { ++ free(c); ++ return; ++ } ++ ++ c->mon = selmon; ++ c->next = systray->icons; ++ systray->icons = c; ++ XGetWindowAttributes(dpy, c->win, &wa); ++ c->x = c->oldx = c->y = c->oldy = 0; ++ c->w = c->oldw = wa.width; ++ c->h = c->oldh = wa.height; ++ c->oldbw = wa.border_width; ++ c->bw = 0; ++ c->isfloating = True; ++ /* reuse tags field as mapped status */ ++ c->tags = 1; ++ updatesizehints(c); ++ updatesystrayicongeom(c, wa.width, wa.height); ++ XAddToSaveSet(dpy, c->win); ++ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); ++ XReparentWindow(dpy, c->win, systray->win, 0, 0); ++ /* use parents background color */ ++ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ XSync(dpy, False); ++ setclientstate(c, NormalState); ++ } ++ return; ++ } ++ + if (!c) + return; + if (cme->message_type == netatom[NetWMState]) { +@@ -755,6 +802,10 @@ destroynotify(XEvent *e) + + if ((c = wintoclient(ev->window))) + unmanage(c, 1); ++ else if (showsystray && (c = wintosystrayicon(ev->window))) { ++ removesystrayicon(c); ++ drawbarwin(systray->bar); ++ } + } + + void +@@ -1021,9 +1072,15 @@ getatomprop(Client *c, Atom prop) + unsigned char *p = NULL; + Atom da, atom = None; + +- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, ++ Atom req = XA_ATOM; ++ if (prop == xatom[XembedInfo]) ++ req = xatom[XembedInfo]; ++ ++ if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, + &da, &di, &dl, &dl, &p) == Success && p) { + atom = *(Atom *)p; ++ if (da == xatom[XembedInfo] && dl == 2) ++ atom = ((Atom *)p)[1]; + XFree(p); + } + return atom; +@@ -1161,7 +1218,7 @@ killclient(const Arg *arg) + { + if (!selmon->sel) + return; +- if (!sendevent(selmon->sel, wmatom[WMDelete])) { ++ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0, 0, 0)) { + XGrabServer(dpy); + XSetErrorHandler(xerrordummy); + XSetCloseDownMode(dpy, DestroyAll); +@@ -1247,9 +1304,15 @@ mappingnotify(XEvent *e) + void + maprequest(XEvent *e) + { ++ Client *i; + static XWindowAttributes wa; + XMapRequestEvent *ev = &e->xmaprequest; + ++ if (showsystray && (i = wintosystrayicon(ev->window))) { ++ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); ++ drawbarwin(systray->bar); ++ } ++ + if (!XGetWindowAttributes(dpy, ev->window, &wa)) + return; + if (wa.override_redirect) +@@ -1373,6 +1436,16 @@ propertynotify(XEvent *e) + Window trans; + XPropertyEvent *ev = &e->xproperty; + ++ if (showsystray && (c = wintosystrayicon(ev->window))) { ++ if (ev->atom == XA_WM_NORMAL_HINTS) { ++ updatesizehints(c); ++ updatesystrayicongeom(c, c->w, c->h); ++ } ++ else ++ updatesystrayiconstate(c, ev); ++ drawbarwin(systray->bar); ++ } ++ + if ((ev->window == root) && (ev->atom == XA_WM_NAME)) + updatestatus(); + else if (ev->state == PropertyDelete) +@@ -1592,26 +1665,36 @@ setclientstate(Client *c, long state) + } + + int +-sendevent(Client *c, Atom proto) ++sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) + { + int n; + Atom *protocols; ++ Atom mt; + int exists = 0; + XEvent ev; + +- if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { +- while (!exists && n--) +- exists = protocols[n] == proto; +- XFree(protocols); ++ if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) { ++ mt = wmatom[WMProtocols]; ++ if (XGetWMProtocols(dpy, w, &protocols, &n)) { ++ while (!exists && n--) ++ exists = protocols[n] == proto; ++ XFree(protocols); ++ } ++ } else { ++ exists = True; ++ mt = proto; + } + if (exists) { + ev.type = ClientMessage; +- ev.xclient.window = c->win; +- ev.xclient.message_type = wmatom[WMProtocols]; ++ ev.xclient.window = w; ++ ev.xclient.message_type = mt; + ev.xclient.format = 32; +- ev.xclient.data.l[0] = proto; +- ev.xclient.data.l[1] = CurrentTime; +- XSendEvent(dpy, c->win, False, NoEventMask, &ev); ++ ev.xclient.data.l[0] = d0; ++ ev.xclient.data.l[1] = d1; ++ ev.xclient.data.l[2] = d2; ++ ev.xclient.data.l[3] = d3; ++ ev.xclient.data.l[4] = d4; ++ XSendEvent(dpy, w, False, mask, &ev); + } + return exists; + } +@@ -1625,7 +1708,7 @@ setfocus(Client *c) + XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &(c->win), 1); + } +- sendevent(c, wmatom[WMTakeFocus]); ++ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); + } + + void +@@ -1714,6 +1797,15 @@ setup(void) + wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); + netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); ++ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); ++ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); ++ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); ++ netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False); ++ netatom[NetSystemTrayVisual] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_VISUAL", False); ++ netatom[NetWMWindowTypeDock] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False); ++ xatom[Manager] = XInternAtom(dpy, "MANAGER", False); ++ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); ++ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", 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); +@@ -1956,6 +2048,12 @@ unmapnotify(XEvent *e) + setclientstate(c, WithdrawnState); + else + unmanage(c, 0); ++ } else if (showsystray && (c = wintosystrayicon(ev->window))) { ++ /* KLUDGE! sometimes icons occasionally unmap their windows, but do ++ * _not_ destroy them. We map those windows back */ ++ XMapRaised(dpy, c->win); ++ removesystrayicon(c); ++ drawbarwin(systray->bar); + } + } + +diff --git a/patch/bar_systray.c b/patch/bar_systray.c +new file mode 100644 +index 0000000..0ff730d +--- /dev/null ++++ b/patch/bar_systray.c +@@ -0,0 +1,187 @@ ++static Systray *systray = NULL; ++static unsigned long systrayorientation = _NET_SYSTEM_TRAY_ORIENTATION_HORZ; ++ ++int ++width_systray(Bar *bar, BarWidthArg *a) ++{ ++ unsigned int w = 0; ++ Client *i; ++ if (!systray) ++ return 1; ++ if (showsystray) ++ for (i = systray->icons; i; w += i->w + systrayspacing, i = i->next); ++ return w ? w + lrpad - systrayspacing : 0; ++} ++ ++int ++draw_systray(Bar *bar, BarDrawArg *a) ++{ ++ if (!showsystray) ++ return a->x; ++ ++ XSetWindowAttributes wa; ++ Client *i; ++ unsigned int w; ++ ++ if (!systray) { ++ /* init systray */ ++ if (!(systray = (Systray *)calloc(1, sizeof(Systray)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); ++ ++ wa.override_redirect = True; ++ wa.event_mask = ButtonPressMask|ExposureMask; ++ wa.border_pixel = 0; ++ #if BAR_ALPHA_PATCH ++ wa.background_pixel = 0; ++ wa.colormap = cmap; ++ systray->win = XCreateWindow(dpy, root, bar->bx + a->x + lrpad / 2, bar->by, MAX(a->w + 40, 1), bar->bh, 0, depth, ++ InputOutput, visual, ++ CWOverrideRedirect|CWBorderPixel|CWBackPixel|CWColormap|CWEventMask, &wa); // CWBackPixmap ++ #else ++ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ systray->win = XCreateSimpleWindow(dpy, root, bar->bx + a->x + lrpad / 2, bar->by, MIN(a->w, 1), bar->bh, 0, 0, scheme[SchemeNorm][ColBg].pixel); ++ XChangeWindowAttributes(dpy, systray->win, CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWEventMask, &wa); ++ #endif // BAR_ALPHA_PATCH ++ ++ XSelectInput(dpy, systray->win, SubstructureNotifyMask); ++ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, ++ PropModeReplace, (unsigned char *)&systrayorientation, 1); ++ #if BAR_ALPHA_PATCH ++ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayVisual], XA_VISUALID, 32, ++ PropModeReplace, (unsigned char *)&visual->visualid, 1); ++ #endif // BAR_ALPHA_PATCH ++ XChangeProperty(dpy, systray->win, netatom[NetWMWindowType], XA_ATOM, 32, ++ PropModeReplace, (unsigned char *)&netatom[NetWMWindowTypeDock], 1); ++ XMapRaised(dpy, systray->win); ++ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); ++ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { ++ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); ++ XSync(dpy, False); ++ } else { ++ fprintf(stderr, "dwm: unable to obtain system tray.\n"); ++ free(systray); ++ systray = NULL; ++ return a->x; ++ } ++ } ++ ++ systray->bar = bar; ++ ++ drw_setscheme(drw, scheme[SchemeNorm]); ++ for (w = 0, i = systray->icons; i; i = i->next) { ++ #if BAR_ALPHA_PATCH ++ wa.background_pixel = 0; ++ #else ++ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ #endif // BAR_ALPHA_PATCH ++ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); ++ XMapRaised(dpy, i->win); ++ i->x = w; ++ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); ++ w += i->w; ++ if (i->next) ++ w += systrayspacing; ++ if (i->mon != bar->mon) ++ i->mon = bar->mon; ++ } ++ ++ XMoveResizeWindow(dpy, systray->win, bar->bx + a->x + lrpad / 2, (w ? bar->by : -bar->by), MAX(w, 1), bar->bh); ++ return a->x + a->w; ++} ++ ++int ++click_systray(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ return -1; ++} ++ ++void ++removesystrayicon(Client *i) ++{ ++ Client **ii; ++ ++ if (!showsystray || !i) ++ return; ++ for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); ++ if (ii) ++ *ii = i->next; ++ free(i); ++ drawbarwin(systray->bar); ++} ++ ++void ++resizerequest(XEvent *e) ++{ ++ XResizeRequestEvent *ev = &e->xresizerequest; ++ Client *i; ++ ++ if ((i = wintosystrayicon(ev->window))) { ++ updatesystrayicongeom(i, ev->width, ev->height); ++ drawbarwin(systray->bar); ++ } ++} ++ ++void ++updatesystrayicongeom(Client *i, int w, int h) ++{ ++ if (i) { ++ i->h = bh; ++ if (w == h) ++ i->w = bh; ++ else if (h == bh) ++ i->w = w; ++ else ++ i->w = (int) ((float)bh * ((float)w / (float)h)); ++ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); ++ /* force icons into the systray dimensions if they don't want to */ ++ if (i->h > bh) { ++ if (i->w == i->h) ++ i->w = bh; ++ else ++ i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); ++ i->h = bh; ++ } ++ if (i->w > 2*bh) ++ i->w = bh; ++ } ++} ++ ++void ++updatesystrayiconstate(Client *i, XPropertyEvent *ev) ++{ ++ long flags; ++ int code = 0; ++ ++ if (!showsystray || !i || ev->atom != xatom[XembedInfo] || ++ !(flags = getatomprop(i, xatom[XembedInfo]))) ++ return; ++ ++ if (flags & XEMBED_MAPPED && !i->tags) { ++ i->tags = 1; ++ code = XEMBED_WINDOW_ACTIVATE; ++ XMapRaised(dpy, i->win); ++ setclientstate(i, NormalState); ++ } ++ else if (!(flags & XEMBED_MAPPED) && i->tags) { ++ i->tags = 0; ++ code = XEMBED_WINDOW_DEACTIVATE; ++ XUnmapWindow(dpy, i->win); ++ setclientstate(i, WithdrawnState); ++ } ++ else ++ return; ++ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, ++ systray->win, XEMBED_EMBEDDED_VERSION); ++} ++ ++Client * ++wintosystrayicon(Window w) ++{ ++ if (!systray) ++ return NULL; ++ Client *i = NULL; ++ if (!showsystray || !w) ++ return i; ++ for (i = systray->icons; i && i->win != w; i = i->next); ++ return i; ++} +\ No newline at end of file +diff --git a/patch/bar_systray.h b/patch/bar_systray.h +new file mode 100644 +index 0000000..5123a73 +--- /dev/null ++++ b/patch/bar_systray.h +@@ -0,0 +1,40 @@ ++#define SYSTEM_TRAY_REQUEST_DOCK 0 ++#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 ++ ++/* XEMBED messages */ ++#define XEMBED_EMBEDDED_NOTIFY 0 ++#define XEMBED_WINDOW_ACTIVATE 1 ++#define XEMBED_FOCUS_IN 4 ++#define XEMBED_MODALITY_ON 10 ++ ++#define XEMBED_MAPPED (1 << 0) ++#define XEMBED_WINDOW_ACTIVATE 1 ++#define XEMBED_WINDOW_DEACTIVATE 2 ++ ++#define VERSION_MAJOR 0 ++#define VERSION_MINOR 0 ++#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR ++ ++/* enums */ ++enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ ++ ++typedef struct Systray Systray; ++struct Systray { ++ Window win; ++ Client *icons; ++ Bar *bar; ++}; ++ ++/* bar integration */ ++static int width_systray(Bar *bar, BarWidthArg *a); ++static int draw_systray(Bar *bar, BarDrawArg *a); ++static int click_systray(Bar *bar, Arg *arg, BarClickArg *a); ++ ++/* function declarations */ ++static Atom getatomprop(Client *c, Atom prop); ++static void removesystrayicon(Client *i); ++static void resizerequest(XEvent *e); ++static void updatesystrayicongeom(Client *i, int w, int h); ++static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); ++static Client *wintosystrayicon(Window w); ++ +diff --git a/patch/include.c b/patch/include.c +index d422f56..c82b392 100644 +--- a/patch/include.c ++++ b/patch/include.c +@@ -2,4 +2,5 @@ + #include "bar_ltsymbol.c" + #include "bar_status.c" + #include "bar_tags.c" +-#include "bar_wintitle.c" +\ No newline at end of file ++#include "bar_wintitle.c" ++#include "bar_systray.c" +\ No newline at end of file +diff --git a/patch/include.h b/patch/include.h +index 5f9a3fe..c01916a 100644 +--- a/patch/include.h ++++ b/patch/include.h +@@ -2,4 +2,5 @@ + #include "bar_ltsymbol.h" + #include "bar_status.h" + #include "bar_tags.h" +-#include "bar_wintitle.h" +\ No newline at end of file ++#include "bar_wintitle.h" ++#include "bar_systray.h" +\ No newline at end of file +-- +2.19.1 + diff --git a/dwm/dwm-barmodules-taggrid-6.2.diff b/dwm/dwm-barmodules-taggrid-6.2.diff new file mode 100644 index 0000000..b481593 --- /dev/null +++ b/dwm/dwm-barmodules-taggrid-6.2.diff @@ -0,0 +1,260 @@ +From 309128900da962d6f46030fa2975c50b76cd2895 Mon Sep 17 00:00:00 2001 +From: bakkeby +Date: Mon, 20 Jul 2020 15:57:24 +0200 +Subject: [PATCH 2/2] Adding taggrid module + +--- + config.def.h | 25 ++++++++ + patch/bar_taggrid.c | 148 ++++++++++++++++++++++++++++++++++++++++++++ + patch/bar_taggrid.h | 4 ++ + patch/include.c | 3 +- + patch/include.h | 3 +- + 5 files changed, 181 insertions(+), 2 deletions(-) + create mode 100644 patch/bar_taggrid.c + create mode 100644 patch/bar_taggrid.h + +diff --git a/config.def.h b/config.def.h +index 2534eac..afee168 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -21,6 +21,22 @@ static const char *colors[][3] = { + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + ++/* grid of tags */ ++#define DRAWCLASSICTAGS 1 << 0 ++#define DRAWTAGGRID 1 << 1 ++ ++#define SWITCHTAG_UP 1 << 0 ++#define SWITCHTAG_DOWN 1 << 1 ++#define SWITCHTAG_LEFT 1 << 2 ++#define SWITCHTAG_RIGHT 1 << 3 ++#define SWITCHTAG_TOGGLETAG 1 << 4 ++#define SWITCHTAG_TAG 1 << 5 ++#define SWITCHTAG_VIEW 1 << 6 ++#define SWITCHTAG_TOGGLEVIEW 1 << 7 ++ ++static const unsigned int drawtagmask = DRAWTAGGRID; /* | DRAWCLASSICTAGS to show classic row of tags */ ++static const int tagrows = 2; ++ + static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class +@@ -46,6 +62,7 @@ static const Rule rules[] = { + static const BarRule barrules[] = { + /* monitor bar alignment widthfunc drawfunc clickfunc name */ + { -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, "tags" }, ++ { -1, 0, BAR_ALIGN_LEFT, width_taggrid, draw_taggrid, click_taggrid, "taggrid" }, + { -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, "layout" }, + { 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" }, + { -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, "wintitle" }, +@@ -100,6 +117,14 @@ static Key keys[] = { + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, ++ { MODKEY|ControlMask, XK_Up, switchtag, { .ui = SWITCHTAG_UP | SWITCHTAG_VIEW } }, ++ { MODKEY|ControlMask, XK_Down, switchtag, { .ui = SWITCHTAG_DOWN | SWITCHTAG_VIEW } }, ++ { MODKEY|ControlMask, XK_Right, switchtag, { .ui = SWITCHTAG_RIGHT | SWITCHTAG_VIEW } }, ++ { MODKEY|ControlMask, XK_Left, switchtag, { .ui = SWITCHTAG_LEFT | SWITCHTAG_VIEW } }, ++ { MODKEY|Mod4Mask, XK_Up, switchtag, { .ui = SWITCHTAG_UP | SWITCHTAG_TAG | SWITCHTAG_VIEW } }, ++ { MODKEY|Mod4Mask, XK_Down, switchtag, { .ui = SWITCHTAG_DOWN | SWITCHTAG_TAG | SWITCHTAG_VIEW } }, ++ { MODKEY|Mod4Mask, XK_Right, switchtag, { .ui = SWITCHTAG_RIGHT | SWITCHTAG_TAG | SWITCHTAG_VIEW } }, ++ { MODKEY|Mod4Mask, XK_Left, switchtag, { .ui = SWITCHTAG_LEFT | SWITCHTAG_TAG | SWITCHTAG_VIEW } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, +diff --git a/patch/bar_taggrid.c b/patch/bar_taggrid.c +new file mode 100644 +index 0000000..53046fa +--- /dev/null ++++ b/patch/bar_taggrid.c +@@ -0,0 +1,148 @@ ++int ++width_taggrid(Bar *bar, BarWidthArg *a) ++{ ++ return (bh / 2) * (LENGTH(tags) / tagrows + ((LENGTH(tags) % tagrows > 0) ? 1 : 0)) + lrpad; ++} ++ ++int ++draw_taggrid(Bar *bar, BarDrawArg *a) ++{ ++ unsigned int x, y, h, max_x = 0, columns, occ = 0; ++ int invert, i,j, k; ++ Client *c; ++ ++ for (c = bar->mon->clients; c; c = c->next) ++ occ |= c->tags; ++ ++ max_x = x = a->x + lrpad / 2; ++ h = bh / tagrows; ++ y = 0; ++ columns = LENGTH(tags) / tagrows + ((LENGTH(tags) % tagrows > 0) ? 1 : 0); ++ ++ /* Firstly we will fill the borders of squares */ ++ XSetForeground(drw->dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel); ++ XFillRectangle(dpy, drw->drawable, drw->gc, x, y, h*columns + 1, bh); ++ ++ /* We will draw LENGTH(tags) squares in tagraws raws. */ ++ for (j = 0, i = 0; j < tagrows; j++) { ++ x = a->x + lrpad / 2; ++ for (k = 0; k < columns; k++, i++) { ++ if (i < LENGTH(tags)) { ++ invert = bar->mon->tagset[bar->mon->seltags] & 1 << i ? 0 : 1; ++ ++ /* Select active color for current square */ ++ XSetForeground(drw->dpy, drw->gc, !invert ? scheme[SchemeSel][ColBg].pixel : ++ scheme[SchemeNorm][ColFg].pixel); ++ XFillRectangle(dpy, drw->drawable, drw->gc, x+1, y+1, h-1, h-1); ++ ++ /* Mark square if tag has client */ ++ if (occ & 1 << i) { ++ XSetForeground(drw->dpy, drw->gc, !invert ? scheme[SchemeSel][ColFg].pixel : ++ scheme[SchemeNorm][ColBg].pixel); ++ XFillRectangle(dpy, drw->drawable, drw->gc, x + 1, y + 1, ++ h / 2, h / 2); ++ } ++ } else { ++ XSetForeground(drw->dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel); ++ XFillRectangle(dpy, drw->drawable, drw->gc, x+1, y+1, h-1, h); ++ } ++ x += h; ++ if (x > max_x) { ++ max_x = x; ++ } ++ } ++ y += h; ++ } ++ return max_x; ++} ++ ++int ++click_taggrid(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ unsigned int i, columns; ++ ++ columns = LENGTH(tags) / tagrows + ((LENGTH(tags) % tagrows > 0) ? 1 : 0); ++ i = (a->rel_x - lrpad / 2) / (bh / tagrows) + columns * (a->rel_y / (bh / tagrows)); ++ if (i >= LENGTH(tags)) { ++ i = LENGTH(tags) - 1; ++ } ++ arg->ui = 1 << i; ++ return ClkTagBar; ++} ++ ++void ++switchtag(const Arg *arg) ++{ ++ unsigned int columns; ++ unsigned int new_tagset = 0; ++ unsigned int pos, i; ++ int col, row; ++ Arg new_arg; ++ ++ columns = LENGTH(tags) / tagrows + ((LENGTH(tags) % tagrows > 0) ? 1 : 0); ++ ++ for (i = 0; i < LENGTH(tags); ++i) { ++ if (!(selmon->tagset[selmon->seltags] & 1 << i)) { ++ continue; ++ } ++ pos = i; ++ row = pos / columns; ++ col = pos % columns; ++ if (arg->ui & SWITCHTAG_UP) { /* UP */ ++ row --; ++ if (row < 0) { ++ row = tagrows - 1; ++ } ++ do { ++ pos = row * columns + col; ++ row --; ++ } while (pos >= LENGTH(tags)); ++ } ++ if (arg->ui & SWITCHTAG_DOWN) { /* DOWN */ ++ row ++; ++ if (row >= tagrows) { ++ row = 0; ++ } ++ pos = row * columns + col; ++ if (pos >= LENGTH(tags)) { ++ row = 0; ++ } ++ pos = row * columns + col; ++ } ++ if (arg->ui & SWITCHTAG_LEFT) { /* LEFT */ ++ col --; ++ if (col < 0) { ++ col = columns - 1; ++ } ++ do { ++ pos = row * columns + col; ++ col --; ++ } while (pos >= LENGTH(tags)); ++ } ++ if (arg->ui & SWITCHTAG_RIGHT) { /* RIGHT */ ++ col ++; ++ if (col >= columns) { ++ col = 0; ++ } ++ pos = row * columns + col; ++ if (pos >= LENGTH(tags)) { ++ col = 0; ++ pos = row * columns + col; ++ } ++ } ++ new_tagset |= 1 << pos; ++ } ++ new_arg.ui = new_tagset; ++ if (arg->ui & SWITCHTAG_TOGGLETAG) { ++ toggletag(&new_arg); ++ } ++ if (arg->ui & SWITCHTAG_TAG) { ++ tag(&new_arg); ++ } ++ if (arg->ui & SWITCHTAG_VIEW) { ++ view (&new_arg); ++ } ++ if (arg->ui & SWITCHTAG_TOGGLEVIEW) { ++ toggleview (&new_arg); ++ } ++} +\ No newline at end of file +diff --git a/patch/bar_taggrid.h b/patch/bar_taggrid.h +new file mode 100644 +index 0000000..c35b337 +--- /dev/null ++++ b/patch/bar_taggrid.h +@@ -0,0 +1,4 @@ ++static int width_taggrid(Bar *bar, BarWidthArg *a); ++static int draw_taggrid(Bar *bar, BarDrawArg *a); ++static int click_taggrid(Bar *bar, Arg *arg, BarClickArg *a); ++static void switchtag(const Arg *arg); +\ No newline at end of file +diff --git a/patch/include.c b/patch/include.c +index d422f56..f6455d8 100644 +--- a/patch/include.c ++++ b/patch/include.c +@@ -2,4 +2,5 @@ + #include "bar_ltsymbol.c" + #include "bar_status.c" + #include "bar_tags.c" +-#include "bar_wintitle.c" +\ No newline at end of file ++#include "bar_wintitle.c" ++#include "bar_taggrid.c" +\ No newline at end of file +diff --git a/patch/include.h b/patch/include.h +index 5f9a3fe..98ac046 100644 +--- a/patch/include.h ++++ b/patch/include.h +@@ -2,4 +2,5 @@ + #include "bar_ltsymbol.h" + #include "bar_status.h" + #include "bar_tags.h" +-#include "bar_wintitle.h" +\ No newline at end of file ++#include "bar_wintitle.h" ++#include "bar_taggrid.h" +\ No newline at end of file +-- +2.19.1 +