commit 0aa0d6b00671557b83dfb4f545c5a0fc4f615c24
Author: Mihir Lad <[email protected]>
Date:   Fri Jul 24 20:06:56 2020 -0400

    [dwm][patch] anybar initial commit

diff --git a/dwm.suckless.org/patches/anybar/dwm-anybar-20200721-bb2e722.diff 
b/dwm.suckless.org/patches/anybar/dwm-anybar-20200721-bb2e722.diff
new file mode 100644
index 00000000..632be6c6
--- /dev/null
+++ b/dwm.suckless.org/patches/anybar/dwm-anybar-20200721-bb2e722.diff
@@ -0,0 +1,304 @@
+From 31a6d3319c4299dcc6ea9735e12ee2a437a889e4 Mon Sep 17 00:00:00 2001
+From: mihirlad55 <[email protected]>
+Date: Tue, 21 Jul 2020 01:32:07 +0000
+Subject: [PATCH] Add support for managing external status bars
+
+This patch allows dwm to manage other status bars such as
+polybar/lemonbar without them needing to set override-redirect. For
+all intents and purposes, DWM treats this bar as if it were its own
+and as a result helps the status bar and DWM live in harmony.
+
+This has a few advantages
+* The bar does not block fullscreen windows
+* DWM makes room for the status bar, so windows do not overlap the bar
+* The bar can be hidden/killed and DWM will not keep an unsightly gap
+  where the bar was
+* DWM receives EnterNotify events when your cursor enters the bar
+
+To use another status bar, set usealtbar to 1 in your config.h and set
+altbarclass to the class name (can be found using xprop) to the class
+name of your status bar. Also make sure that if your status bar will
+be displayed on top, topbar is set to 1 in your config, and if it will
+be displayed on bottom, topbar is set to 0. This patch does not
+support bars that are not docked at the top or at the bottom of your
+monitor.
+
+The patch is developed at https://github.com/mihirlad55/dwm-anybar
+---
+ config.def.h |   2 +
+ dwm.c        | 105 ++++++++++++++++++++++++++++++++++++++++++++-------
+ 2 files changed, 93 insertions(+), 14 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..cb32018 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 int usealtbar          = 1;        /* 1 means use non-dwm status 
bar */
++static const char *altbarclass      = "Polybar"; /* Alternate bar class name 
*/
+ static const char *fonts[]          = { "monospace:size=10" };
+ static const char dmenufont[]       = "monospace:size=10";
+ static const char col_gray1[]       = "#222222";
+diff --git a/dwm.c b/dwm.c
+index 9fd0286..74ec400 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -47,8 +47,8 @@
+ /* macros */
+ #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)) \
+-                               * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - 
MAX((y),(m)->wy)))
++#define INTERSECT(x,y,w,h,m)    (MAX(0, MIN((x)+(w),(m)->mx+(m)->mw) - 
MAX((x),(m)->mx)) \
++                               * MAX(0, MIN((y)+(h),(m)->my+(m)->mh) - 
MAX((y),(m)->my)))
+ #define ISVISIBLE(C)            ((C->tags & C->mon->tagset[C->mon->seltags]))
+ #define LENGTH(X)               (sizeof X / sizeof X[0])
+ #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
+@@ -116,7 +116,7 @@ struct Monitor {
+       float mfact;
+       int nmaster;
+       int num;
+-      int by;               /* bar geometry */
++      int by, bh;           /* bar geometry */
+       int mx, my, mw, mh;   /* screen size */
+       int wx, wy, ww, wh;   /* window area  */
+       unsigned int seltags;
+@@ -179,6 +179,7 @@ static void incnmaster(const Arg *arg);
+ static void keypress(XEvent *e);
+ static void killclient(const Arg *arg);
+ static void manage(Window w, XWindowAttributes *wa);
++static void managealtbar(Window win, XWindowAttributes *wa);
+ static void mappingnotify(XEvent *e);
+ static void maprequest(XEvent *e);
+ static void monocle(Monitor *m);
+@@ -216,6 +217,7 @@ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+ static void unmanage(Client *c, int destroyed);
++static void unmanagealtbar(Window w);
+ static void unmapnotify(XEvent *e);
+ static void updatebarpos(Monitor *m);
+ static void updatebars(void);
+@@ -230,6 +232,7 @@ static void updatewmhints(Client *c);
+ static void view(const Arg *arg);
+ static Client *wintoclient(Window w);
+ static Monitor *wintomon(Window w);
++static int wmclasscontains(Window win, const char *class, const char *name);
+ static int xerror(Display *dpy, XErrorEvent *ee);
+ static int xerrordummy(Display *dpy, XErrorEvent *ee);
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+@@ -505,8 +508,10 @@ 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);
++      if (!usealtbar) {
++              XUnmapWindow(dpy, mon->barwin);
++              XDestroyWindow(dpy, mon->barwin);
++      }
+       free(mon);
+ }
+ 
+@@ -568,7 +573,7 @@ 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);
++                              XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, 
m->ww, m->bh);
+                       }
+                       focus(NULL);
+                       arrange(NULL);
+@@ -639,6 +644,7 @@ createmon(void)
+       m->nmaster = nmaster;
+       m->showbar = showbar;
+       m->topbar = topbar;
++      m->bh = bh;
+       m->lt[0] = &layouts[0];
+       m->lt[1] = &layouts[1 % LENGTH(layouts)];
+       strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+@@ -649,10 +655,13 @@ void
+ destroynotify(XEvent *e)
+ {
+       Client *c;
++      Monitor *m;
+       XDestroyWindowEvent *ev = &e->xdestroywindow;
+ 
+       if ((c = wintoclient(ev->window)))
+               unmanage(c, 1);
++      else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
++              unmanagealtbar(ev->window);
+ }
+ 
+ void
+@@ -696,6 +705,9 @@ dirtomon(int dir)
+ void
+ drawbar(Monitor *m)
+ {
++      if (usealtbar)
++              return;
++
+       int x, w, tw = 0;
+       int boxs = drw->fonts->h / 9;
+       int boxw = drw->fonts->h / 6 + 2;
+@@ -1077,6 +1089,25 @@ manage(Window w, XWindowAttributes *wa)
+       focus(NULL);
+ }
+ 
++void
++managealtbar(Window win, XWindowAttributes *wa)
++{
++      Monitor *m;
++      if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height)))
++              return;
++
++      m->barwin = win;
++      m->by = wa->y;
++      bh = m->bh = wa->height;
++      updatebarpos(m);
++      arrange(m);
++      XSelectInput(dpy, win, 
EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
++      XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height);
++      XMapWindow(dpy, win);
++      XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, 
PropModeAppend,
++              (unsigned char *) &win, 1);
++}
++
+ void
+ mappingnotify(XEvent *e)
+ {
+@@ -1097,7 +1128,9 @@ maprequest(XEvent *e)
+               return;
+       if (wa.override_redirect)
+               return;
+-      if (!wintoclient(ev->window))
++      if (wmclasscontains(ev->window, altbarclass, ""))
++              managealtbar(ev->window, &wa);
++      else if (!wintoclient(ev->window))
+               manage(ev->window, &wa);
+ }
+ 
+@@ -1393,7 +1426,9 @@ scan(void)
+                       if (!XGetWindowAttributes(dpy, wins[i], &wa)
+                       || wa.override_redirect || XGetTransientForHint(dpy, 
wins[i], &d1))
+                               continue;
+-                      if (wa.map_state == IsViewable || getstate(wins[i]) == 
IconicState)
++                      if (wmclasscontains(wins[i], altbarclass, ""))
++                              managealtbar(wins[i], &wa);
++                      else if (wa.map_state == IsViewable || 
getstate(wins[i]) == IconicState)
+                               manage(wins[i], &wa);
+               }
+               for (i = 0; i < num; i++) { /* now the transients */
+@@ -1546,7 +1581,7 @@ setup(void)
+       if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
+               die("no fonts could be loaded.");
+       lrpad = drw->fonts->h;
+-      bh = drw->fonts->h + 2;
++      bh = usealtbar ? 0 : drw->fonts->h + 2;
+       updategeom();
+       /* init atoms */
+       utf8string = XInternAtom(dpy, "UTF8_STRING", False);
+@@ -1704,7 +1739,7 @@ togglebar(const Arg *arg)
+ {
+       selmon->showbar = !selmon->showbar;
+       updatebarpos(selmon);
+-      XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, 
selmon->ww, bh);
++      XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, 
selmon->ww, selmon->bh);
+       arrange(selmon);
+ }
+ 
+@@ -1787,10 +1822,26 @@ unmanage(Client *c, int destroyed)
+       arrange(m);
+ }
+ 
++void
++unmanagealtbar(Window w)
++{
++    Monitor *m = wintomon(w);
++
++    if (!m)
++        return;
++
++    m->barwin = 0;
++    m->by = 0;
++    m->bh = 0;
++    updatebarpos(m);
++    arrange(m);
++}
++
+ void
+ unmapnotify(XEvent *e)
+ {
+       Client *c;
++      Monitor *m;
+       XUnmapEvent *ev = &e->xunmap;
+ 
+       if ((c = wintoclient(ev->window))) {
+@@ -1798,12 +1849,16 @@ unmapnotify(XEvent *e)
+                       setclientstate(c, WithdrawnState);
+               else
+                       unmanage(c, 0);
+-      }
++      } else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
++              unmanagealtbar(ev->window);
+ }
+ 
+ void
+ updatebars(void)
+ {
++      if (usealtbar)
++              return;
++
+       Monitor *m;
+       XSetWindowAttributes wa = {
+               .override_redirect = True,
+@@ -1829,11 +1884,11 @@ updatebarpos(Monitor *m)
+       m->wy = m->my;
+       m->wh = m->mh;
+       if (m->showbar) {
+-              m->wh -= bh;
++              m->wh -= m->bh;
+               m->by = m->topbar ? m->wy : m->wy + m->wh;
+-              m->wy = m->topbar ? m->wy + bh : m->wy;
++              m->wy = m->topbar ? m->wy + m->bh : m->wy;
+       } else
+-              m->by = -bh;
++              m->by = -m->bh;
+ }
+ 
+ void
+@@ -2077,6 +2132,28 @@ wintomon(Window w)
+       return selmon;
+ }
+ 
++int
++wmclasscontains(Window win, const char *class, const char *name)
++{
++      XClassHint ch = { NULL, NULL };
++      int res = 1;
++
++      if (XGetClassHint(dpy, win, &ch)) {
++              if (ch.res_name && strstr(ch.res_name, name) == NULL)
++                      res = 0;
++              if (ch.res_class && strstr(ch.res_class, class) == NULL)
++                      res = 0;
++      } else
++              res = 0;
++
++      if (ch.res_class)
++              XFree(ch.res_class);
++      if (ch.res_name)
++              XFree(ch.res_name);
++
++      return res;
++}
++
+ /* There's no way to check accesses to destroyed windows, thus those cases are
+  * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
+  * default error handler, which may call exit. */
+-- 
+2.27.0
+
diff --git 
a/dwm.suckless.org/patches/anybar/dwm-anybar-polybar-tray-fix-20200721-bb2e722.diff
 
