commit e4c4ad83cea06c23929678131863fb338eefa47f
Author: Timmy Keller <[email protected]>
Date:   Mon Mar 1 18:33:02 2021 -0600

    [dwm][patch] adds functionalgaps patch

diff --git 
a/dwm.suckless.org/patches/functionalgaps/dwm-functionalgaps+pertag-6.2.diff 
b/dwm.suckless.org/patches/functionalgaps/dwm-functionalgaps+pertag-6.2.diff
new file mode 100644
index 00000000..c7e1c60e
--- /dev/null
+++ b/dwm.suckless.org/patches/functionalgaps/dwm-functionalgaps+pertag-6.2.diff
@@ -0,0 +1,352 @@
+diff -pu dwm.git/config.def.h dwm.functionalgapspertag/config.def.h
+--- dwm.git/config.def.h       2021-02-27 21:17:53.862314811 -0600
++++ dwm.functionalgapspertag/config.def.h      2021-03-01 15:40:07.312696974 
-0600
+@@ -2,6 +2,8 @@
+ 
+ /* appearance */
+ static const unsigned int borderpx  = 1;        /* border pixel of windows */
++static const int startwithgaps[]    = { 0 };  /* 1 means gaps are used by 
default, this can be customized for each tag */
++static const unsigned int gappx[]   = { 10 };   /* default gap between 
windows in pixels, this can be customized for each tag */
+ 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 */
+@@ -84,6 +86,10 @@ static Key keys[] = {
+       { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
+       { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
+       { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
++      { MODKEY,                       XK_minus,  setgaps,        {.i = -5 } },
++      { MODKEY,                       XK_equal,  setgaps,        {.i = +5 } },
++      { MODKEY|ShiftMask,             XK_minus,  setgaps,        {.i = 
GAP_RESET } },
++      { MODKEY|ShiftMask,             XK_equal,  setgaps,        {.i = 
GAP_TOGGLE} },
+       TAGKEYS(                        XK_1,                      0)
+       TAGKEYS(                        XK_2,                      1)
+       TAGKEYS(                        XK_3,                      2)
+diff -pu dwm.git/dwm.c dwm.functionalgapspertag/dwm.c
+--- dwm.git/dwm.c      2021-02-27 21:17:53.862314811 -0600
++++ dwm.functionalgapspertag/dwm.c     2021-03-01 17:10:10.402964866 -0600
+@@ -57,6 +57,9 @@
+ #define TAGMASK                 ((1 << LENGTH(tags)) - 1)
+ #define TEXTW(X)                (drw_fontset_getwidth(drw, (X)) + lrpad)
+ 
++#define GAP_TOGGLE 100
++#define GAP_RESET  0
++
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+ enum { SchemeNorm, SchemeSel }; /* color schemes */
+@@ -111,6 +114,8 @@ typedef struct {
+       void (*arrange)(Monitor *);
+ } Layout;
+ 
++typedef struct Pertag Pertag;
++
+ struct Monitor {
+       char ltsymbol[16];
+       float mfact;
+@@ -130,6 +135,7 @@ struct Monitor {
+       Monitor *next;
+       Window barwin;
+       const Layout *lt[2];
++      Pertag *pertag;
+ };
+ 
+ typedef struct {
+@@ -200,6 +206,7 @@ static void sendmon(Client *c, Monitor *
+ static void setclientstate(Client *c, long state);
+ static void setfocus(Client *c);
+ static void setfullscreen(Client *c, int fullscreen);
++static void setgaps(const Arg *arg);
+ static void setlayout(const Arg *arg);
+ static void setmfact(const Arg *arg);
+ static void setup(void);
+@@ -272,6 +279,18 @@ static Window root, wmcheckwin;
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+ 
++struct Pertag {
++      unsigned int curtag, prevtag; /* current and previous tag */
++      int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
++      float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
++      unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
++      const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and 
layouts indexes  */
++      int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
++
++      int drawwithgaps[LENGTH(tags) + 1]; /* gaps toggle for each tag */
++      int gappx[LENGTH(tags) + 1]; /* gaps for each tag */
++};
++
+ /* compile-time check if all tags fit into an unsigned int bit array. */
+ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+ 
+@@ -632,6 +651,7 @@ Monitor *
+ createmon(void)
+ {
+       Monitor *m;
++      unsigned int i;
+ 
+       m = ecalloc(1, sizeof(Monitor));
+       m->tagset[0] = m->tagset[1] = 1;
+@@ -642,6 +662,26 @@ createmon(void)
+       m->lt[0] = &layouts[0];
+       m->lt[1] = &layouts[1 % LENGTH(layouts)];
+       strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
++      m->pertag = ecalloc(1, sizeof(Pertag));
++      m->pertag->curtag = m->pertag->prevtag = 1;
++
++      for (i = 0; i <= LENGTH(tags); i++) {
++              m->pertag->nmasters[i] = m->nmaster;
++              m->pertag->mfacts[i] = m->mfact;
++
++              m->pertag->ltidxs[i][0] = m->lt[0];
++              m->pertag->ltidxs[i][1] = m->lt[1];
++              m->pertag->sellts[i] = m->sellt;
++
++              m->pertag->showbars[i] = m->showbar;
++              if (i > 0) {
++                      m->pertag->drawwithgaps[i] = startwithgaps[(i - 1) % 
LENGTH(gappx)];
++                      m->pertag->gappx[i] = gappx[(i - 1) % LENGTH(gappx)];
++              }
++      }
++      m->pertag->drawwithgaps[0] = startwithgaps[0]; 
++      m->pertag->gappx[0] = gappx[0];
++
+       return m;
+ }
+ 
+@@ -797,6 +837,12 @@ focus(Client *c)
+               attachstack(c);
+               grabbuttons(c, 1);
+               XSetWindowBorder(dpy, c->win, 
scheme[SchemeSel][ColBorder].pixel);
++                if (!selmon->pertag->drawwithgaps[selmon->pertag->curtag] && 
!c->isfloating) {
++                      XWindowChanges wc;
++                        wc.sibling = selmon->barwin;
++                        wc.stack_mode = Below;
++                        XConfigureWindow(dpy, c->win, CWSibling | 
CWStackMode, &wc);
++                }
+               setfocus(c);
+       } else {
+               XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+@@ -967,7 +1013,7 @@ grabkeys(void)
+ void
+ incnmaster(const Arg *arg)
+ {
+-      selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
++      selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = 
MAX(selmon->nmaster + arg->i, 0);
+       arrange(selmon);
+ }
+ 
+@@ -1113,7 +1159,10 @@ monocle(Monitor *m)
+       if (n > 0) /* override layout symbol */
+               snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
+       for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
+-              resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 
0);
++              if (selmon->pertag->drawwithgaps[selmon->pertag->curtag])
++                      resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * 
c->bw, 0);
++              else
++                      resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False);
+ }
+ 
+ void
+@@ -1283,6 +1332,15 @@ resizeclient(Client *c, int x, int y, in
+       c->oldw = c->w; c->w = wc.width = w;
+       c->oldh = c->h; c->h = wc.height = h;
+       wc.border_width = c->bw;
++      if (!selmon->pertag->drawwithgaps[selmon->pertag->curtag] && /* this is 
the noborderfloatingfix patch, slightly modified so that it will work if, and 
only if, gaps are disabled. */
++          (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) /* these 
two first lines are the only ones changed. if you are manually patching and 
have noborder installed already, just change these lines; or conversely, just 
remove this section if the noborder patch is not desired;) */
++          || &monocle == c->mon->lt[c->mon->sellt]->arrange))
++          && !c->isfullscreen && !c->isfloating
++          && NULL != c->mon->lt[c->mon->sellt]->arrange) {
++              c->w = wc.width += c->bw * 2;
++              c->h = wc.height += c->bw * 2;
++              wc.border_width = 0;
++      }
+       XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, 
&wc);
+       configure(c);
+       XSync(dpy, False);
+@@ -1499,12 +1557,35 @@ setfullscreen(Client *c, int fullscreen)
+ }
+ 
+ void
++setgaps(const Arg *arg)
++{
++      switch(arg->i)
++      {
++              case GAP_TOGGLE:
++                      selmon->pertag->drawwithgaps[selmon->pertag->curtag] = 
!selmon->pertag->drawwithgaps[selmon->pertag->curtag];
++                      break;
++              case GAP_RESET:
++                      if (selmon->pertag->curtag > 0)
++                              selmon->pertag->gappx[selmon->pertag->curtag] = 
gappx[selmon->pertag->curtag - 1 % LENGTH(gappx)];
++                      else
++                              selmon->pertag->gappx[0] = gappx[0];
++                      break;
++              default:
++                      if (selmon->pertag->gappx[selmon->pertag->curtag] + 
arg->i < 0)
++                              selmon->pertag->gappx[selmon->pertag->curtag] = 
0;
++                      else
++                              selmon->pertag->gappx[selmon->pertag->curtag] 
+= arg->i;
++      }
++      arrange(selmon);
++}
++
++void
+ setlayout(const Arg *arg)
+ {
+       if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
+-              selmon->sellt ^= 1;
++              selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] 
^= 1;
+       if (arg && arg->v)
+-              selmon->lt[selmon->sellt] = (Layout *)arg->v;
++              selmon->lt[selmon->sellt] = 
selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout 
*)arg->v;
+       strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof 
selmon->ltsymbol);
+       if (selmon->sel)
+               arrange(selmon);
+@@ -1523,7 +1604,7 @@ setmfact(const Arg *arg)
+       f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
+       if (f < 0.05 || f > 0.95)
+               return;
+-      selmon->mfact = f;
++      selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
+       arrange(selmon);
+ }
+ 
+@@ -1680,29 +1761,48 @@ tile(Monitor *m)
+       for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+       if (n == 0)
+               return;
+-
+-      if (n > m->nmaster)
+-              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++)
+-              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);
+-                      if (my + HEIGHT(c) < m->wh)
+-                              my += HEIGHT(c);
+-              } else {
+-                      h = (m->wh - ty) / (n - i);
+-                      resize(c, m->wx + mw, m->wy + ty, m->ww - mw - 
(2*c->bw), h - (2*c->bw), 0);
+-                      if (ty + HEIGHT(c) < m->wh)
+-                              ty += HEIGHT(c);
+-              }
++      if (m->pertag->drawwithgaps[m->pertag->curtag]) { /* draw with fullgaps 
logic */
++              if (n > m->nmaster)
++                      mw = m->nmaster ? m->ww * m->mfact : 0;
++              else
++                      mw = m->ww - m->pertag->gappx[m->pertag->curtag];
++              for (i = 0, my = ty = m->pertag->gappx[m->pertag->curtag], c = 
nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++                      if (i < m->nmaster) {
++                              h = (m->wh - my) / (MIN(n, m->nmaster) - i) - 
m->pertag->gappx[m->pertag->curtag];
++                              resize(c, m->wx + 
m->pertag->gappx[m->pertag->curtag], m->wy + my, mw - (2*c->bw) - 
m->pertag->gappx[m->pertag->curtag], h - (2*c->bw), 0);
++                              if (my + HEIGHT(c) + 
m->pertag->gappx[m->pertag->curtag] < m->wh)
++                                      my += HEIGHT(c) + 
m->pertag->gappx[m->pertag->curtag];
++                      } else {
++                              h = (m->wh - ty) / (n - i) - 
m->pertag->gappx[m->pertag->curtag];
++                              resize(c, m->wx + mw + 
m->pertag->gappx[m->pertag->curtag], m->wy + ty, m->ww - mw - (2*c->bw) - 
2*m->pertag->gappx[m->pertag->curtag], h - (2*c->bw), 0);
++                              if (ty + HEIGHT(c) + 
m->pertag->gappx[m->pertag->curtag] < m->wh)
++                                      ty += HEIGHT(c) + 
m->pertag->gappx[m->pertag->curtag];
++                      }
++      } else { /* draw with singularborders logic */
++              if (n > m->nmaster)
++                      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++)
++                      if (i < m->nmaster) {
++                              h = (m->wh - my) / (MIN(n, m->nmaster) - i);
++                              if (n == 1)
++                                      resize(c, m->wx - c->bw, m->wy, m->ww, 
m->wh, False);
++                              else
++                                      resize(c, m->wx - c->bw, m->wy + my, mw 
- c->bw, h - c->bw, False);
++                              my += HEIGHT(c) - c->bw;
++                      } else {
++                              h = (m->wh - ty) / (n - i);
++                              resize(c, m->wx + mw - c->bw, m->wy + ty, m->ww 
- mw, h - c->bw, False);
++                              ty += HEIGHT(c) - c->bw;
++                      }
++      }
+ }
+ 
+ void
+ togglebar(const Arg *arg)
+ {
+-      selmon->showbar = !selmon->showbar;
++      selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = 
!selmon->showbar;
+       updatebarpos(selmon);
+       XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, 
selmon->ww, bh);
+       arrange(selmon);
+@@ -1741,9 +1841,33 @@ void
+ toggleview(const Arg *arg)
+ {
+       unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & 
TAGMASK);
++      int i;
+ 
+       if (newtagset) {
+               selmon->tagset[selmon->seltags] = newtagset;
++
++              if (newtagset == ~0) {
++                      selmon->pertag->prevtag = selmon->pertag->curtag;
++                      selmon->pertag->curtag = 0;
++              }
++
++              /* test if the user did not select the same tag */
++              if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
++                      selmon->pertag->prevtag = selmon->pertag->curtag;
++                      for (i = 0; !(newtagset & 1 << i); i++) ;
++                      selmon->pertag->curtag = i + 1;
++              }
++
++              /* apply settings for this view */
++              selmon->nmaster = 
selmon->pertag->nmasters[selmon->pertag->curtag];
++              selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
++              selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
++              selmon->lt[selmon->sellt] = 
selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
++              selmon->lt[selmon->sellt^1] = 
selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
++
++              if (selmon->showbar != 
selmon->pertag->showbars[selmon->pertag->curtag])
++                      togglebar(NULL);
++
+               focus(NULL);
+               arrange(selmon);
+       }
+@@ -2038,11 +2162,37 @@ updatewmhints(Client *c)
+ void
+ view(const Arg *arg)
+ {
++      int i;
++      unsigned int tmptag;
++
+       if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
+               return;
+       selmon->seltags ^= 1; /* toggle sel tagset */
+-      if (arg->ui & TAGMASK)
++      if (arg->ui & TAGMASK) {
+               selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
++              selmon->pertag->prevtag = selmon->pertag->curtag;
++
++              if (arg->ui == ~0)
++                      selmon->pertag->curtag = 0;
++              else {
++                      for (i = 0; !(arg->ui & 1 << i); i++) ;
++                      selmon->pertag->curtag = i + 1;
++              }
++      } else {
++              tmptag = selmon->pertag->prevtag;
++              selmon->pertag->prevtag = selmon->pertag->curtag;
++              selmon->pertag->curtag = tmptag;
++      }
++
++      selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
++      selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
++      selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
++      selmon->lt[selmon->sellt] = 
selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
++      selmon->lt[selmon->sellt^1] = 
selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
++
++      if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
++              togglebar(NULL);
++
+       focus(NULL);
+       arrange(selmon);
+ }
diff --git 
a/dwm.suckless.org/patches/functionalgaps/dwm-functionalgaps-6.2.diff 
b/dwm.suckless.org/patches/functionalgaps/dwm-functionalgaps-6.2.diff
new file mode 100644
index 00000000..08d03588
--- /dev/null
+++ b/dwm.suckless.org/patches/functionalgaps/dwm-functionalgaps-6.2.diff
@@ -0,0 +1,190 @@
+diff -pur dwm.git/config.def.h dwm.mygaps/config.def.h
+--- dwm.git/config.def.h       2021-02-27 21:17:53.862314811 -0600
++++ dwm.mygaps/config.def.h    2021-02-28 00:06:39.066149441 -0600
+@@ -2,6 +2,8 @@
+ 
+ /* appearance */
+ static const unsigned int borderpx  = 1;        /* border pixel of windows */
++static const int startwithgaps             = 0;        /* 1 means gaps are 
used by default */
++static const unsigned int gappx     = 10;       /* default gap between 
windows in pixels */
+ 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 */
+@@ -84,6 +86,10 @@ static Key keys[] = {
+       { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
+       { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
+       { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
++      { MODKEY,                       XK_minus,  setgaps,        {.i = -5 } },
++      { MODKEY,                       XK_equal,  setgaps,        {.i = +5 } },
++      { MODKEY|ShiftMask,             XK_minus,  setgaps,        {.i = 
GAP_RESET } },
++      { MODKEY|ShiftMask,             XK_equal,  setgaps,        {.i = 
GAP_TOGGLE} },
+       TAGKEYS(                        XK_1,                      0)
+       TAGKEYS(                        XK_2,                      1)
+       TAGKEYS(                        XK_3,                      2)
+diff -pur dwm.git/dwm.c dwm.mygaps/dwm.c
+--- dwm.git/dwm.c      2021-02-27 21:17:53.862314811 -0600
++++ dwm.mygaps/dwm.c   2021-02-28 00:23:19.232865766 -0600
+@@ -57,6 +57,9 @@
+ #define TAGMASK                 ((1 << LENGTH(tags)) - 1)
+ #define TEXTW(X)                (drw_fontset_getwidth(drw, (X)) + lrpad)
+ 
++#define GAP_TOGGLE 100
++#define GAP_RESET  0
++
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+ enum { SchemeNorm, SchemeSel }; /* color schemes */
+@@ -119,6 +122,8 @@ struct Monitor {
+       int by;               /* bar geometry */
+       int mx, my, mw, mh;   /* screen size */
+       int wx, wy, ww, wh;   /* window area  */
++      int gappx;            /* gaps between windows */
++      int drawwithgaps;     /* toggle gaps */
+       unsigned int seltags;
+       unsigned int sellt;
+       unsigned int tagset[2];
+@@ -200,6 +205,7 @@ static void sendmon(Client *c, Monitor *
+ static void setclientstate(Client *c, long state);
+ static void setfocus(Client *c);
+ static void setfullscreen(Client *c, int fullscreen);
++static void setgaps(const Arg *arg);
+ static void setlayout(const Arg *arg);
+ static void setmfact(const Arg *arg);
+ static void setup(void);
+@@ -639,6 +645,8 @@ createmon(void)
+       m->nmaster = nmaster;
+       m->showbar = showbar;
+       m->topbar = topbar;
++      m->gappx = gappx;
++      m->drawwithgaps = startwithgaps;
+       m->lt[0] = &layouts[0];
+       m->lt[1] = &layouts[1 % LENGTH(layouts)];
+       strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+@@ -797,6 +805,12 @@ focus(Client *c)
+               attachstack(c);
+               grabbuttons(c, 1);
+               XSetWindowBorder(dpy, c->win, 
scheme[SchemeSel][ColBorder].pixel);
++                if (!selmon->drawwithgaps && !c->isfloating) {
++                      XWindowChanges wc;
++                        wc.sibling = selmon->barwin;
++                        wc.stack_mode = Below;
++                        XConfigureWindow(dpy, c->win, CWSibling | 
CWStackMode, &wc);
++                }
+               setfocus(c);
+       } else {
+               XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+@@ -1113,7 +1127,10 @@ monocle(Monitor *m)
+       if (n > 0) /* override layout symbol */
+               snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
+       for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
+-              resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 
0);
++              if (selmon->drawwithgaps)
++                      resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * 
c->bw, 0);
++              else
++                      resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False);
+ }
+ 
+ void
+@@ -1283,6 +1300,15 @@ resizeclient(Client *c, int x, int y, in
+       c->oldw = c->w; c->w = wc.width = w;
+       c->oldh = c->h; c->h = wc.height = h;
+       wc.border_width = c->bw;
++      if (!selmon->drawwithgaps && /* this is the noborderfloatingfix patch, 
slightly modified so that it will work if, and only if, gaps are disabled. */
++          (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) /* these 
two first lines are the only ones changed. if you are manually patching and 
have noborder installed already, just change these lines; or conversely, just 
remove this section if the noborder patch is not desired ;) */
++          || &monocle == c->mon->lt[c->mon->sellt]->arrange))
++          && !c->isfullscreen && !c->isfloating
++          && NULL != c->mon->lt[c->mon->sellt]->arrange) {
++              c->w = wc.width += c->bw * 2;
++              c->h = wc.height += c->bw * 2;
++              wc.border_width = 0;
++      }
+       XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, 
&wc);
+       configure(c);
+       XSync(dpy, False);
+@@ -1499,6 +1525,26 @@ setfullscreen(Client *c, int fullscreen)
+ }
+ 
+ void
++setgaps(const Arg *arg)
++{
++      switch(arg->i)
++      {
++              case GAP_TOGGLE:
++                      selmon->drawwithgaps = !selmon->drawwithgaps;
++                      break;
++              case GAP_RESET:
++                      selmon->gappx = gappx;
++                      break;
++              default:
++                      if (selmon->gappx + arg->i < 0)
++                              selmon->gappx = 0;
++                      else
++                              selmon->gappx += arg->i;
++      }
++      arrange(selmon);
++}
++
++void
+ setlayout(const Arg *arg)
+ {
+       if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
+@@ -1680,23 +1726,42 @@ tile(Monitor *m)
+       for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+       if (n == 0)
+               return;
+-
+-      if (n > m->nmaster)
+-              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++)
+-              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);
+-                      if (my + HEIGHT(c) < m->wh)
+-                              my += HEIGHT(c);
+-              } else {
+-                      h = (m->wh - ty) / (n - i);
+-                      resize(c, m->wx + mw, m->wy + ty, m->ww - mw - 
(2*c->bw), h - (2*c->bw), 0);
+-                      if (ty + HEIGHT(c) < m->wh)
+-                              ty += HEIGHT(c);
+-              }
++        if (m->drawwithgaps) { /* draw with fullgaps logic */
++                if (n > m->nmaster)
++                        mw = m->nmaster ? m->ww * m->mfact : 0;
++                else
++                        mw = m->ww - m->gappx;
++                for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; 
c = nexttiled(c->next), i++)
++                        if (i < m->nmaster) {
++                                h = (m->wh - my) / (MIN(n, m->nmaster) - i) - 
m->gappx;
++                                resize(c, m->wx + m->gappx, m->wy + my, mw - 
(2*c->bw) - m->gappx, h - (2*c->bw), 0);
++                                if (my + HEIGHT(c) + m->gappx < m->wh)
++                                        my += HEIGHT(c) + m->gappx;
++                        } else {
++                                h = (m->wh - ty) / (n - i) - m->gappx;
++                                resize(c, m->wx + mw + m->gappx, m->wy + ty, 
m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0);
++                                if (ty + HEIGHT(c) + m->gappx < m->wh)
++                                        ty += HEIGHT(c) + m->gappx;
++                        }
++        } else { /* draw with singularborders logic */
++                if (n > m->nmaster)
++                        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++)
++                        if (i < m->nmaster) {
++                                h = (m->wh - my) / (MIN(n, m->nmaster) - i);
++                                if (n == 1)
++                                        resize(c, m->wx - c->bw, m->wy, 
m->ww, m->wh, False);
++                                else
++                                        resize(c, m->wx - c->bw, m->wy + my, 
mw - c->bw, h - c->bw, False);
++                                my += HEIGHT(c) - c->bw;
++                        } else {
++                                h = (m->wh - ty) / (n - i);
++                                resize(c, m->wx + mw - c->bw, m->wy + ty, 
m->ww - mw, h - c->bw, False);
++                                ty += HEIGHT(c) - c->bw;
++                        }
++        }
+ }
+ 
+ void
diff --git 
a/dwm.suckless.org/patches/functionalgaps/dwm-functionalgaps-pertagfunctionality-6.2.diff
 
