Return to repo list

suckless-gf-dwm

Gentoo-friendly patches for Suckless's dwm.
Return to HMagellan.com

commit b43d0ccb3a8e8804c65c6c38d975964245225276
parent 81e72b87099ef472260107a246242cee168e8353
Author: Erik Letson <hmagellan@hmagellan.com>
Date:   Thu, 13 Aug 2020 18:02:05 -0500

Added anybar (whew\!)

Diffstat:
Aanybar/USAGE | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aanybar/anybar-polybar-tray-fix.patch | 358+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aanybar/anybar.patch | 246+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mfocusonclick/USAGE | 3++-
4 files changed, 733 insertions(+), 1 deletion(-)

diff --git a/anybar/USAGE b/anybar/USAGE @@ -0,0 +1,127 @@ +anybar - Let dwm use external bars (e.g., polybar) +Source: https://dwm.suckless.org/patches/anybar/dwm-anybar-20200721-bb2e722.diff +Original Author: Mihir Lad - <mihirlad55 at gmail> + +Description from source: + """ + 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 + + 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 + """ + +== YOU MUST == +(1). Place the 'anybar.patch' file in /etc/portage/patches/x11-wm/dwm/ +(2). Add the following lines to your savedconfig file: + + static const int usealtbar = 1; /* 1 means use non-dwm status bar */ + static const char *altbarclass = "Polybar"; /* Alternate bar class name */ + + The string 'altbarclass' should be set to the class name of the external status bar. Find that with xprop(1). +(3). Run 'emerge dwm' + +== YOU PROBABLY SHOULD == +(1). This patch supports a custom bar launching command called 'altbarcmd'. According to the patch's GitHub + page (https://github.com/mihirlad55/dwm-anybar), using 'altbarcmd' is the prefered way to launch an external + bar with this patch. An example of using this in your savedconfig file is below: + + static const char *altbarcmd = "$HOME/bar.sh"; /* Alternate bar launch command */ + + '$HOME/bar.sh' should be changed to point to the executable script/program you want to use to launch your bar. +(2). It goes without saying, but to make this patch useful, you should install some sort of external status bar (e.g., polybar). +(3). If you are using polybar and want tray functionality, use the 'anybar-polybar-tray-fix' patch described below. + +== PATCH MODIFICATIONS == +(1). Re-implemented patch with diff -up rather than git-style, since portage didn't like the original. + +== INCOMPATIBILITIES == +No known specific incompatibilities. + +################################################################################################### +################################################################################################### + +anybar-polybar-tray-fix - anybar.patch fix for polybar tray +Source: https://dwm.suckless.org/patches/anybar/dwm-anybar-polybar-tray-fix-20200721-bb2e722.diff +Original Author: Mihir Lad - <mihirlad55 at gmail> + +Description from source: + """ + 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. + + 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 + """ + +== YOU MUST == +(1). Place the 'anybar-polybar-tray-fix.patch' file in /etc/portage/patches/x11-wm/dwm/ +(2). Add the following lines to your savedconfig file: + + 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 */ + + The string 'altbarclass' should be set to the class name of the external status bar. Find that with xprop(1). +(3). Run 'emerge dwm' + +== YOU PROBABLY SHOULD == +(1). This patch supports a custom bar launching command called 'altbarcmd'. According to the patch's GitHub + page (https://github.com/mihirlad55/dwm-anybar), using 'altbarcmd' is the prefered way to launch an external + bar with this patch. An example of using this in your savedconfig file is below: + + static const char *altbarcmd = "$HOME/bar.sh"; /* Alternate bar launch command */ + + '$HOME/bar.sh' should be changed to point to the executable script/program you want to use to launch your bar. +(2). It goes without saying, but to make this patch useful, you should install polybar ('emerge x11-misc/polybar') and + configure it. +(3). If you are not using polybar, or you do not care about polybar's tray functionality, use the 'anybar' patch described + above. + +== PATCH MODIFICATIONS == +(1). Re-implemented patch with diff -up rather than git-style, since portage didn't like the original. + +== INCOMPATIBILITIES == +No known specific incompatibilities. diff --git a/anybar/anybar-polybar-tray-fix.patch b/anybar/anybar-polybar-tray-fix.patch @@ -0,0 +1,358 @@ +diff -up a/dwm.c b/dwm.c +--- a/dwm.c 2020-08-13 14:18:03.871180006 -0500 ++++ b/dwm.c 2020-08-13 16:33:52.661982131 -0500 +@@ -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]; + }; + +@@ -178,6 +180,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); +@@ -194,6 +198,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); +@@ -215,6 +220,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); +@@ -229,6 +236,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); +@@ -504,8 +512,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); + } + +@@ -567,7 +577,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); +@@ -638,6 +648,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); +@@ -648,10 +659,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 +@@ -695,6 +711,9 @@ dirtomon(int dir) + void + drawbar(Monitor *m) + { ++ if (usealtbar) ++ return; ++ + int x, w, sw = 0; + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; +@@ -1077,6 +1096,44 @@ manage(Window w, XWindowAttributes *wa) + } + + 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) + { + XMappingEvent *ev = &e->xmapping; +@@ -1096,7 +1153,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); + } + +@@ -1392,7 +1451,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 +1469,27 @@ 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) + { + if (c->mon == m) +@@ -1545,7 +1627,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); +@@ -1699,9 +1781,17 @@ 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); + } + +@@ -1785,9 +1875,40 @@ unmanage(Client *c, int destroyed) + } + + 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))) { +@@ -1795,12 +1916,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, +@@ -1826,11 +1953,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 +@@ -2067,13 +2194,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. */ diff --git a/anybar/anybar.patch b/anybar/anybar.patch @@ -0,0 +1,246 @@ +diff -up a/dwm.c b/dwm.c +--- a/dwm.c 2020-08-13 14:18:03.871180006 -0500 ++++ b/dwm.c 2020-08-13 14:42:25.474213921 -0500 +@@ -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; +@@ -215,6 +215,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); +@@ -229,6 +230,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); +@@ -504,8 +506,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); + } + +@@ -567,7 +571,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); +@@ -638,6 +642,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); +@@ -648,10 +653,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 +@@ -695,6 +703,9 @@ dirtomon(int dir) + void + drawbar(Monitor *m) + { ++ if (usealtbar) ++ return; ++ + int x, w, sw = 0; + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; +@@ -1077,6 +1088,25 @@ manage(Window w, XWindowAttributes *wa) + } + + 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) + { + XMappingEvent *ev = &e->xmapping; +@@ -1096,6 +1126,8 @@ maprequest(XEvent *e) + return; + if (wa.override_redirect) + return; ++ if (wmclasscontains(ev->window, altbarclass, "")) ++ managealtbar(ev->window, &wa); + if (!wintoclient(ev->window)) + manage(ev->window, &wa); + } +@@ -1392,7 +1424,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 */ +@@ -1545,7 +1579,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); +@@ -1701,7 +1735,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); + } + +@@ -1785,9 +1819,25 @@ unmanage(Client *c, int destroyed) + } + + 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))) { +@@ -1795,12 +1845,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, +@@ -1826,11 +1880,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 +@@ -2074,6 +2128,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. */ +Only in b/: fixedanybar.patch diff --git a/focusonclick/USAGE b/focusonclick/USAGE @@ -12,12 +12,13 @@ Description from source: """ == YOU MUST == -(1). Place the patch file in /etc/portage/patches/x11-wm/dwm/ and run 'emerge dwm' +(1). Place the patch file in /etc/portage/patches/x11-wm/dwm/ (2). Add a line to your savedconfig file that looks like this: static const int focusonwheel = 0; It can be equal to either 0 (for no focus on mouse wheel click) or 1 (for the opposite). +(3). Run 'emerge dwm' == YOU PROBABLY SHOULD == No further action is required.