b/dwm.suckless.org/patches/anybar/dwm-anybar-polybar-tray-fix-20200721-bb2e722.diff
new file mode 100644
index 00000000..e52354b7
--- /dev/null
+++ 
b/dwm.suckless.org/patches/anybar/dwm-anybar-polybar-tray-fix-20200721-bb2e722.diff
@@ -0,0 +1,414 @@
+From 62286f56a59ebd0ef7ee1308dd957d09c1ad0b11 Mon Sep 17 00:00:00 2001
+From: mihirlad55 <[email protected]>
+Date: Tue, 21 Jul 2020 01:32:06 +0000
+Subject: [PATCH] Add support for managing external status bars
+
+This patch allows dwm to manage other status bars such as
+polybar/lemonbar without them needing to set override-redirect. For
+all intents and purposes, DWM treats this bar as if it were its own
+and as a result helps the status bar and DWM live in harmony.
+
+This has a few advantages
+* The bar does not block fullscreen windows
+* DWM makes room for the status bar, so windows do not overlap the bar
+* The bar can be hidden/killed and DWM will not keep an unsightly gap
+  where the bar was
+* DWM receives EnterNotify events when your cursor enters the bar
+
+To use another status bar, set usealtbar to 1 in your config.h and set
+altbarclass to the class name (can be found using xprop) to the class
+name of your status bar. Also make sure that if your status bar will
+be displayed on top, topbar is set to 1 in your config, and if it will
+be displayed on bottom, topbar is set to 0. This patch does not
+support bars that are not docked at the top or at the bottom of your
+monitor.
+
+This verison of the patch fixes handling of polybar's tray.
+
+The patch is developed at https://github.com/mihirlad55/dwm-anybar
+---
+ config.def.h |   3 +
+ dwm.c        | 183 ++++++++++++++++++++++++++++++++++++++++++++++-----
+ 2 files changed, 171 insertions(+), 15 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..6dc83bd 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -5,6 +5,9 @@ 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 int usealtbar          = 1;        /* 1 means use non-dwm status 
bar */
++static const char *altbarclass      = "Polybar"; /* Alternate bar class name 
*/
++static const char *alttrayname      = "tray";    /* Polybar tray instance 
name */
+ static const char *fonts[]          = { "monospace:size=10" };
+ static const char dmenufont[]       = "monospace:size=10";
+ static const char col_gray1[]       = "#222222";
+diff --git a/dwm.c b/dwm.c
+index 9fd0286..c8fd4b2 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -47,8 +47,8 @@
+ /* macros */
+ #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)) \
+-                               * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - 
MAX((y),(m)->wy)))
++#define INTERSECT(x,y,w,h,m)    (MAX(0, MIN((x)+(w),(m)->mx+(m)->mw) - 
MAX((x),(m)->mx)) \
++                               * MAX(0, MIN((y)+(h),(m)->my+(m)->mh) - 
MAX((y),(m)->my)))
+ #define ISVISIBLE(C)            ((C->tags & C->mon->tagset[C->mon->seltags]))
+ #define LENGTH(X)               (sizeof X / sizeof X[0])
+ #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
+@@ -116,7 +116,8 @@ struct Monitor {
+       float mfact;
+       int nmaster;
+       int num;
+-      int by;               /* bar geometry */
++      int by, bh;           /* bar geometry */
++      int tx, tw;           /* bar tray geometry */
+       int mx, my, mw, mh;   /* screen size */
+       int wx, wy, ww, wh;   /* window area  */
+       unsigned int seltags;
+@@ -129,6 +130,7 @@ struct Monitor {
+       Client *stack;
+       Monitor *next;
+       Window barwin;
++      Window traywin;
+       const Layout *lt[2];
+ };
+ 
+@@ -179,6 +181,8 @@ static void incnmaster(const Arg *arg);
+ static void keypress(XEvent *e);
+ static void killclient(const Arg *arg);
+ static void manage(Window w, XWindowAttributes *wa);
++static void managealtbar(Window win, XWindowAttributes *wa);
++static void managetray(Window win, XWindowAttributes *wa);
+ static void mappingnotify(XEvent *e);
+ static void maprequest(XEvent *e);
+ static void monocle(Monitor *m);
+@@ -195,6 +199,7 @@ static void resizemouse(const Arg *arg);
+ static void restack(Monitor *m);
+ static void run(void);
+ static void scan(void);
++static void scantray(void);
+ static int sendevent(Client *c, Atom proto);
+ static void sendmon(Client *c, Monitor *m);
+ static void setclientstate(Client *c, long state);
+@@ -216,6 +221,8 @@ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+ static void unmanage(Client *c, int destroyed);
++static void unmanagealtbar(Window w);
++static void unmanagetray(Window w);
+ static void unmapnotify(XEvent *e);
+ static void updatebarpos(Monitor *m);
+ static void updatebars(void);
+@@ -230,6 +237,7 @@ static void updatewmhints(Client *c);
+ static void view(const Arg *arg);
+ static Client *wintoclient(Window w);
+ static Monitor *wintomon(Window w);
++static int wmclasscontains(Window win, const char *class, const char *name);
+ static int xerror(Display *dpy, XErrorEvent *ee);
+ static int xerrordummy(Display *dpy, XErrorEvent *ee);
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+@@ -505,8 +513,10 @@ 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);
++      if (!usealtbar) {
++              XUnmapWindow(dpy, mon->barwin);
++              XDestroyWindow(dpy, mon->barwin);
++      }
+       free(mon);
+ }
+ 
+@@ -568,7 +578,7 @@ 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);
++                              XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, 
m->ww, m->bh);
+                       }
+                       focus(NULL);
+                       arrange(NULL);
+@@ -639,6 +649,7 @@ createmon(void)
+       m->nmaster = nmaster;
+       m->showbar = showbar;
+       m->topbar = topbar;
++      m->bh = bh;
+       m->lt[0] = &layouts[0];
+       m->lt[1] = &layouts[1 % LENGTH(layouts)];
+       strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+@@ -649,10 +660,15 @@ void
+ destroynotify(XEvent *e)
+ {
+       Client *c;
++      Monitor *m;
+       XDestroyWindowEvent *ev = &e->xdestroywindow;
+ 
+       if ((c = wintoclient(ev->window)))
+               unmanage(c, 1);
++      else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
++              unmanagealtbar(ev->window);
++      else if (m->traywin == ev->window)
++              unmanagetray(ev->window);
+ }
+ 
+ void
+@@ -696,6 +712,9 @@ dirtomon(int dir)
+ void
+ drawbar(Monitor *m)
+ {
++      if (usealtbar)
++              return;
++
+       int x, w, tw = 0;
+       int boxs = drw->fonts->h / 9;
+       int boxw = drw->fonts->h / 6 + 2;
+@@ -1077,6 +1096,45 @@ manage(Window w, XWindowAttributes *wa)
+       focus(NULL);
+ }
+ 
++void
++managealtbar(Window win, XWindowAttributes *wa)
++{
++      Monitor *m;
++      if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height)))
++              return;
++
++      m->barwin = win;
++      m->by = wa->y;
++      bh = m->bh = wa->height;
++      updatebarpos(m);
++      arrange(m);
++      XSelectInput(dpy, win, 
EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
++      XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height);
++      XMapWindow(dpy, win);
++      XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, 
PropModeAppend,
++              (unsigned char *) &win, 1);
++}
++
++void
++managetray(Window win, XWindowAttributes *wa)
++{
++      Monitor *m;
++      if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height)))
++              return;
++
++      m->traywin = win;
++      m->tx = wa->x;
++      m->tw = wa->width;
++      updatebarpos(m);
++      arrange(m);
++      XSelectInput(dpy, win, 
EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
++      XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height);
++      XMapWindow(dpy, win);
++      XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, 
PropModeAppend,
++                      (unsigned char *) &win, 1);
++}
++
++
+ void
+ mappingnotify(XEvent *e)
+ {
+@@ -1097,7 +1155,9 @@ maprequest(XEvent *e)
+               return;
+       if (wa.override_redirect)
+               return;
+-      if (!wintoclient(ev->window))
++      if (wmclasscontains(ev->window, altbarclass, ""))
++              managealtbar(ev->window, &wa);
++      else if (!wintoclient(ev->window))
+               manage(ev->window, &wa);
+ }
+ 
+@@ -1393,7 +1453,9 @@ scan(void)
+                       if (!XGetWindowAttributes(dpy, wins[i], &wa)
+                       || wa.override_redirect || XGetTransientForHint(dpy, 
wins[i], &d1))
+                               continue;
+-                      if (wa.map_state == IsViewable || getstate(wins[i]) == 
IconicState)
++                      if (wmclasscontains(wins[i], altbarclass, ""))
++                              managealtbar(wins[i], &wa);
++                      else if (wa.map_state == IsViewable || 
getstate(wins[i]) == IconicState)
+                               manage(wins[i], &wa);
+               }
+               for (i = 0; i < num; i++) { /* now the transients */
+@@ -1408,6 +1470,29 @@ scan(void)
+       }
+ }
+ 
++void
++scantray(void)
++{
++      unsigned int num;
++      Window d1, d2, *wins = NULL;
++      XWindowAttributes wa;
++
++      if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
++              for (unsigned int i = 0; i < num; i++) {
++                      if (wmclasscontains(wins[i], altbarclass, alttrayname)) 
{
++                              if (!XGetWindowAttributes(dpy, wins[i], &wa))
++                                      break;
++                              managetray(wins[i], &wa);
++                      }
++              }
++      }
++
++      if (wins)
++              XFree(wins);
++}
++
++
++
+ void
+ sendmon(Client *c, Monitor *m)
+ {
+@@ -1546,7 +1631,7 @@ setup(void)
+       if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
+               die("no fonts could be loaded.");
+       lrpad = drw->fonts->h;
+-      bh = drw->fonts->h + 2;
++      bh = usealtbar ? 0 : drw->fonts->h + 2;
+       updategeom();
+       /* init atoms */
+       utf8string = XInternAtom(dpy, "UTF8_STRING", False);
+@@ -1702,9 +1787,18 @@ tile(Monitor *m)
+ void
+ togglebar(const Arg *arg)
+ {
++      /**
++     * Polybar tray does not raise maprequest event. It must be manually 
scanned
++       * for. Scanning it too early while the tray is being populated would 
give
++       * wrong dimensions.
++     */
++      if (!selmon->traywin)
++              scantray();
++
+       selmon->showbar = !selmon->showbar;
+       updatebarpos(selmon);
+-      XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, 
selmon->ww, bh);
++      XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, 
selmon->ww, selmon->bh);
++      XMoveResizeWindow(dpy, selmon->traywin, selmon->tx, selmon->by, 
selmon->tw, selmon->bh);
+       arrange(selmon);
+ }
+ 
+@@ -1787,10 +1881,41 @@ unmanage(Client *c, int destroyed)
+       arrange(m);
+ }
+ 
++void
++unmanagealtbar(Window w)
++{
++    Monitor *m = wintomon(w);
++
++    if (!m)
++        return;
++
++    m->barwin = 0;
++    m->by = 0;
++    m->bh = 0;
++    updatebarpos(m);
++    arrange(m);
++}
++
++void
++unmanagetray(Window w)
++{
++      Monitor *m = wintomon(w);
++
++      if (!m)
++              return;
++
++      m->traywin = 0;
++      m->tx = 0;
++      m->tw = 0;
++      updatebarpos(m);
++      arrange(m);
++}
++
+ void
+ unmapnotify(XEvent *e)
+ {
+       Client *c;
++      Monitor *m;
+       XUnmapEvent *ev = &e->xunmap;
+ 
+       if ((c = wintoclient(ev->window))) {
+@@ -1798,12 +1923,18 @@ unmapnotify(XEvent *e)
+                       setclientstate(c, WithdrawnState);
+               else
+                       unmanage(c, 0);
+-      }
++      } else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
++              unmanagealtbar(ev->window);
++      else if (m->traywin == ev->window)
++              unmanagetray(ev->window);
+ }
+ 
+ void
+ updatebars(void)
+ {
++      if (usealtbar)
++              return;
++
+       Monitor *m;
+       XSetWindowAttributes wa = {
+               .override_redirect = True,
+@@ -1829,11 +1960,11 @@ updatebarpos(Monitor *m)
+       m->wy = m->my;
+       m->wh = m->mh;
+       if (m->showbar) {
+-              m->wh -= bh;
++              m->wh -= m->bh;
+               m->by = m->topbar ? m->wy : m->wy + m->wh;
+-              m->wy = m->topbar ? m->wy + bh : m->wy;
++              m->wy = m->topbar ? m->wy + m->bh : m->wy;
+       } else
+-              m->by = -bh;
++              m->by = -m->bh;
+ }
+ 
+ void
+@@ -2070,13 +2201,35 @@ wintomon(Window w)
+       if (w == root && getrootptr(&x, &y))
+               return recttomon(x, y, 1, 1);
+       for (m = mons; m; m = m->next)
+-              if (w == m->barwin)
++              if (w == m->barwin || w == m->traywin)
+                       return m;
+       if ((c = wintoclient(w)))
+               return c->mon;
+       return selmon;
+ }
+ 
++int
++wmclasscontains(Window win, const char *class, const char *name)
++{
++      XClassHint ch = { NULL, NULL };
++      int res = 1;
++
++      if (XGetClassHint(dpy, win, &ch)) {
++              if (ch.res_name && strstr(ch.res_name, name) == NULL)
++                      res = 0;
++              if (ch.res_class && strstr(ch.res_class, class) == NULL)
++                      res = 0;
++      } else
++              res = 0;
++
++      if (ch.res_class)
++              XFree(ch.res_class);
++      if (ch.res_name)
++              XFree(ch.res_name);
++
++      return res;
++}
++
+ /* There's no way to check accesses to destroyed windows, thus those cases are
+  * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
+  * default error handler, which may call exit. */
+-- 
+2.27.0
+
diff --git a/dwm.suckless.org/patches/anybar/index.md 
b/dwm.suckless.org/patches/anybar/index.md
new file mode 100644
index 00000000..c35ddfe7
--- /dev/null
+++ b/dwm.suckless.org/patches/anybar/index.md
@@ -0,0 +1,75 @@
+anybar
+======
+
+Description
+-----------
+**dwm-anybar** is a patch for dwm that enables dwm to manage external status
+bars such as lemonbar and polybar. dwm treats the external bar as it would its
+own, so all regular dwm commands such as togglebar affect the external bar in
+the same way.
+
+The project is being managed and developed on this GitHub
+[repo](https://github.com/mihirlad55/dwm-anybar). If you discover any bugs or
+patch incompatabilities, feel free to create an issue there.
+
+
+Configuration
+-------------
+    static const int showbar       = 1;          /* 0 means no bar */
+    static const int topbar        = 1;          /* 0 means bottom bar */
+    static const int usealtbar     = 1;          /* 1 means use non-dwm status 
bar */
+    static const char *altbarclass = "Polybar";  /* Alternate bar class name */
+
+`showbar` and `topbar` affect the external status bar as it would dwm's status
+bar. `showbar` must be `1` to show the external bar. `topbar` must be set
+appropriately as well based on if the external bar is docked at the bottom or
+the top of the screen. The patch only supports bars docked at the top/bottom of
+the monitor.
+
+`usealtbar` must be set to `1` to use an external status bar, otherwise dwm's
+own bar will be enabled.
+
+`altbarclass` must be set to the class name of the external status bar for dwm
+to differentiate it from regular windows. The class name of the bar can be 
found
+using `xprop`
+
+       xprop(1):
+        WM_CLASS(STRING) = instance, class
+                                     ^^^^^
+                                      altbarclass should be set to this
+        WM_NAME(STRING) = title
+
+
+Polybar Tray Fix
+----------------
+Since polybar's tray is handled as a separate window and is populated slowly, 
it
+is difficult to manage. There is a `polybar-tray-fix` version of the patch that
+allows dwm to manage the tray. The tray isn't actually managed until the
+togglebar command is called, but it fixes the issue where toggling the bar 
would
+not hide the tray.
+
+This version of the patch adds `alttrayname` to `config.def.h` which is already
+set to the correct value.
+
+
+Download
+--------
+* Anybar Patch v1.0.3:
+  [dwm-anybar-20200721-bb2e722.diff](dwm-anybar-20200721-bb2e722.diff)
+* Anybar Patch (with Polybar tray fix) v1.0.3:
+  
[dwm-anybar-polybar-tray-fix-20200721-bb2e722.diff](dwm-anybar-polybar-tray-fix-20200721-bb2e722.diff)
+
+The latest releases of the patch will always be available first on the project
+[Releases](https://github.com/mihirlad55/dwm-anybar/releases) page. There are
+also "update" patches to update from previous versions of the patch.
+
+
+Related Projects
+----------------
+* [polybar-dwm-module](https://github.com/mihirlad55/polybar-dwm-module)
+  works better with this patch
+
+
+Authors
+-------
+* Mihir Lad - <mihirlad55 at gmail>


Reply via email to