commit dd04b20cb659aac335df91342af87c380ecd0493
Author: mzeinali <[email protected]>
Date:   Wed Oct 14 11:05:31 2020 +0330

    A new update for single_tagset which is compatible with dwm 6.2.

diff --git a/dwm.suckless.org/patches/single_tagset/dwm-single_tagset-6.2.diff 
b/dwm.suckless.org/patches/single_tagset/dwm-single_tagset-6.2.diff
new file mode 100644
index 00000000..533bff81
--- /dev/null
+++ b/dwm.suckless.org/patches/single_tagset/dwm-single_tagset-6.2.diff
@@ -0,0 +1,536 @@
+Author: Mohammad Zeinali <[email protected]>
+URL: http://dwm.suckless.org/patches/single_tagset
+A new update for single_tagset which is compatible with dwm 6.2.
+
+diff --git a/dwm.c b/dwm.c
+index 4465af1..179328e 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);
+@@ -183,7 +189,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);
+@@ -267,6 +273,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"
+@@ -299,7 +306,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;
+               }
+@@ -381,9 +388,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);
+@@ -402,15 +409,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
+@@ -477,8 +518,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);
+@@ -564,7 +605,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);
+@@ -610,7 +651,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);
+@@ -630,10 +671,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
");
++              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;
+@@ -659,7 +721,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;
+ }
+ 
+@@ -668,11 +730,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;
+       }
+ }
+@@ -708,7 +770,7 @@ drawbar(Monitor *m)
+               drw_text(drw, m->ww - sw, 0, sw, 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;
+@@ -783,8 +845,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) {
+@@ -837,16 +899,16 @@ focusstack(const Arg *arg)
+       if (!selmon->sel)
+               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) {
+@@ -1106,12 +1168,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);
+ }
+ 
+@@ -1193,9 +1255,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;
+ }
+ 
+@@ -1359,8 +1421,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;
+                       }
+@@ -1413,11 +1475,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);
+@@ -1540,6 +1600,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
", sizeof(Clientlist));
+       root = RootWindow(dpy, screen);
+       drw = drw_create(dpy, screen, root, sw, sh);
+       if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
+@@ -1615,7 +1677,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)
+@@ -1655,7 +1717,23 @@ spawn(const Arg *arg)
+ void
+ tag(const Arg *arg)
+ {
+-      if (selmon->sel && arg->ui & TAGMASK) {
++      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);
+@@ -1676,7 +1754,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;
+ 
+@@ -1684,7 +1762,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);
+@@ -1722,12 +1800,17 @@ togglefloating(const Arg *arg)
+ void
+ toggletag(const Arg *arg)
+ {
+-      unsigned int newtags;
+-
+-      if (!selmon->sel)
+-              return;
+-      newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
+-      if (newtags) {
++      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);
+@@ -1737,6 +1820,18 @@ 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);
++
+       unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & 
TAGMASK);
+ 
+       if (newtagset) {
+@@ -1744,6 +1839,7 @@ toggleview(const Arg *arg)
+               focus(NULL);
+               arrange(selmon);
+       }
++      }
+ }
+ 
+ void
+@@ -1841,7 +1937,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);
+@@ -1871,8 +1967,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();
+                       }
+@@ -1892,16 +1990,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);
+                       }
+               }
+@@ -2035,13 +2130,31 @@ updatewmhints(Client *c)
+ void
+ view(const Arg *arg)
+ {
+-      if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
+-              return;
++      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);
+-      arrange(selmon);
++      attachclients(selmon);
+ }
+ 
+ Client *
+@@ -2051,7 +2164,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;
+@@ -2118,8 +2231,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);
+ }
diff --git a/dwm.suckless.org/patches/single_tagset/index.md 
b/dwm.suckless.org/patches/single_tagset/index.md
index 3f5b5e40..496ecacb 100644
--- 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-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)
 * [dwm-single\_tagset-6.0.diff](dwm-single_tagset-6.0.diff) (14417b) (20120406)
@@ -25,3 +26,4 @@ Download
 Authors
 -------
 * Jan Christoph Ebersbach - <[email protected]>
+* Mohammad Zeinali - <[email protected]>


Reply via email to