~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--bar_ltsymbol.c.rej20
-rw-r--r--bar_ltsymbol.h.rej6
-rw-r--r--patch/bar_ltsymbol.c17
-rw-r--r--patch/bar_ltsymbol.h3
-rw-r--r--patch/bar_status.c19
-rw-r--r--patch/bar_status.h3
-rw-r--r--patch/bar_tags.c55
-rw-r--r--patch/bar_tags.h3
-rw-r--r--patch/bar_wintitle.c31
-rw-r--r--patch/bar_wintitle.h3
-rw-r--r--patch/include.c5
-rw-r--r--patch/include.h5
-rw-r--r--patches/dwm-barmodules-6.2.diff894
14 files changed, 1066 insertions, 0 deletions
diff --git a/README.md b/README.md
index 20aa431..4bf5423 100644
--- a/README.md
+++ b/README.md
@@ -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
+