diff options
author | Ferass 'Vitali64' EL HAFIDI <vitali64pmemail@protonmail.com> | 2022-11-14 18:49:30 +0100 |
---|---|---|
committer | Ferass 'Vitali64' EL HAFIDI <vitali64pmemail@protonmail.com> | 2022-11-14 18:49:30 +0100 |
commit | 0a66fa426beaa938bc57e4cff315068364b4f2d5 (patch) | |
tree | 4fcffa6ce2a8137b7fcbdfa00e64041c98c28cb7 | |
parent | 2d82784cfbca8e0296b08da63db210dce068d197 (diff) | |
download | sucklessdwm-master.tar.gz |
Signed-off-by: Ferass 'Vitali64' EL HAFIDI <vitali64pmemail@protonmail.com>
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | bar_ltsymbol.c.rej | 20 | ||||
-rw-r--r-- | bar_ltsymbol.h.rej | 6 | ||||
-rw-r--r-- | patch/bar_ltsymbol.c | 17 | ||||
-rw-r--r-- | patch/bar_ltsymbol.h | 3 | ||||
-rw-r--r-- | patch/bar_status.c | 19 | ||||
-rw-r--r-- | patch/bar_status.h | 3 | ||||
-rw-r--r-- | patch/bar_tags.c | 55 | ||||
-rw-r--r-- | patch/bar_tags.h | 3 | ||||
-rw-r--r-- | patch/bar_wintitle.c | 31 | ||||
-rw-r--r-- | patch/bar_wintitle.h | 3 | ||||
-rw-r--r-- | patch/include.c | 5 | ||||
-rw-r--r-- | patch/include.h | 5 | ||||
-rw-r--r-- | patches/dwm-barmodules-6.2.diff | 894 |
14 files changed, 1066 insertions, 0 deletions
@@ -1,3 +1,5 @@ +<div style="background: red;">This is unmaintained. I'm now using Wayland</div> + # v64-dwm - Vitali64's dynamic window manager build dwm is an extremely fast, small, and dynamic window manager for X. diff --git a/bar_ltsymbol.c.rej b/bar_ltsymbol.c.rej new file mode 100644 index 0000000..bb55781 --- /dev/null +++ b/bar_ltsymbol.c.rej @@ -0,0 +1,20 @@ +--- bar_ltsymbol.c ++++ bar_ltsymbol.c +@@ -1,17 +0,0 @@ +-int +-width_ltsymbol(Bar *bar, BarWidthArg *a) +-{ +- return TEXTW(bar->mon->ltsymbol); +-} +- +-int +-draw_ltsymbol(Bar *bar, BarDrawArg *a) +-{ +- return drw_text(drw, a->x, 0, a->w, bh, lrpad / 2, bar->mon->ltsymbol, 0); +-} +- +-int +-click_ltsymbol(Bar *bar, Arg *arg, BarClickArg *a) +-{ +- return ClkLtSymbol; +-} diff --git a/bar_ltsymbol.h.rej b/bar_ltsymbol.h.rej new file mode 100644 index 0000000..639c009 --- /dev/null +++ b/bar_ltsymbol.h.rej @@ -0,0 +1,6 @@ +--- bar_ltsymbol.h ++++ bar_ltsymbol.h +@@ -1,3 +0,0 @@ +-static int width_ltsymbol(Bar *bar, BarWidthArg *a); +-static int draw_ltsymbol(Bar *bar, BarDrawArg *a); +-static int click_ltsymbol(Bar *bar, Arg *arg, BarClickArg *a); diff --git a/patch/bar_ltsymbol.c b/patch/bar_ltsymbol.c new file mode 100644 index 0000000..6676a2a --- /dev/null +++ b/patch/bar_ltsymbol.c @@ -0,0 +1,17 @@ +int +width_ltsymbol(Bar *bar, BarWidthArg *a) +{ + return TEXTW(bar->mon->ltsymbol); +} + +int +draw_ltsymbol(Bar *bar, BarDrawArg *a) +{ + return drw_text(drw, a->x, 0, a->w, bh, lrpad / 2, bar->mon->ltsymbol, 0); +} + +int +click_ltsymbol(Bar *bar, Arg *arg, BarClickArg *a) +{ + return ClkLtSymbol; +} diff --git a/patch/bar_ltsymbol.h b/patch/bar_ltsymbol.h new file mode 100644 index 0000000..d9c79bf --- /dev/null +++ b/patch/bar_ltsymbol.h @@ -0,0 +1,3 @@ +static int width_ltsymbol(Bar *bar, BarWidthArg *a); +static int draw_ltsymbol(Bar *bar, BarDrawArg *a); +static int click_ltsymbol(Bar *bar, Arg *arg, BarClickArg *a); diff --git a/patch/bar_status.c b/patch/bar_status.c new file mode 100644 index 0000000..7d27282 --- /dev/null +++ b/patch/bar_status.c @@ -0,0 +1,19 @@ +int +width_status(Bar *bar, BarWidthArg *a) +{ + return TEXTW(stext); +} + + +int +draw_status(Bar *bar, BarDrawArg *a) +{ + return drw_text(drw, a->x, 0, a->w, bh, lrpad / 2, stext, 0); +} + + +int +click_status(Bar *bar, Arg *arg, BarClickArg *a) +{ + return ClkStatusText; +} diff --git a/patch/bar_status.h b/patch/bar_status.h new file mode 100644 index 0000000..b02a4b8 --- /dev/null +++ b/patch/bar_status.h @@ -0,0 +1,3 @@ +static int width_status(Bar *bar, BarWidthArg *a); +static int draw_status(Bar *bar, BarDrawArg *a); +static int click_status(Bar *bar, Arg *arg, BarClickArg *a); diff --git a/patch/bar_tags.c b/patch/bar_tags.c new file mode 100644 index 0000000..680e1fe --- /dev/null +++ b/patch/bar_tags.c @@ -0,0 +1,55 @@ +int +width_tags(Bar *bar, BarWidthArg *a) +{ + int w, i; + + for (w = 0, i = 0; i < LENGTH(tags); i++) { + w += TEXTW(tags[i]); + } + return w; +} + +int +draw_tags(Bar *bar, BarDrawArg *a) +{ + int invert; + int w, x = a->x; + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; + unsigned int i, occ = 0, urg = 0; + Client *c; + Monitor *m = bar->mon; + + for (c = m->clients; c; c = c->next) { + occ |= c->tags; + if (c->isurgent) + urg |= c->tags; + } + + for (i = 0; i < LENGTH(tags); i++) { + invert = urg & 1 << i; + 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], invert); + if (occ & 1 << i) + drw_rect(drw, x + boxs, boxs, boxw, boxw, + m == selmon && selmon->sel && selmon->sel->tags & 1 << i, invert); + x += w; + } + + return x; +} + +int +click_tags(Bar *bar, Arg *arg, BarClickArg *a) +{ + int i = 0, x = lrpad / 2; + + do { + x += TEXTW(tags[i]); + } while (a->rel_x >= x && ++i < LENGTH(tags)); + if (i < LENGTH(tags)) { + arg->ui = 1 << i; + } + return ClkTagBar; +} diff --git a/patch/bar_tags.h b/patch/bar_tags.h new file mode 100644 index 0000000..7ac04d8 --- /dev/null +++ b/patch/bar_tags.h @@ -0,0 +1,3 @@ +static int width_tags(Bar *bar, BarWidthArg *a); +static int draw_tags(Bar *bar, BarDrawArg *a); +static int click_tags(Bar *bar, Arg *arg, BarClickArg *a); diff --git a/patch/bar_wintitle.c b/patch/bar_wintitle.c new file mode 100644 index 0000000..3c11b75 --- /dev/null +++ b/patch/bar_wintitle.c @@ -0,0 +1,31 @@ +int +width_wintitle(Bar *bar, BarWidthArg *a) +{ + return a->max_width; +} + +int +draw_wintitle(Bar *bar, BarDrawArg *a) +{ + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; + int x = a->x, w = a->w; + Monitor *m = bar->mon; + + 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); + } + return x + w; +} + +int +click_wintitle(Bar *bar, Arg *arg, BarClickArg *a) +{ + return ClkWinTitle; +} diff --git a/patch/bar_wintitle.h b/patch/bar_wintitle.h new file mode 100644 index 0000000..266404c --- /dev/null +++ b/patch/bar_wintitle.h @@ -0,0 +1,3 @@ +static int width_wintitle(Bar *bar, BarWidthArg *a); +static int draw_wintitle(Bar *bar, BarDrawArg *a); +static int click_wintitle(Bar *bar, Arg *arg, BarClickArg *a); diff --git a/patch/include.c b/patch/include.c new file mode 100644 index 0000000..d422f56 --- /dev/null +++ b/patch/include.c @@ -0,0 +1,5 @@ +/* Bar functionality */ +#include "bar_ltsymbol.c" +#include "bar_status.c" +#include "bar_tags.c" +#include "bar_wintitle.c"
\ No newline at end of file diff --git a/patch/include.h b/patch/include.h new file mode 100644 index 0000000..5f9a3fe --- /dev/null +++ b/patch/include.h @@ -0,0 +1,5 @@ +/* Bar functionality */ +#include "bar_ltsymbol.h" +#include "bar_status.h" +#include "bar_tags.h" +#include "bar_wintitle.h"
\ No newline at end of file diff --git a/patches/dwm-barmodules-6.2.diff b/patches/dwm-barmodules-6.2.diff new file mode 100644 index 0000000..a16520a --- /dev/null +++ b/patches/dwm-barmodules-6.2.diff @@ -0,0 +1,894 @@ +From 53e19fbad52e4cba1f9f2ed9f21ab26db37f4eef Mon Sep 17 00:00:00 2001 +From: bakkeby <bakkeby@gmail.com> +Date: Sun, 19 Jul 2020 19:26:10 +0200 +Subject: [PATCH] Bar Modules - splits the bar functionality into individual + segments that can be re-arranged + +--- + config.def.h | 20 +++ + dwm.c | 390 ++++++++++++++++++++++++++++++++----------- + patch/bar_ltsymbol.c | 17 ++ + patch/bar_ltsymbol.h | 3 + + patch/bar_status.c | 19 +++ + patch/bar_status.h | 3 + + patch/bar_tags.c | 55 ++++++ + patch/bar_tags.h | 3 + + patch/bar_wintitle.c | 31 ++++ + patch/bar_wintitle.h | 3 + + patch/include.c | 5 + + patch/include.h | 5 + + 12 files changed, 458 insertions(+), 96 deletions(-) + create mode 100644 patch/bar_ltsymbol.c + create mode 100644 patch/bar_ltsymbol.h + create mode 100644 patch/bar_status.c + create mode 100644 patch/bar_status.h + create mode 100644 patch/bar_tags.c + create mode 100644 patch/bar_tags.h + create mode 100644 patch/bar_wintitle.c + create mode 100644 patch/bar_wintitle.h + create mode 100644 patch/include.c + create mode 100644 patch/include.h + +diff --git a/config.def.h b/config.def.h +index 1c0b587..2534eac 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -31,6 +31,26 @@ static const Rule rules[] = { + { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, + }; + ++/* Bar rules allow you to configure what is shown where on the bar, as well as ++ * introducing your own bar modules. ++ * ++ * monitor: ++ * -1 show on all monitors ++ * 0 show on monitor 0 ++ * 'A' show on active monitor (i.e. focused / selected) (or just -1 for active?) ++ * bar - bar index, 0 is default, 1 is extrabar ++ * alignment - how the module is aligned compared to other modules ++ * widthfunc, drawfunc, clickfunc - providing bar module width, draw and click functions ++ * name - does nothing, intended for visual clue and for logging / debugging ++ */ ++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" }, ++ { -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, "wintitle" }, ++}; ++ + /* layout(s) */ + static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ + static const int nmaster = 1; /* number of clients in master area */ +diff --git a/dwm.c b/dwm.c +index 4465af1..9173ba9 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -45,6 +45,7 @@ + #include "util.h" + + /* macros */ ++#define BARRULES 20 + #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) + #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) + #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ +@@ -66,6 +67,19 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, + enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ + enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, + ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ ++enum { ++ BAR_ALIGN_LEFT, ++ BAR_ALIGN_CENTER, ++ BAR_ALIGN_RIGHT, ++ BAR_ALIGN_LEFT_LEFT, ++ BAR_ALIGN_LEFT_RIGHT, ++ BAR_ALIGN_LEFT_CENTER, ++ BAR_ALIGN_NONE, ++ BAR_ALIGN_RIGHT_LEFT, ++ BAR_ALIGN_RIGHT_RIGHT, ++ BAR_ALIGN_RIGHT_CENTER, ++ BAR_ALIGN_LAST ++}; /* bar alignment */ + + typedef union { + int i; +@@ -74,6 +88,46 @@ typedef union { + const void *v; + } Arg; + ++typedef struct Monitor Monitor; ++typedef struct Bar Bar; ++struct Bar { ++ Window win; ++ Monitor *mon; ++ Bar *next; ++ int idx; ++ int topbar; ++ int bx, by, bw, bh; /* bar geometry */ ++ int w[BARRULES]; // module width ++ int x[BARRULES]; // module position ++}; ++ ++typedef struct { ++ int max_width; ++} BarWidthArg; ++ ++typedef struct { ++ int x; ++ int w; ++} BarDrawArg; ++ ++typedef struct { ++ int rel_x; ++ int rel_y; ++ int rel_w; ++ int rel_h; ++} BarClickArg; ++ ++typedef struct { ++ int monitor; ++ int bar; ++ int alignment; // see bar alignment enum ++ int (*widthfunc)(Bar *bar, BarWidthArg *a); ++ int (*drawfunc)(Bar *bar, BarDrawArg *a); ++ int (*clickfunc)(Bar *bar, Arg *arg, BarClickArg *a); ++ char *name; // for debugging ++ int x, w; // position, width for internal use ++} BarRule; ++ + typedef struct { + unsigned int click; + unsigned int mask; +@@ -82,7 +136,6 @@ typedef struct { + const Arg arg; + } Button; + +-typedef struct Monitor Monitor; + typedef struct Client Client; + struct Client { + char name[256]; +@@ -116,19 +169,17 @@ struct Monitor { + float mfact; + int nmaster; + int num; +- int by; /* bar geometry */ + int mx, my, mw, mh; /* screen size */ + int wx, wy, ww, wh; /* window area */ + unsigned int seltags; + unsigned int sellt; + unsigned int tagset[2]; + int showbar; +- int topbar; + Client *clients; + Client *sel; + Client *stack; + Monitor *next; +- Window barwin; ++ Bar *bar; + const Layout *lt[2]; + }; + +@@ -163,6 +214,7 @@ static void detachstack(Client *c); + static Monitor *dirtomon(int dir); + static void drawbar(Monitor *m); + static void drawbars(void); ++static void drawbarwin(Bar *bar); + static void enternotify(XEvent *e); + static void expose(XEvent *e); + static void focus(Client *c); +@@ -234,12 +286,13 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); + static void zoom(const Arg *arg); + ++#include "patch/include.h" + /* variables */ + 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; /* bar geometry */ + static int lrpad; /* sum of left and right padding for text */ + static int (*xerrorxlib)(Display *, XErrorEvent *); + static unsigned int numlockmask = 0; +@@ -271,6 +324,8 @@ static Window root, wmcheckwin; + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++#include "patch/include.c" ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + +@@ -416,43 +471,61 @@ attachstack(Client *c) + void + buttonpress(XEvent *e) + { +- unsigned int i, x, click; ++ int click, i, r, mi; + Arg arg = {0}; + Client *c; + Monitor *m; ++ Bar *bar; + XButtonPressedEvent *ev = &e->xbutton; ++ const BarRule *br; ++ BarClickArg carg = { 0, 0, 0, 0 }; + + click = ClkRootWin; + /* focus monitor if necessary */ +- if ((m = wintomon(ev->window)) && m != selmon) { ++ if ((m = wintomon(ev->window)) && m != selmon ++ ) { + unfocus(selmon->sel, 1); + selmon = m; + focus(NULL); + } +- if (ev->window == selmon->barwin) { +- i = x = 0; +- do +- x += TEXTW(tags[i]); +- while (ev->x >= x && ++i < LENGTH(tags)); +- if (i < LENGTH(tags)) { +- click = ClkTagBar; +- arg.ui = 1 << i; +- } else if (ev->x < x + blw) +- click = ClkLtSymbol; +- else if (ev->x > selmon->ww - TEXTW(stext)) +- click = ClkStatusText; +- else +- click = ClkWinTitle; +- } else if ((c = wintoclient(ev->window))) { ++ ++ for (mi = 0, m = mons; m && m != selmon; m = m->next, mi++); // get the monitor index ++ for (bar = selmon->bar; bar; bar = bar->next) { ++ if (ev->window == bar->win) { ++ for (r = 0; r < LENGTH(barrules); r++) { ++ br = &barrules[r]; ++ if (br->bar != bar->idx || (br->monitor == 'A' && m != selmon) || br->clickfunc == NULL) ++ continue; ++ if (br->monitor != 'A' && br->monitor != -1 && br->monitor != mi) ++ continue; ++ if (bar->x[r] <= ev->x && ev->x <= bar->x[r] + bar->w[r]) { ++ carg.rel_x = ev->x - bar->x[r]; ++ carg.rel_y = ev->y; ++ carg.rel_w = bar->w[r]; ++ carg.rel_h = bar->bh; ++ click = br->clickfunc(bar, &arg, &carg); ++ if (click < 0) ++ return; ++ break; ++ } ++ } ++ break; ++ } ++ } ++ ++ if (click == ClkRootWin && (c = wintoclient(ev->window))) { + focus(c); + restack(selmon); + XAllowEvents(dpy, ReplayPointer, CurrentTime); + click = ClkClientWin; + } +- for (i = 0; i < LENGTH(buttons); i++) ++ ++ for (i = 0; i < LENGTH(buttons); i++) { + if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button +- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) ++ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) { + buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); ++ } ++ } + } + + void +@@ -497,6 +570,7 @@ void + cleanupmon(Monitor *mon) + { + Monitor *m; ++ Bar *bar; + + if (mon == mons) + mons = mons->next; +@@ -504,8 +578,12 @@ cleanupmon(Monitor *mon) + for (m = mons; m && m->next != mon; m = m->next); + m->next = mon->next; + } +- XUnmapWindow(dpy, mon->barwin); +- XDestroyWindow(dpy, mon->barwin); ++ for (bar = mon->bar; bar; bar = mon->bar) { ++ XUnmapWindow(dpy, bar->win); ++ XDestroyWindow(dpy, bar->win); ++ mon->bar = bar->next; ++ free(bar); ++ } + free(mon); + } + +@@ -551,6 +629,7 @@ void + configurenotify(XEvent *e) + { + Monitor *m; ++ Bar *bar; + Client *c; + XConfigureEvent *ev = &e->xconfigure; + int dirty; +@@ -567,7 +646,8 @@ configurenotify(XEvent *e) + for (c = m->clients; c; c = c->next) + if (c->isfullscreen) + resizeclient(c, m->mx, m->my, m->mw, m->mh); +- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); ++ for (bar = m->bar; bar; bar = bar->next) ++ XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh); + } + focus(NULL); + arrange(NULL); +@@ -630,17 +710,40 @@ configurerequest(XEvent *e) + Monitor * + createmon(void) + { +- Monitor *m; ++ Monitor *m, *mon; ++ int i, n, mi, max_bars = 2, istopbar = topbar; ++ ++ const BarRule *br; ++ Bar *bar; + + m = ecalloc(1, sizeof(Monitor)); + m->tagset[0] = m->tagset[1] = 1; + m->mfact = mfact; + m->nmaster = nmaster; + m->showbar = showbar; +- m->topbar = topbar; ++ ++ for (mi = 0, mon = mons; mon; mon = mon->next, mi++); // monitor index + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); ++ ++ /* Derive the number of bars for this monitor based on bar rules */ ++ for (n = -1, i = 0; i < LENGTH(barrules); i++) { ++ br = &barrules[i]; ++ if (br->monitor == 'A' || br->monitor == -1 || br->monitor == mi) ++ n = MAX(br->bar, n); ++ } ++ ++ for (i = 0; i <= n && i < max_bars; i++) { ++ bar = ecalloc(1, sizeof(Bar)); ++ bar->mon = m; ++ bar->idx = i; ++ bar->next = m->bar; ++ bar->topbar = istopbar; ++ m->bar = bar; ++ istopbar = !istopbar; ++ } ++ + return m; + } + +@@ -695,62 +798,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; +- Client *c; +- +- /* 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); +- } +- +- for (c = m->clients; c; c = c->next) { +- occ |= c->tags; +- if (c->isurgent) +- urg |= c->tags; +- } +- x = 0; +- for (i = 0; i < LENGTH(tags); i++) { +- 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; +- } +- w = blw = TEXTW(m->ltsymbol); +- drw_setscheme(drw, scheme[SchemeNorm]); +- x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); +- +- 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); ++ Bar *bar; ++ for (bar = m->bar; bar; bar = bar->next) ++ drawbarwin(bar); + } + + void + drawbars(void) + { + Monitor *m; +- + for (m = mons; m; m = m->next) + drawbar(m); + } + ++void ++drawbarwin(Bar *bar) ++{ ++ if (!bar->win) ++ return; ++ Monitor *mon; ++ int r, w, mi; ++ int rx, lx, rw, lw; // bar size, split between left and right if a center module is added ++ const BarRule *br; ++ BarWidthArg warg = { 0 }; ++ BarDrawArg darg = { 0, 0 }; ++ ++ for (mi = 0, mon = mons; mon && mon != bar->mon; mon = mon->next, mi++); // get the monitor index ++ rw = lw = bar->bw; ++ rx = lx = 0; ++ ++ drw_setscheme(drw, scheme[SchemeNorm]); ++ drw_rect(drw, lx, 0, lw, bh, 1, 1); ++ for (r = 0; r < LENGTH(barrules); r++) { ++ br = &barrules[r]; ++ if (br->bar != bar->idx || br->drawfunc == NULL || (br->monitor == 'A' && bar->mon != selmon)) ++ continue; ++ if (br->monitor != 'A' && br->monitor != -1 && br->monitor != mi) ++ continue; ++ drw_setscheme(drw, scheme[SchemeNorm]); ++ warg.max_width = (br->alignment < BAR_ALIGN_RIGHT_LEFT ? lw : rw); ++ w = br->widthfunc(bar, &warg); ++ w = MIN(warg.max_width, w); ++ ++ if (lw <= 0) { // if left is exhausted then switch to right side, and vice versa ++ lw = rw; ++ lx = rx; ++ } else if (rw <= 0) { ++ rw = lw; ++ rx = lx; ++ } ++ ++ switch(br->alignment) { ++ default: ++ case BAR_ALIGN_NONE: ++ case BAR_ALIGN_LEFT_LEFT: ++ case BAR_ALIGN_LEFT: ++ bar->x[r] = lx; ++ if (lx == rx) { ++ rx += w; ++ rw -= w; ++ } ++ lx += w; ++ lw -= w; ++ break; ++ case BAR_ALIGN_LEFT_RIGHT: ++ case BAR_ALIGN_RIGHT: ++ bar->x[r] = lx + lw - w; ++ if (lx == rx) ++ rw -= w; ++ lw -= w; ++ break; ++ case BAR_ALIGN_LEFT_CENTER: ++ case BAR_ALIGN_CENTER: ++ bar->x[r] = lx + lw / 2 - w / 2; ++ if (lx == rx) { ++ rw = rx + rw - bar->x[r] - w; ++ rx = bar->x[r] + w; ++ } ++ lw = bar->x[r] - lx; ++ break; ++ case BAR_ALIGN_RIGHT_LEFT: ++ bar->x[r] = rx; ++ if (lx == rx) { ++ lx += w; ++ lw -= w; ++ } ++ rx += w; ++ rw -= w; ++ break; ++ case BAR_ALIGN_RIGHT_RIGHT: ++ bar->x[r] = rx + rw - w; ++ if (lx == rx) ++ lw -= w; ++ rw -= w; ++ break; ++ case BAR_ALIGN_RIGHT_CENTER: ++ bar->x[r] = rx + rw / 2 - w / 2; ++ if (lx == rx) { ++ lw = lx + lw - bar->x[r] + w; ++ lx = bar->x[r] + w; ++ } ++ rw = bar->x[r] - rx; ++ break; ++ } ++ bar->w[r] = w; ++ darg.x = bar->x[r]; ++ darg.w = bar->w[r]; ++ br->drawfunc(bar, &darg); ++ } ++ drw_map(drw, bar->win, 0, 0, bar->bw, bar->bh); ++} ++ + void + enternotify(XEvent *e) + { +@@ -1045,7 +1203,7 @@ manage(Window w, XWindowAttributes *wa) + c->y = c->mon->my + c->mon->mh - HEIGHT(c); + c->x = MAX(c->x, c->mon->mx); + /* only fix client y-offset, if the client center might cover the bar */ +- c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) ++ c->y = MAX(c->y, ((c->mon->bar->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) + && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); + c->bw = borderpx; + +@@ -1232,7 +1390,8 @@ propertynotify(XEvent *e) + break; + case XA_WM_HINTS: + updatewmhints(c); +- drawbars(); ++ if (c->isurgent) ++ drawbars(); + break; + } + if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { +@@ -1358,7 +1517,7 @@ restack(Monitor *m) + XRaiseWindow(dpy, m->sel->win); + if (m->lt[m->sellt]->arrange) { + wc.stack_mode = Below; +- wc.sibling = m->barwin; ++ wc.sibling = m->bar->win; + for (c = m->stack; c; c = c->snext) + if (!c->isfloating && ISVISIBLE(c)) { + XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); +@@ -1699,9 +1858,11 @@ tile(Monitor *m) + void + togglebar(const Arg *arg) + { ++ Bar *bar; + selmon->showbar = !selmon->showbar; + updatebarpos(selmon); +- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); ++ for (bar = selmon->bar; bar; bar = bar->next) ++ XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh); + arrange(selmon); + } + +@@ -1801,22 +1962,37 @@ unmapnotify(XEvent *e) + void + updatebars(void) + { ++ Bar *bar; + Monitor *m; + XSetWindowAttributes wa = { + .override_redirect = True, ++ #if BAR_ALPHA_PATCH ++ .background_pixel = 0, ++ .border_pixel = 0, ++ .colormap = cmap, ++ #else + .background_pixmap = ParentRelative, ++ #endif // BAR_ALPHA_PATCH + .event_mask = ButtonPressMask|ExposureMask + }; + XClassHint ch = {"dwm", "dwm"}; + for (m = mons; m; m = m->next) { +- if (m->barwin) +- continue; +- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), +- CopyFromParent, DefaultVisual(dpy, screen), +- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); +- XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); +- XMapRaised(dpy, m->barwin); +- XSetClassHint(dpy, m->barwin, &ch); ++ for (bar = m->bar; bar; bar = bar->next) { ++ if (!bar->win) { ++ #if BAR_ALPHA_PATCH ++ bar->win = XCreateWindow(dpy, root, bar->bx, bar->by, bar->bw, bar->bh, 0, depth, ++ InputOutput, visual, ++ CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa); ++ #else ++ bar->win = XCreateWindow(dpy, root, bar->bx, bar->by, bar->bw, bar->bh, 0, DefaultDepth(dpy, screen), ++ CopyFromParent, DefaultVisual(dpy, screen), ++ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); ++ #endif // BAR_ALPHA_PATCH ++ XDefineCursor(dpy, bar->win, cursor[CurNormal]->cursor); ++ XMapRaised(dpy, bar->win); ++ XSetClassHint(dpy, bar->win, &ch); ++ } ++ } + } + } + +@@ -1825,12 +2001,30 @@ updatebarpos(Monitor *m) + { + m->wy = m->my; + m->wh = m->mh; +- if (m->showbar) { +- m->wh -= bh; +- m->by = m->topbar ? m->wy : m->wy + m->wh; +- m->wy = m->topbar ? m->wy + bh : m->wy; +- } else +- m->by = -bh; ++ int num_bars; ++ Bar *bar; ++ int y_pad = 0; ++ int x_pad = 0; ++ ++ for (bar = m->bar; bar; bar = bar->next) { ++ bar->bx = m->mx + x_pad; ++ bar->bw = m->ww - 2 * x_pad; ++ bar->bh = bh; ++ } ++ ++ if (!m->showbar) { ++ for (bar = m->bar; bar; bar = bar->next) ++ bar->by = -bh - y_pad; ++ return; ++ } ++ ++ for (num_bars = 0, bar = m->bar; bar; bar = bar->next, num_bars++) ++ if (bar->topbar) ++ m->wy = m->my + bh + y_pad; ++ m->wh = m->wh - y_pad * num_bars - bh * num_bars; ++ ++ for (bar = m->bar; bar; bar = bar->next) ++ bar->by = (bar->topbar ? m->wy - bh : m->wy + m->wh); + } + + void +@@ -1987,9 +2181,11 @@ updatesizehints(Client *c) + void + updatestatus(void) + { ++ Monitor *m; + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + strcpy(stext, "dwm-"VERSION); +- drawbar(selmon); ++ for (m = mons; m; m = m->next) ++ drawbar(m); + } + + void +@@ -2063,12 +2259,14 @@ wintomon(Window w) + int x, y; + Client *c; + Monitor *m; ++ Bar *bar; + + if (w == root && getrootptr(&x, &y)) + return recttomon(x, y, 1, 1); + for (m = mons; m; m = m->next) +- if (w == m->barwin) +- return m; ++ for (bar = m->bar; bar; bar = bar->next) ++ if (w == bar->win) ++ return m; + if ((c = wintoclient(w))) + return c->mon; + return selmon; +diff --git a/patch/bar_ltsymbol.c b/patch/bar_ltsymbol.c +new file mode 100644 +index 0000000..6676a2a +--- /dev/null ++++ b/patch/bar_ltsymbol.c +@@ -0,0 +1,17 @@ ++int ++width_ltsymbol(Bar *bar, BarWidthArg *a) ++{ ++ return TEXTW(bar->mon->ltsymbol); ++} ++ ++int ++draw_ltsymbol(Bar *bar, BarDrawArg *a) ++{ ++ return drw_text(drw, a->x, 0, a->w, bh, lrpad / 2, bar->mon->ltsymbol, 0); ++} ++ ++int ++click_ltsymbol(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ return ClkLtSymbol; ++} +diff --git a/patch/bar_ltsymbol.h b/patch/bar_ltsymbol.h +new file mode 100644 +index 0000000..d9c79bf +--- /dev/null ++++ b/patch/bar_ltsymbol.h +@@ -0,0 +1,3 @@ ++static int width_ltsymbol(Bar *bar, BarWidthArg *a); ++static int draw_ltsymbol(Bar *bar, BarDrawArg *a); ++static int click_ltsymbol(Bar *bar, Arg *arg, BarClickArg *a); +diff --git a/patch/bar_status.c b/patch/bar_status.c +new file mode 100644 +index 0000000..7d27282 +--- /dev/null ++++ b/patch/bar_status.c +@@ -0,0 +1,19 @@ ++int ++width_status(Bar *bar, BarWidthArg *a) ++{ ++ return TEXTW(stext); ++} ++ ++ ++int ++draw_status(Bar *bar, BarDrawArg *a) ++{ ++ return drw_text(drw, a->x, 0, a->w, bh, lrpad / 2, stext, 0); ++} ++ ++ ++int ++click_status(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ return ClkStatusText; ++} +diff --git a/patch/bar_status.h b/patch/bar_status.h +new file mode 100644 +index 0000000..b02a4b8 +--- /dev/null ++++ b/patch/bar_status.h +@@ -0,0 +1,3 @@ ++static int width_status(Bar *bar, BarWidthArg *a); ++static int draw_status(Bar *bar, BarDrawArg *a); ++static int click_status(Bar *bar, Arg *arg, BarClickArg *a); +diff --git a/patch/bar_tags.c b/patch/bar_tags.c +new file mode 100644 +index 0000000..680e1fe +--- /dev/null ++++ b/patch/bar_tags.c +@@ -0,0 +1,55 @@ ++int ++width_tags(Bar *bar, BarWidthArg *a) ++{ ++ int w, i; ++ ++ for (w = 0, i = 0; i < LENGTH(tags); i++) { ++ w += TEXTW(tags[i]); ++ } ++ return w; ++} ++ ++int ++draw_tags(Bar *bar, BarDrawArg *a) ++{ ++ int invert; ++ int w, x = a->x; ++ int boxs = drw->fonts->h / 9; ++ int boxw = drw->fonts->h / 6 + 2; ++ unsigned int i, occ = 0, urg = 0; ++ Client *c; ++ Monitor *m = bar->mon; ++ ++ for (c = m->clients; c; c = c->next) { ++ occ |= c->tags; ++ if (c->isurgent) ++ urg |= c->tags; ++ } ++ ++ for (i = 0; i < LENGTH(tags); i++) { ++ invert = urg & 1 << i; ++ 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], invert); ++ if (occ & 1 << i) ++ drw_rect(drw, x + boxs, boxs, boxw, boxw, ++ m == selmon && selmon->sel && selmon->sel->tags & 1 << i, invert); ++ x += w; ++ } ++ ++ return x; ++} ++ ++int ++click_tags(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ int i = 0, x = lrpad / 2; ++ ++ do { ++ x += TEXTW(tags[i]); ++ } while (a->rel_x >= x && ++i < LENGTH(tags)); ++ if (i < LENGTH(tags)) { ++ arg->ui = 1 << i; ++ } ++ return ClkTagBar; ++} +diff --git a/patch/bar_tags.h b/patch/bar_tags.h +new file mode 100644 +index 0000000..7ac04d8 +--- /dev/null ++++ b/patch/bar_tags.h +@@ -0,0 +1,3 @@ ++static int width_tags(Bar *bar, BarWidthArg *a); ++static int draw_tags(Bar *bar, BarDrawArg *a); ++static int click_tags(Bar *bar, Arg *arg, BarClickArg *a); +diff --git a/patch/bar_wintitle.c b/patch/bar_wintitle.c +new file mode 100644 +index 0000000..3c11b75 +--- /dev/null ++++ b/patch/bar_wintitle.c +@@ -0,0 +1,31 @@ ++int ++width_wintitle(Bar *bar, BarWidthArg *a) ++{ ++ return a->max_width; ++} ++ ++int ++draw_wintitle(Bar *bar, BarDrawArg *a) ++{ ++ int boxs = drw->fonts->h / 9; ++ int boxw = drw->fonts->h / 6 + 2; ++ int x = a->x, w = a->w; ++ Monitor *m = bar->mon; ++ ++ 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); ++ } ++ return x + w; ++} ++ ++int ++click_wintitle(Bar *bar, Arg *arg, BarClickArg *a) ++{ ++ return ClkWinTitle; ++} +diff --git a/patch/bar_wintitle.h b/patch/bar_wintitle.h +new file mode 100644 +index 0000000..266404c +--- /dev/null ++++ b/patch/bar_wintitle.h +@@ -0,0 +1,3 @@ ++static int width_wintitle(Bar *bar, BarWidthArg *a); ++static int draw_wintitle(Bar *bar, BarDrawArg *a); ++static int click_wintitle(Bar *bar, Arg *arg, BarClickArg *a); +diff --git a/patch/include.c b/patch/include.c +new file mode 100644 +index 0000000..d422f56 +--- /dev/null ++++ b/patch/include.c +@@ -0,0 +1,5 @@ ++/* Bar functionality */ ++#include "bar_ltsymbol.c" ++#include "bar_status.c" ++#include "bar_tags.c" ++#include "bar_wintitle.c" +\ No newline at end of file +diff --git a/patch/include.h b/patch/include.h +new file mode 100644 +index 0000000..5f9a3fe +--- /dev/null ++++ b/patch/include.h +@@ -0,0 +1,5 @@ ++/* Bar functionality */ ++#include "bar_ltsymbol.h" ++#include "bar_status.h" ++#include "bar_tags.h" ++#include "bar_wintitle.h" +\ No newline at end of file +-- +2.19.1 + |