commit b8c2194ffef04b022808421c304331060a352810
Author: mzeinali <[email protected]>
Date:   Fri Sep 27 02:13:49 2024 +0330

    Add dwm-single_tagset-6.5.diff file

diff --git a/dwm.suckless.org/patches/single_tagset/dwm-single_tagset-6.5.diff 
b/dwm.suckless.org/patches/single_tagset/dwm-single_tagset-6.5.diff
new file mode 100644
index 00000000..bfe48d5c
--- /dev/null
+++ b/dwm.suckless.org/patches/single_tagset/dwm-single_tagset-6.5.diff
@@ -0,0 +1,537 @@
+From ccc8c267279865f357625bb0e8a89f722bfd647a Mon Sep 17 00:00:00 2001
+From: Mohammad Zeinali <[email protected]>
+Date: Thu, 26 Sep 2024 15:37:28 +0330
+Subject: [PATCH] single tagset for dwm 6.5
+
+---
+ dwm.c | 225 ++++++++++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 171 insertions(+), 54 deletions(-)
+
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..1079c5a 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 *c);
+ 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;
+               }
+@@ -383,9 +390,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);
+@@ -404,15 +411,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
+@@ -479,8 +520,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);
+@@ -567,7 +608,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);
+@@ -613,7 +654,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);
+@@ -633,10 +674,32 @@ 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;
+@@ -662,7 +725,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;
+ }
+ 
+@@ -671,11 +734,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;
+       }
+ }
+@@ -714,7 +777,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;
+@@ -789,8 +852,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) {
+@@ -843,16 +906,16 @@ focusstack(const Arg *arg)
+       if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
+               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) {
+@@ -1116,12 +1179,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);
+ }
+ 
+@@ -1203,9 +1266,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;
+ }
+ 
+@@ -1369,8 +1432,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;
+                       }
+@@ -1423,11 +1486,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);
+@@ -1557,6 +1618,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)))
+@@ -1631,7 +1694,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)
+@@ -1669,7 +1732,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);
+@@ -1690,7 +1769,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;
+ 
+@@ -1698,7 +1777,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);
+@@ -1738,12 +1817,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);
+@@ -1753,12 +1837,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);
++              }
+       }
+ }
+ 
+@@ -1858,7 +1957,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);
+@@ -1889,8 +1988,10 @@ updategeom(void)
+               /* new monitors if nn > n */
+               for (i = n; i < nn; i++) {
+                       for (m = mons; m && m->next; m = m->next);
+-                      if (m)
++                      if (m) {
+                               m->next = createmon();
++                              attachclients(m->next);
++                      }
+                       else
+                               mons = createmon();
+               }
+@@ -1910,16 +2011,13 @@ updategeom(void)
+               /* removed monitors if n > nn */
+               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);
+               }
+               free(unique);
+@@ -2053,13 +2151,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 *
+@@ -2069,7 +2186,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;
+@@ -2135,7 +2252,7 @@ zoom(const Arg *arg)
+ 
+       if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating)
+               return;
+-      if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next)))
++      if (c == nexttiled(selmon->cl->clients, selmon) && !(c = 
nexttiled(c->next, selmon)))
+               return;
+       pop(c);
+ }
+-- 
+2.46.2
+
diff --git a/dwm.suckless.org/patches/single_tagset/index.md 
b/dwm.suckless.org/patches/single_tagset/index.md
index 2528e65f..e555c88f 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.5.diff](dwm-single_tagset-6.5.diff)
 * 
[dwm-single\_tagset-20211015-a786211.diff](dwm-single_tagset-20211015-a786211.diff)
 * 
[dwm-single\_tagset-20210623-67d76bd.diff](dwm-single_tagset-20210623-67d76bd.diff)
 * [dwm-single\_tagset-6.2.diff](dwm-single_tagset-6.2.diff)


Reply via email to