b/dwm.suckless.org/patches/functionalgaps/dwm-functionalgaps-pertagfunctionality-6.2.diff
new file mode 100644
index 00000000..7d1fabe6
--- /dev/null
+++ 
b/dwm.suckless.org/patches/functionalgaps/dwm-functionalgaps-pertagfunctionality-6.2.diff
@@ -0,0 +1,207 @@
+diff -pu dwm.withpertag/config.def.h dwm.functionalgapspertag/config.def.h
+--- dwm.withpertag/config.def.h        2021-02-27 23:47:22.426092186 -0600
++++ dwm.functionalgapspertag/config.def.h      2021-03-01 15:40:07.312696974 
-0600
+@@ -2,6 +2,8 @@
+ 
+ /* appearance */
+ static const unsigned int borderpx  = 1;        /* border pixel of windows */
++static const int startwithgaps[]    = { 0 };  /* 1 means gaps are used by 
default, this can be customized for each tag */
++static const unsigned int gappx[]   = { 10 };   /* default gap between 
windows in pixels, this can be customized for each tag */
+ 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 */
+@@ -84,6 +86,10 @@ static Key keys[] = {
+       { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
+       { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
+       { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
++      { MODKEY,                       XK_minus,  setgaps,        {.i = -5 } },
++      { MODKEY,                       XK_equal,  setgaps,        {.i = +5 } },
++      { MODKEY|ShiftMask,             XK_minus,  setgaps,        {.i = 
GAP_RESET } },
++      { MODKEY|ShiftMask,             XK_equal,  setgaps,        {.i = 
GAP_TOGGLE} },
+       TAGKEYS(                        XK_1,                      0)
+       TAGKEYS(                        XK_2,                      1)
+       TAGKEYS(                        XK_3,                      2)
+diff -pu dwm.withpertag/dwm.c dwm.functionalgapspertag/dwm.c
+--- dwm.withpertag/dwm.c       2021-02-27 23:47:41.352759785 -0600
++++ dwm.functionalgapspertag/dwm.c     2021-03-01 17:10:10.402964866 -0600
+@@ -57,6 +57,9 @@
+ #define TAGMASK                 ((1 << LENGTH(tags)) - 1)
+ #define TEXTW(X)                (drw_fontset_getwidth(drw, (X)) + lrpad)
+ 
++#define GAP_TOGGLE 100
++#define GAP_RESET  0
++
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+ enum { SchemeNorm, SchemeSel }; /* color schemes */
+@@ -112,6 +115,7 @@ typedef struct {
+ } Layout;
+ 
+ typedef struct Pertag Pertag;
++
+ struct Monitor {
+       char ltsymbol[16];
+       float mfact;
+@@ -202,6 +206,7 @@ static void sendmon(Client *c, Monitor *
+ static void setclientstate(Client *c, long state);
+ static void setfocus(Client *c);
+ static void setfullscreen(Client *c, int fullscreen);
++static void setgaps(const Arg *arg);
+ static void setlayout(const Arg *arg);
+ static void setmfact(const Arg *arg);
+ static void setup(void);
+@@ -281,6 +286,9 @@ struct Pertag {
+       unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
+       const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and 
layouts indexes  */
+       int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
++
++      int drawwithgaps[LENGTH(tags) + 1]; /* gaps toggle for each tag */
++      int gappx[LENGTH(tags) + 1]; /* gaps for each tag */
+ };
+ 
+ /* compile-time check if all tags fit into an unsigned int bit array. */
+@@ -666,7 +674,13 @@ createmon(void)
+               m->pertag->sellts[i] = m->sellt;
+ 
+               m->pertag->showbars[i] = m->showbar;
++              if (i > 0) {
++                      m->pertag->drawwithgaps[i] = startwithgaps[(i - 1) % 
LENGTH(gappx)];
++                      m->pertag->gappx[i] = gappx[(i - 1) % LENGTH(gappx)];
++              }
+       }
++      m->pertag->drawwithgaps[0] = startwithgaps[0]; 
++      m->pertag->gappx[0] = gappx[0];
+ 
+       return m;
+ }
+@@ -823,6 +837,12 @@ focus(Client *c)
+               attachstack(c);
+               grabbuttons(c, 1);
+               XSetWindowBorder(dpy, c->win, 
scheme[SchemeSel][ColBorder].pixel);
++                if (!selmon->pertag->drawwithgaps[selmon->pertag->curtag] && 
!c->isfloating) {
++                      XWindowChanges wc;
++                        wc.sibling = selmon->barwin;
++                        wc.stack_mode = Below;
++                        XConfigureWindow(dpy, c->win, CWSibling | 
CWStackMode, &wc);
++                }
+               setfocus(c);
+       } else {
+               XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+@@ -1139,7 +1159,10 @@ monocle(Monitor *m)
+       if (n > 0) /* override layout symbol */
+               snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
+       for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
+-              resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 
0);
++              if (selmon->pertag->drawwithgaps[selmon->pertag->curtag])
++                      resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * 
c->bw, 0);
++              else
++                      resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False);
+ }
+ 
+ void
+@@ -1309,6 +1332,15 @@ resizeclient(Client *c, int x, int y, in
+       c->oldw = c->w; c->w = wc.width = w;
+       c->oldh = c->h; c->h = wc.height = h;
+       wc.border_width = c->bw;
++      if (!selmon->pertag->drawwithgaps[selmon->pertag->curtag] && /* this is 
the noborderfloatingfix patch, slightly modified so that it will work if, and 
only if, gaps are disabled. */
++          (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) /* these 
two first lines are the only ones changed. if you are manually patching and 
have noborder installed already, just change these lines; or conversely, just 
remove this section if the noborder patch is not desired;) */
++          || &monocle == c->mon->lt[c->mon->sellt]->arrange))
++          && !c->isfullscreen && !c->isfloating
++          && NULL != c->mon->lt[c->mon->sellt]->arrange) {
++              c->w = wc.width += c->bw * 2;
++              c->h = wc.height += c->bw * 2;
++              wc.border_width = 0;
++      }
+       XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, 
&wc);
+       configure(c);
+       XSync(dpy, False);
+@@ -1525,6 +1557,29 @@ setfullscreen(Client *c, int fullscreen)
+ }
+ 
+ void
++setgaps(const Arg *arg)
++{
++      switch(arg->i)
++      {
++              case GAP_TOGGLE:
++                      selmon->pertag->drawwithgaps[selmon->pertag->curtag] = 
!selmon->pertag->drawwithgaps[selmon->pertag->curtag];
++                      break;
++              case GAP_RESET:
++                      if (selmon->pertag->curtag > 0)
++                              selmon->pertag->gappx[selmon->pertag->curtag] = 
gappx[selmon->pertag->curtag - 1 % LENGTH(gappx)];
++                      else
++                              selmon->pertag->gappx[0] = gappx[0];
++                      break;
++              default:
++                      if (selmon->pertag->gappx[selmon->pertag->curtag] + 
arg->i < 0)
++                              selmon->pertag->gappx[selmon->pertag->curtag] = 
0;
++                      else
++                              selmon->pertag->gappx[selmon->pertag->curtag] 
+= arg->i;
++      }
++      arrange(selmon);
++}
++
++void
+ setlayout(const Arg *arg)
+ {
+       if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
+@@ -1706,23 +1761,42 @@ tile(Monitor *m)
+       for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+       if (n == 0)
+               return;
+-
+-      if (n > m->nmaster)
+-              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++)
+-              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);
+-                      if (my + HEIGHT(c) < m->wh)
+-                              my += HEIGHT(c);
+-              } else {
+-                      h = (m->wh - ty) / (n - i);
+-                      resize(c, m->wx + mw, m->wy + ty, m->ww - mw - 
(2*c->bw), h - (2*c->bw), 0);
+-                      if (ty + HEIGHT(c) < m->wh)
+-                              ty += HEIGHT(c);
+-              }
++      if (m->pertag->drawwithgaps[m->pertag->curtag]) { /* draw with fullgaps 
logic */
++              if (n > m->nmaster)
++                      mw = m->nmaster ? m->ww * m->mfact : 0;
++              else
++                      mw = m->ww - m->pertag->gappx[m->pertag->curtag];
++              for (i = 0, my = ty = m->pertag->gappx[m->pertag->curtag], c = 
nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++                      if (i < m->nmaster) {
++                              h = (m->wh - my) / (MIN(n, m->nmaster) - i) - 
m->pertag->gappx[m->pertag->curtag];
++                              resize(c, m->wx + 
m->pertag->gappx[m->pertag->curtag], m->wy + my, mw - (2*c->bw) - 
m->pertag->gappx[m->pertag->curtag], h - (2*c->bw), 0);
++                              if (my + HEIGHT(c) + 
m->pertag->gappx[m->pertag->curtag] < m->wh)
++                                      my += HEIGHT(c) + 
m->pertag->gappx[m->pertag->curtag];
++                      } else {
++                              h = (m->wh - ty) / (n - i) - 
m->pertag->gappx[m->pertag->curtag];
++                              resize(c, m->wx + mw + 
m->pertag->gappx[m->pertag->curtag], m->wy + ty, m->ww - mw - (2*c->bw) - 
2*m->pertag->gappx[m->pertag->curtag], h - (2*c->bw), 0);
++                              if (ty + HEIGHT(c) + 
m->pertag->gappx[m->pertag->curtag] < m->wh)
++                                      ty += HEIGHT(c) + 
m->pertag->gappx[m->pertag->curtag];
++                      }
++      } else { /* draw with singularborders logic */
++              if (n > m->nmaster)
++                      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++)
++                      if (i < m->nmaster) {
++                              h = (m->wh - my) / (MIN(n, m->nmaster) - i);
++                              if (n == 1)
++                                      resize(c, m->wx - c->bw, m->wy, m->ww, 
m->wh, False);
++                              else
++                                      resize(c, m->wx - c->bw, m->wy + my, mw 
- c->bw, h - c->bw, False);
++                              my += HEIGHT(c) - c->bw;
++                      } else {
++                              h = (m->wh - ty) / (n - i);
++                              resize(c, m->wx + mw - c->bw, m->wy + ty, m->ww 
- mw, h - c->bw, False);
++                              ty += HEIGHT(c) - c->bw;
++                      }
++      }
+ }
+ 
+ void
diff --git a/dwm.suckless.org/patches/functionalgaps/index.md 
b/dwm.suckless.org/patches/functionalgaps/index.md
new file mode 100644
index 00000000..d718c52a
--- /dev/null
+++ b/dwm.suckless.org/patches/functionalgaps/index.md
@@ -0,0 +1,26 @@
+functionalgaps
+==========
+
+Description
+-----------
+Functionalgaps combines the beautifully simplistic gaps of 
[fullgaps](../fullgaps) with the non-gaps of 
[singularborders](../singularborders) and [noborder](../noborder). It is named 
functionalgaps because, since gaps are purely aesthetic, and therefore not 
useful whatsoever, this patch adds to their functionality by allowing them to 
easily be turned *off*.
+
+It is also notable because of its out of the box integration with 
[pertag](../pertag), allowing gaps to be enabled/disabled and sized on a 
per-tag basis.
+
+Gaps can be toggled with `[Alt]+[Shift]+[=]`, resized using `[Alt]+[+]` / 
`[Alt]+[-]`, and reset using `[Alt]+[Shift]+[-]` just like 
[fullgaps](../fullgaps).
+
+The config variables `startwithgaps` and `gappx` are avaliable to change basic 
behavior.
+The versions supporting pertag also have a feature to set these variables for 
individual tags.
+* Example: setting 'startwithgaps[] = { 1, 0 }' will cause tag 1 to start with 
gaps, and tag 2 to start without; this behavior will then loop for the rest of 
the unset tags (3 has gaps, 4 doesn't; 5 has gaps, 6 doesn't; etc.). You can 
also, of course, set a value for each tag individually.
+
+The modified noborder patch can also be easily removed, if not desired, by 
deleting or commenting out the 'if' statement added to the `resizeclient` c 
function. It is included for purely asthetic reasons since singularborders 
looks bad when a single window is open in tiled mode. The included version of 
the patch is modified to only activate when in singularborders mode.
+
+Download
+--------
+* [dwm-functionalgaps-6.2.diff](dwm-functionalgaps-6.2.diff) (comes WITHOUT 
pertag support)
+* 
[dwm-functionalgaps-pertagfunctionality-6.2.diff](dwm-functionalgaps-pertagfunctionality-6.2.diff)
 (comes WITH pertag support but WITHOUT the pertag patch)
+* [dwm-functionalgaps+pertag-6.2.diff](dwm-functionalgaps+pertag-6.2.diff) 
(comes WITH pertag support + the pertag patch itself)
+
+Author
+------
+* Timmy Keller <[email protected]>


Reply via email to