sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit a3f2b1e21130bde27b397725044477fa42b06ff5
parent 17262a2218936c4bb6ffd665d00c479ff546bf7c
Author: Mihir Lad <mihirlad55@gmail.com>
Date:   Sun,  9 Aug 2020 22:22:47 -0400

[dwm][patch][anybar] Update patch to v1.1.0

Also add v1.0.3 to v1.1.0 update patch.

Diffstat:
Ddwm.suckless.org/patches/anybar/dwm-anybar-20200721-bb2e722.diff | 304-------------------------------------------------------------------------------
Adwm.suckless.org/patches/anybar/dwm-anybar-20200810-bb2e722.diff | 335+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddwm.suckless.org/patches/anybar/dwm-anybar-polybar-tray-fix-20200721-bb2e722.diff | 414-------------------------------------------------------------------------------
Adwm.suckless.org/patches/anybar/dwm-anybar-polybar-tray-fix-20200810-bb2e722.diff | 445+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/anybar/dwm-anybar-v1.0.3-to-v1.1.0.diff | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdwm.suckless.org/patches/anybar/index.md | 10++++++----
6 files changed, 848 insertions(+), 722 deletions(-)

diff --git a/dwm.suckless.org/patches/anybar/dwm-anybar-20200721-bb2e722.diff b/dwm.suckless.org/patches/anybar/dwm-anybar-20200721-bb2e722.diff @@ -1,304 +0,0 @@ -From 31a6d3319c4299dcc6ea9735e12ee2a437a889e4 Mon Sep 17 00:00:00 2001 -From: mihirlad55 <mihirlad55@gmail.com> -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-20200810-bb2e722.diff b/dwm.suckless.org/patches/anybar/dwm-anybar-20200810-bb2e722.diff @@ -0,0 +1,335 @@ +From 782f63d8f858b1c14df38aaf623438d7ea2f75e1 Mon Sep 17 00:00:00 2001 +From: mihirlad55 <mihirlad55@gmail.com> +Date: Mon, 10 Aug 2020 01:39:35 +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 | 3 ++ + dwm.c | 114 ++++++++++++++++++++++++++++++++++++++++++++------- + 2 files changed, 103 insertions(+), 14 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1c0b587..d0d60aa 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 *altbarcmd = "$HOME/bar.sh"; /* Alternate bar launch command */ + 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..f149ab4 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); +@@ -207,6 +208,7 @@ static void seturgent(Client *c, int urg); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static void spawnbar(); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *); +@@ -216,6 +218,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 +233,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 +509,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 +574,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 +645,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 +656,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 +706,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 +1090,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 +1129,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 +1427,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 +1582,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); +@@ -1595,6 +1631,7 @@ setup(void) + XSelectInput(dpy, root, wa.event_mask); + grabkeys(); + focus(NULL); ++ spawnbar(); + } + + +@@ -1653,6 +1690,13 @@ spawn(const Arg *arg) + } + } + ++void ++spawnbar() ++{ ++ if (*altbarcmd) ++ system(altbarcmd); ++} ++ + void + tag(const Arg *arg) + { +@@ -1704,7 +1748,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 +1831,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 +1858,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 +1893,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 +2141,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.28.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 @@ -1,414 +0,0 @@ -From 62286f56a59ebd0ef7ee1308dd957d09c1ad0b11 Mon Sep 17 00:00:00 2001 -From: mihirlad55 <mihirlad55@gmail.com> -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/dwm-anybar-polybar-tray-fix-20200810-bb2e722.diff b/dwm.suckless.org/patches/anybar/dwm-anybar-polybar-tray-fix-20200810-bb2e722.diff @@ -0,0 +1,445 @@ +From 9b5719969ce85c3ecc0238d49c0255c5c2cc79f0 Mon Sep 17 00:00:00 2001 +From: mihirlad55 <mihirlad55@gmail.com> +Date: Mon, 10 Aug 2020 01:39:28 +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 | 4 ++ + dwm.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 181 insertions(+), 15 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1c0b587..f45211b 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -5,6 +5,10 @@ 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 *altbarcmd = "$HOME/bar.sh"; /* Alternate bar launch command */ + 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..c1d8ce0 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); +@@ -207,6 +212,7 @@ static void seturgent(Client *c, int urg); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static void spawnbar(); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *); +@@ -216,6 +222,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 +238,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 +514,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 +579,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 +650,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 +661,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 +713,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 +1097,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 +1156,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 +1454,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 +1471,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 +1632,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); +@@ -1595,6 +1681,7 @@ setup(void) + XSelectInput(dpy, root, wa.event_mask); + grabkeys(); + focus(NULL); ++ spawnbar(); + } + + +@@ -1653,6 +1740,13 @@ spawn(const Arg *arg) + } + } + ++void ++spawnbar() ++{ ++ if (*altbarcmd) ++ system(altbarcmd); ++} ++ + void + tag(const Arg *arg) + { +@@ -1702,9 +1796,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 +1890,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 +1932,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 +1969,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 +2210,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.28.0 + diff --git a/dwm.suckless.org/patches/anybar/dwm-anybar-v1.0.3-to-v1.1.0.diff b/dwm.suckless.org/patches/anybar/dwm-anybar-v1.0.3-to-v1.1.0.diff @@ -0,0 +1,62 @@ +From 8503e750d1e4627365b070db1ba44704ccddba0c Mon Sep 17 00:00:00 2001 +From: mihirlad55 <mihirlad55@gmail.com> +Date: Mon, 10 Aug 2020 01:39:28 +0000 +Subject: [PATCH] Update from v1.0.3 to v1.1.0 + +- The altbarcmd variable is added to config.def.h where the launch command for + the bar can be specified. This method of launching the bar ensures that the + bar does not launch too early before dwm is ready. +--- + config.def.h | 1 + + dwm.c | 9 +++++++++ + 2 files changed, 10 insertions(+) + +diff --git a/config.def.h b/config.def.h +index cb32018..d0d60aa 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -7,6 +7,7 @@ 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 *altbarcmd = "$HOME/bar.sh"; /* Alternate bar launch command */ + 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 74ec400..f149ab4 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -208,6 +208,7 @@ static void seturgent(Client *c, int urg); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static void spawnbar(); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *); +@@ -1630,6 +1631,7 @@ setup(void) + XSelectInput(dpy, root, wa.event_mask); + grabkeys(); + focus(NULL); ++ spawnbar(); + } + + +@@ -1688,6 +1690,13 @@ spawn(const Arg *arg) + } + } + ++void ++spawnbar() ++{ ++ if (*altbarcmd) ++ system(altbarcmd); ++} ++ + void + tag(const Arg *arg) + { +-- +2.28.0 + diff --git a/dwm.suckless.org/patches/anybar/index.md b/dwm.suckless.org/patches/anybar/index.md @@ -54,10 +54,12 @@ 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) +* Anybar Patch v1.1.0: + [dwm-anybar-20200810-bb2e722.diff](dwm-anybar-20200810-bb2e722.diff) +* Anybar Patch v1.0.3 to v1.1.0 Update: + [dwm-anybar-v1.0.3-to-v1.1.0.diff](dwm-anybar-v1.0.3-to-v1.1.0.diff) +* Anybar Patch (with Polybar tray fix) v1.1.0: + [dwm-anybar-polybar-tray-fix-20200810-bb2e722.diff](dwm-anybar-polybar-tray-fix-20200810-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