sites

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

commit e4c4ad83cea06c23929678131863fb338eefa47f
parent a6a1f1bd92b164b5536da13c6817c8885bda9ab7
Author: Timmy Keller <applesrcol8796@gmail.com>
Date:   Mon,  1 Mar 2021 18:33:02 -0600

[dwm][patch] adds functionalgaps patch

Diffstat:
Adwm.suckless.org/patches/functionalgaps/dwm-functionalgaps+pertag-6.2.diff | 352+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/functionalgaps/dwm-functionalgaps-6.2.diff | 190+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/functionalgaps/dwm-functionalgaps-pertagfunctionality-6.2.diff | 207+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/functionalgaps/index.md | 26++++++++++++++++++++++++++
4 files changed, 775 insertions(+), 0 deletions(-)

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 @@ -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 @@ -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 @@ -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 @@ -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 <applesrcol8796@gmail.com>