sites

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

commit 2b88d5a313d1e22560a930ea14166412f4d5e5c0
parent 47d5115fcbd39cfc4a638a7812b88c54a03c21a0
Author: BrunoCooper17 <BrunoCooper17@outlook.com>
Date:   Wed, 23 Jun 2021 11:28:49 -0500

[dwm][patch][single_tagset] Fix patch to make it work with last commit (67d76bd)

Diffstat:
Adwm.suckless.org/patches/single_tagset/dwm-single_tagset-20210623-67d76bd.diff | 552+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdwm.suckless.org/patches/single_tagset/index.md | 2++
2 files changed, 554 insertions(+), 0 deletions(-)

diff --git a/dwm.suckless.org/patches/single_tagset/dwm-single_tagset-20210623-67d76bd.diff b/dwm.suckless.org/patches/single_tagset/dwm-single_tagset-20210623-67d76bd.diff @@ -0,0 +1,552 @@ +From 116830e90487d53cbe44c05a8c0ffe8985e1509e Mon Sep 17 00:00:00 2001 +From: BrunoCooper17 <BrunoCooper17@outlook.com> +Date: Tue, 22 Jun 2021 22:31:37 -0500 +Subject: [PATCH] An updated single_tagset patch for dwm-6.2 + +Description +This patch addresses the multi-monitor setup. Instead of having separate tags for every monitor there is just one list of tags for all monitors. Instead of moving windows from one monitor to the other, the desired tag from the other monitor can just be selected and all windows will be drawn on the current monitor. + +Several deep changes needed to be made: + +Macro ISVISIBLE expects a second parameter, the monitor +Monitor->clients and Monitor->stack were moved to the global variable Clientlist cl. All monitors refer to this one list. +A new method attachclients was added. When changing between tags this function ensures that all clients are pointing to the right monitor. + +Authors +Jan Christoph Ebersbach - jceb@e-jc.de +Mohammad Zeinali - mzeinali@tutanota.com +Jesus Mastache Caballero - <BrunoCooper17@outlook.com> + +--- + dwm.c | 226 ++++++++++++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 171 insertions(+), 55 deletions(-) + +diff --git a/dwm.c b/dwm.c +index b0b3466..10d7f6e 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -49,7 +49,7 @@ + #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 ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) ++#define ISVISIBLE(C, M) ((C->tags & M->tagset[M->seltags])) + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define MOUSEMASK (BUTTONMASK|PointerMotionMask) + #define WIDTH(X) ((X)->w + 2 * (X)->bw) +@@ -82,6 +82,7 @@ typedef struct { + const Arg arg; + } Button; + ++typedef struct Clientlist Clientlist; + typedef struct Monitor Monitor; + typedef struct Client Client; + struct Client { +@@ -124,9 +125,8 @@ struct Monitor { + unsigned int tagset[2]; + int showbar; + int topbar; +- Client *clients; ++ Clientlist *cl; + Client *sel; +- Client *stack; + Monitor *next; + Window barwin; + const Layout *lt[2]; +@@ -141,12 +141,18 @@ typedef struct { + int monitor; + } Rule; + ++struct Clientlist { ++ Client *clients; ++ Client *stack; ++}; ++ + /* function declarations */ + static void applyrules(Client *c); + static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); + static void arrange(Monitor *m); + static void arrangemon(Monitor *m); + static void attach(Client *c); ++static void attachclients(Monitor *m); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -184,7 +190,7 @@ static void maprequest(XEvent *e); + static void monocle(Monitor *m); + static void motionnotify(XEvent *e); + static void movemouse(const Arg *arg); +-static Client *nexttiled(Client *c); ++static Client *nexttiled(Client *c, Monitor *m); + static void pop(Client *); + static void propertynotify(XEvent *e); + static void quit(const Arg *arg); +@@ -268,6 +274,7 @@ static Display *dpy; + static Drw *drw; + static Monitor *mons, *selmon; + static Window root, wmcheckwin; ++static Clientlist *cl; + + /* configuration, allows nested code to access above variables */ + #include "config.h" +@@ -300,7 +307,7 @@ applyrules(Client *c) + { + c->isfloating = r->isfloating; + c->tags |= r->tags; +- for (m = mons; m && m->num != r->monitor; m = m->next); ++ for (m = mons; m && (m->tagset[m->seltags] & c->tags) == 0; m = m->next); + if (m) + c->mon = m; + } +@@ -382,9 +389,9 @@ void + arrange(Monitor *m) + { + if (m) +- showhide(m->stack); ++ showhide(m->cl->stack); + else for (m = mons; m; m = m->next) +- showhide(m->stack); ++ showhide(m->cl->stack); + if (m) { + arrangemon(m); + restack(m); +@@ -403,15 +410,49 @@ arrangemon(Monitor *m) + void + attach(Client *c) + { +- c->next = c->mon->clients; +- c->mon->clients = c; ++ c->next = c->mon->cl->clients; ++ c->mon->cl->clients = c; ++} ++ ++void ++attachclients(Monitor *m) { ++ /* attach clients to the specified monitor */ ++ Monitor *tm; ++ Client *c; ++ unsigned int utags = 0; ++ Bool rmons = False; ++ if(!m) ++ return; ++ ++ /* collect information about the tags in use */ ++ for (tm = mons; tm; tm = tm->next) ++ if(tm != m) ++ utags |= tm->tagset[tm->seltags]; ++ ++ for (c = m->cl->clients; c; c = c->next) ++ if(ISVISIBLE(c, m)) { ++ /* if client is also visible on other tags that are displayed on ++ * other monitors, remove these tags */ ++ if(c->tags & utags) { ++ c->tags = c->tags & m->tagset[m->seltags]; ++ rmons = True; ++ } ++ unfocus(c, True); ++ c->mon = m; ++ } ++ ++ if (rmons) ++ for (tm = mons; tm; tm = tm->next) ++ if(tm != m) ++ arrange(tm); ++ + } + + void + attachstack(Client *c) + { +- c->snext = c->mon->stack; +- c->mon->stack = c; ++ c->snext = c->mon->cl->stack; ++ c->mon->cl->stack = c; + } + + void +@@ -478,8 +519,8 @@ cleanup(void) + view(&a); + selmon->lt[selmon->sellt] = &foo; + for (m = mons; m; m = m->next) +- while (m->stack) +- unmanage(m->stack, 0); ++ while (m->cl->stack) ++ unmanage(m->cl->stack, 0); + XUngrabKey(dpy, AnyKey, AnyModifier, root); + while (mons) + cleanupmon(mons); +@@ -565,7 +606,7 @@ configurenotify(XEvent *e) + drw_resize(drw, sw, bh); + updatebars(); + for (m = mons; m; m = m->next) { +- for (c = m->clients; c; c = c->next) ++ for (c = m->cl->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); +@@ -611,7 +652,7 @@ configurerequest(XEvent *e) + c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ + if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) + configure(c); +- if (ISVISIBLE(c)) ++ if (ISVISIBLE(c, m)) + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); + } else + configure(c); +@@ -631,10 +672,31 @@ configurerequest(XEvent *e) + Monitor * + createmon(void) + { +- Monitor *m; ++ Monitor *m, *tm; ++ int i; + ++ /* bail out if the number of monitors exceeds the number of tags */ ++ for (i=1, tm=mons; tm; i++, tm=tm->next); ++ if (i > LENGTH(tags)) { ++ fprintf(stderr, "dwm: failed to add monitor, number of tags exceeded\n"); ++ return NULL; ++ } ++ /* find the first tag that isn't in use */ ++ for (i=0; i < LENGTH(tags); i++) { ++ for (tm=mons; tm && !(tm->tagset[tm->seltags] & (1<<i)); tm=tm->next); ++ if (!tm) ++ break; ++ } ++ /* reassign all tags to monitors since there's currently no free tag for the ++ * new monitor */ ++ if (i >= LENGTH(tags)) ++ for (i=0, tm=mons; tm; tm=tm->next, i++) { ++ tm->seltags ^= 1; ++ tm->tagset[tm->seltags] = (1<<i) & TAGMASK; ++ } + m = ecalloc(1, sizeof(Monitor)); +- m->tagset[0] = m->tagset[1] = 1; ++ m->cl = cl; ++ m->tagset[0] = m->tagset[1] = (1<<i) & TAGMASK; + m->mfact = mfact; + m->nmaster = nmaster; + m->showbar = showbar; +@@ -660,7 +722,7 @@ detach(Client *c) + { + Client **tc; + +- for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); ++ for (tc = &c->mon->cl->clients; *tc && *tc != c; tc = &(*tc)->next); + *tc = c->next; + } + +@@ -669,11 +731,11 @@ detachstack(Client *c) + { + Client **tc, *t; + +- for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); ++ for (tc = &c->mon->cl->stack; *tc && *tc != c; tc = &(*tc)->snext); + *tc = c->snext; + + if (c == c->mon->sel) { +- for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); ++ for (t = c->mon->cl->stack; t && !ISVISIBLE(t, c->mon); t = t->snext); + c->mon->sel = t; + } + } +@@ -709,7 +771,7 @@ drawbar(Monitor *m) + drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); + } + +- for (c = m->clients; c; c = c->next) { ++ for (c = m->cl->clients; c; c = c->next) { + occ |= c->tags; + if (c->isurgent) + urg |= c->tags; +@@ -784,8 +846,8 @@ expose(XEvent *e) + void + focus(Client *c) + { +- if (!c || !ISVISIBLE(c)) +- for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); ++ if (!c || !ISVISIBLE(c, selmon)) ++ for (c = selmon->cl->stack; c && !ISVISIBLE(c, selmon); c = c->snext); + if (selmon->sel && selmon->sel != c) + unfocus(selmon->sel, 0); + if (c) { +@@ -838,16 +900,16 @@ focusstack(const Arg *arg) + if (!selmon->sel || selmon->sel->isfullscreen) + return; + if (arg->i > 0) { +- for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); ++ for (c = selmon->sel->next; c && !ISVISIBLE(c, selmon); c = c->next); + if (!c) +- for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); ++ for (c = selmon->cl->clients; c && !ISVISIBLE(c, selmon); c = c->next); + } else { +- for (i = selmon->clients; i != selmon->sel; i = i->next) +- if (ISVISIBLE(i)) ++ for (i = selmon->cl->clients; i != selmon->sel; i = i->next) ++ if (ISVISIBLE(i, selmon)) + c = i; + if (!c) + for (; i; i = i->next) +- if (ISVISIBLE(i)) ++ if (ISVISIBLE(i, selmon)) + c = i; + } + if (c) { +@@ -1107,12 +1169,12 @@ monocle(Monitor *m) + unsigned int n = 0; + Client *c; + +- for (c = m->clients; c; c = c->next) +- if (ISVISIBLE(c)) ++ for (c = m->cl->clients; c; c = c->next) ++ if (ISVISIBLE(c, m)) + n++; + if (n > 0) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); +- for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) ++ for (c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m)) + resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); + } + +@@ -1194,9 +1256,9 @@ movemouse(const Arg *arg) + } + + Client * +-nexttiled(Client *c) ++nexttiled(Client *c, Monitor *m) + { +- for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); ++ for (; c && (c->isfloating || !ISVISIBLE(c, m)); c = c->next); + return c; + } + +@@ -1360,8 +1422,8 @@ restack(Monitor *m) + if (m->lt[m->sellt]->arrange) { + wc.stack_mode = Below; + wc.sibling = m->barwin; +- for (c = m->stack; c; c = c->snext) +- if (!c->isfloating && ISVISIBLE(c)) { ++ for (c = m->cl->stack; c; c = c->snext) ++ if (!c->isfloating && ISVISIBLE(c, m)) { + XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); + wc.sibling = c->win; + } +@@ -1414,11 +1476,9 @@ sendmon(Client *c, Monitor *m) + if (c->mon == m) + return; + unfocus(c, 1); +- detach(c); + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ +- attach(c); + attachstack(c); + focus(NULL); + arrange(NULL); +@@ -1541,6 +1601,8 @@ setup(void) + screen = DefaultScreen(dpy); + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); ++ if(!(cl = (Clientlist *)calloc(1, sizeof(Clientlist)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Clientlist)); + root = RootWindow(dpy, screen); + drw = drw_create(dpy, screen, root, sw, sh); + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) +@@ -1616,7 +1678,7 @@ showhide(Client *c) + { + if (!c) + return; +- if (ISVISIBLE(c)) { ++ if (ISVISIBLE(c, c->mon)) { + /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); + if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) +@@ -1656,7 +1718,23 @@ spawn(const Arg *arg) + void + tag(const Arg *arg) + { ++ Monitor *m; ++ unsigned int newtags; + if (selmon->sel && arg->ui & TAGMASK) { ++ newtags = arg->ui & TAGMASK; ++ for (m = mons; m; m = m->next) ++ /* if tag is visible on another monitor, move client to the new monitor */ ++ if (m != selmon && m->tagset[m->seltags] & newtags) { ++ /* prevent moving client to all tags (MODKEY-Shift-0) when multiple monitors are connected */ ++ if(newtags & selmon->tagset[selmon->seltags]) ++ return; ++ selmon->sel->tags = newtags; ++ selmon->sel->mon = m; ++ arrange(m); ++ break; ++ } ++ /* workaround in case just one monitor is connected */ ++ + selmon->sel->tags = arg->ui & TAGMASK; + focus(NULL); + arrange(selmon); +@@ -1677,7 +1755,7 @@ tile(Monitor *m) + unsigned int i, n, h, mw, my, ty; + Client *c; + +- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); ++ for (n = 0, c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m), n++); + if (n == 0) + return; + +@@ -1685,7 +1763,7 @@ tile(Monitor *m) + mw = m->nmaster ? m->ww * m->mfact : 0; + else + mw = m->ww; +- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) ++ for (i = my = ty = 0, c = nexttiled(m->cl->clients, m); c; c = nexttiled(c->next, m), i++) + if (i < m->nmaster) { + h = (m->wh - my) / (MIN(n, m->nmaster) - i); + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); +@@ -1725,12 +1803,17 @@ togglefloating(const Arg *arg) + void + toggletag(const Arg *arg) + { ++ Monitor *m; + unsigned int newtags; + + if (!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if (newtags) { ++ /* prevent adding tags that are in use on other monitors */ ++ for (m = mons; m; m = m->next) ++ if (m != selmon && newtags & m->tagset[m->seltags]) ++ return; + selmon->sel->tags = newtags; + focus(NULL); + arrange(selmon); +@@ -1740,12 +1823,27 @@ toggletag(const Arg *arg) + void + toggleview(const Arg *arg) + { ++ Monitor *m; + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); + + if (newtagset) { ++ /* prevent displaying the same tags on multiple monitors */ ++ for(m = mons; m; m = m->next) ++ if(m != selmon && newtagset & m->tagset[m->seltags]) ++ return; + selmon->tagset[selmon->seltags] = newtagset; +- focus(NULL); ++ attachclients(selmon); + arrange(selmon); ++ focus(NULL); ++ ++ unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); ++ ++ if (newtagset) { ++ selmon->tagset[selmon->seltags] = newtagset; ++ attachclients(selmon); ++ arrange(selmon); ++ focus(NULL); ++ } + } + } + +@@ -1844,7 +1942,7 @@ updateclientlist() + + XDeleteProperty(dpy, root, netatom[NetClientList]); + for (m = mons; m; m = m->next) +- for (c = m->clients; c; c = c->next) ++ for (c = m->cl->clients; c; c = c->next) + XChangeProperty(dpy, root, netatom[NetClientList], + XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); +@@ -1874,8 +1972,10 @@ updategeom(void) + if (n <= nn) { /* new monitors available */ + for (i = 0; i < (nn - n); i++) { + for (m = mons; m && m->next; m = m->next); +- if (m) ++ if (m) { + m->next = createmon(); ++ attachclients(m->next); ++ } + else + mons = createmon(); + } +@@ -1895,16 +1995,13 @@ updategeom(void) + } else { /* less monitors available nn < n */ + for (i = nn; i < n; i++) { + for (m = mons; m && m->next; m = m->next); +- while ((c = m->clients)) { +- dirty = 1; +- m->clients = c->next; +- detachstack(c); +- c->mon = mons; +- attach(c); +- attachstack(c); +- } + if (m == selmon) + selmon = mons; ++ for (c = m->cl->clients; c; c = c->next) { ++ dirty = True; ++ if (c->mon == m) ++ c->mon = selmon; ++ } + cleanupmon(m); + } + } +@@ -2038,13 +2135,32 @@ updatewmhints(Client *c) + void + view(const Arg *arg) + { ++ Monitor *m; ++ unsigned int newtagset = selmon->tagset[selmon->seltags ^ 1]; + if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; ++ /* swap tags when trying to display a tag from another monitor */ ++ if (arg->ui & TAGMASK) ++ newtagset = arg->ui & TAGMASK; ++ for (m = mons; m; m = m->next) ++ if (m != selmon && newtagset & m->tagset[m->seltags]) { ++ /* prevent displaying all tags (MODKEY-0) when multiple monitors ++ * are connected */ ++ if (newtagset & selmon->tagset[selmon->seltags]) ++ return; ++ m->sel = selmon->sel; ++ m->seltags ^= 1; ++ m->tagset[m->seltags] = selmon->tagset[selmon->seltags]; ++ attachclients(m); ++ arrange(m); ++ break; ++ } + selmon->seltags ^= 1; /* toggle sel tagset */ + if (arg->ui & TAGMASK) + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; +- focus(NULL); ++ attachclients(selmon); + arrange(selmon); ++ focus(NULL); + } + + Client * +@@ -2054,7 +2170,7 @@ wintoclient(Window w) + Monitor *m; + + for (m = mons; m; m = m->next) +- for (c = m->clients; c; c = c->next) ++ for (c = m->cl->clients; c; c = c->next) + if (c->win == w) + return c; + return NULL; +@@ -2121,8 +2237,8 @@ zoom(const Arg *arg) + if (!selmon->lt[selmon->sellt]->arrange + || (selmon->sel && selmon->sel->isfloating)) + return; +- if (c == nexttiled(selmon->clients)) +- if (!c || !(c = nexttiled(c->next))) ++ if (c == nexttiled(selmon->cl->clients, selmon)) ++ if (!c || !(c = nexttiled(c->next, selmon))) + return; + pop(c); + } +-- +2.32.0 + diff --git a/dwm.suckless.org/patches/single_tagset/index.md b/dwm.suckless.org/patches/single_tagset/index.md @@ -18,6 +18,7 @@ Several deep changes needed to be made: Download -------- +* [dwm-single\_tagset-20210623-67d76bd.diff](dwm-single_tagset-20210623-67d76bd.diff) * [dwm-single\_tagset-6.2.diff](dwm-single_tagset-6.2.diff) * [dwm-single\_tagset-20160731-56a31dc.diff](dwm-single_tagset-20160731-56a31dc.diff) * [dwm-6.1-single\_tagset.diff](dwm-6.1-single_tagset.diff) (16634b) (20140209) @@ -27,3 +28,4 @@ Authors ------- * Jan Christoph Ebersbach - <jceb@e-jc.de> * Mohammad Zeinali - <mzeinali@tutanota.com> +* Jesus Mastache Caballero - <BrunoCooper17@outlook.com>