summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2021-01-21 10:06:32 -0500
committerJon Santmyer <jon@jonsantmyer.com>2021-01-21 10:06:32 -0500
commit1eaf45a58b9bfd0c19bd16250932b7a536ac5ebe (patch)
tree596f776f47cb87d8bab7cdaf061016b89247c781
parent61bb8b2241d4db08bea4261c82e27cd9797099e7 (diff)
downloaddwm-1eaf45a58b9bfd0c19bd16250932b7a536ac5ebe.tar.gz
dwm-1eaf45a58b9bfd0c19bd16250932b7a536ac5ebe.tar.bz2
dwm-1eaf45a58b9bfd0c19bd16250932b7a536ac5ebe.zip
add desired patches to patches dir
patch vanitygaps into dwm
-rw-r--r--Makefile2
-rw-r--r--config.def.h38
-rw-r--r--dwm.c37
-rw-r--r--patches/actualfullscreen.diff53
-rw-r--r--patches/alwaysfullscreen.diff13
-rw-r--r--patches/autostart.diff179
-rw-r--r--patches/vanitygaps.diff971
-rw-r--r--vanitygaps.c809
8 files changed, 2071 insertions, 31 deletions
diff --git a/Makefile b/Makefile
index 77bcbc0..c05dbdd 100644
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,7 @@ dwm: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}
clean:
- rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
+ rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz config.h
dist: clean
mkdir -p dwm-${VERSION}
diff --git a/config.def.h b/config.def.h
index 1c0b587..a886863 100644
--- a/config.def.h
+++ b/config.def.h
@@ -3,6 +3,11 @@
/* appearance */
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
+static const unsigned int gappih = 20; /* horiz inner gap between windows */
+static const unsigned int gappiv = 10; /* vert inner gap between windows */
+static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */
+static const unsigned int gappov = 30; /* vert outer gap between windows and screen edge */
+static int smartgaps = 0; /* 1 means no outer gap when there is only one window */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
static const char *fonts[] = { "monospace:size=10" };
@@ -36,11 +41,26 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95]
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
+#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */
+#include "vanitygaps.c"
+
static const Layout layouts[] = {
/* symbol arrange function */
{ "[]=", tile }, /* first entry is default */
- { "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { "[@]", spiral },
+ { "[\\]", dwindle },
+ { "H[]", deck },
+ { "TTT", bstack },
+ { "===", bstackhoriz },
+ { "HHH", grid },
+ { "###", nrowgrid },
+ { "---", horizgrid },
+ { ":::", gaplessgrid },
+ { "|M|", centeredmaster },
+ { ">M>", centeredfloatingmaster },
+ { "><>", NULL }, /* no layout function means floating behavior */
+ { NULL, NULL },
};
/* key definitions */
@@ -71,6 +91,22 @@ static Key keys[] = {
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY, XK_Return, zoom, {0} },
+ { MODKEY|Mod4Mask, XK_u, incrgaps, {.i = +1 } },
+ { MODKEY|Mod4Mask|ShiftMask, XK_u, incrgaps, {.i = -1 } },
+ { MODKEY|Mod4Mask, XK_i, incrigaps, {.i = +1 } },
+ { MODKEY|Mod4Mask|ShiftMask, XK_i, incrigaps, {.i = -1 } },
+ { MODKEY|Mod4Mask, XK_o, incrogaps, {.i = +1 } },
+ { MODKEY|Mod4Mask|ShiftMask, XK_o, incrogaps, {.i = -1 } },
+ { MODKEY|Mod4Mask, XK_6, incrihgaps, {.i = +1 } },
+ { MODKEY|Mod4Mask|ShiftMask, XK_6, incrihgaps, {.i = -1 } },
+ { MODKEY|Mod4Mask, XK_7, incrivgaps, {.i = +1 } },
+ { MODKEY|Mod4Mask|ShiftMask, XK_7, incrivgaps, {.i = -1 } },
+ { MODKEY|Mod4Mask, XK_8, incrohgaps, {.i = +1 } },
+ { MODKEY|Mod4Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } },
+ { MODKEY|Mod4Mask, XK_9, incrovgaps, {.i = +1 } },
+ { MODKEY|Mod4Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } },
+ { MODKEY|Mod4Mask, XK_0, togglegaps, {0} },
+ { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
diff --git a/dwm.c b/dwm.c
index 664c527..bedbfea 100644
--- a/dwm.c
+++ b/dwm.c
@@ -119,6 +119,10 @@ struct Monitor {
int by; /* bar geometry */
int mx, my, mw, mh; /* screen size */
int wx, wy, ww, wh; /* window area */
+ int gappih; /* horizontal gap between windows */
+ int gappiv; /* vertical gap between windows */
+ int gappoh; /* horizontal outer gaps */
+ int gappov; /* vertical outer gaps */
unsigned int seltags;
unsigned int sellt;
unsigned int tagset[2];
@@ -209,7 +213,6 @@ static void sigchld(int unused);
static void spawn(const Arg *arg);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
-static void tile(Monitor *);
static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
static void toggletag(const Arg *arg);
@@ -639,6 +642,10 @@ createmon(void)
m->nmaster = nmaster;
m->showbar = showbar;
m->topbar = topbar;
+ m->gappih = gappih;
+ m->gappiv = gappiv;
+ m->gappoh = gappoh;
+ m->gappov = gappov;
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
@@ -1672,34 +1679,6 @@ tagmon(const Arg *arg)
}
void
-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++);
- 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);
- }
-}
-
-void
togglebar(const Arg *arg)
{
selmon->showbar = !selmon->showbar;
diff --git a/patches/actualfullscreen.diff b/patches/actualfullscreen.diff
new file mode 100644
index 0000000..21eea19
--- /dev/null
+++ b/patches/actualfullscreen.diff
@@ -0,0 +1,53 @@
+From 3a16816a6f5d38014c2a06ce395873c545c8789a Mon Sep 17 00:00:00 2001
+From: Soenke Lambert <s.lambert@mittwald.de>
+Date: Tue, 12 Nov 2019 10:44:02 +0100
+Subject: [PATCH] Fullscreen current window with [Alt]+[Shift]+[f]
+
+This actually fullscreens a window, instead of just hiding the statusbar
+and applying the monocle layout.
+---
+ config.def.h | 1 +
+ dwm.c | 8 ++++++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..8cd3204 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -78,6 +78,7 @@ static Key keys[] = {
+ { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XK_space, setlayout, {0} },
+ { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
++ { MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
+ { MODKEY, XK_0, view, {.ui = ~0 } },
+ { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
+ { MODKEY, XK_comma, focusmon, {.i = -1 } },
+diff --git a/dwm.c b/dwm.c
+index 4465af1..c1b899a 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -211,6 +211,7 @@ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
++static void togglefullscr(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+@@ -1719,6 +1720,13 @@ togglefloating(const Arg *arg)
+ arrange(selmon);
+ }
+
++void
++togglefullscr(const Arg *arg)
++{
++ if(selmon->sel)
++ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
++}
++
+ void
+ toggletag(const Arg *arg)
+ {
+--
+2.17.1
+
diff --git a/patches/alwaysfullscreen.diff b/patches/alwaysfullscreen.diff
new file mode 100644
index 0000000..19882e6
--- /dev/null
+++ b/patches/alwaysfullscreen.diff
@@ -0,0 +1,13 @@
+diff --git a/dwm.c b/dwm.c
+index 0362114..a5cab76 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -847,7 +847,7 @@ focusstack(const Arg *arg)
+ {
+ Client *c = NULL, *i;
+
+- if (!selmon->sel)
++ if (!selmon->sel || selmon->sel->isfullscreen)
+ return;
+ if (arg->i > 0) {
+ for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
diff --git a/patches/autostart.diff b/patches/autostart.diff
new file mode 100644
index 0000000..7e17424
--- /dev/null
+++ b/patches/autostart.diff
@@ -0,0 +1,179 @@
+From 37e970479dc5d40e57fc0cbfeaa5e39941483237 Mon Sep 17 00:00:00 2001
+From: Gan Ainm <gan.ainm.riomhphost@gmail.com>
+Date: Wed, 10 Jun 2020 10:59:02 +0000
+Subject: [PATCH] dwm-xdgautostart-6.2.diff
+
+===================================================================
+---
+ dwm.1 | 23 +++++++++++++++++
+ dwm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 105 insertions(+)
+
+diff --git a/dwm.1 b/dwm.1
+index 13b3729..9533aa6 100644
+--- a/dwm.1
++++ b/dwm.1
+@@ -30,6 +30,14 @@ top left corner. The tags which are applied to one or more windows are
+ indicated with an empty square in the top left corner.
+ .P
+ dwm draws a small border around windows to indicate the focus state.
++.P
++On start, dwm can start additional programs that may be specified in two special
++shell scripts (see the FILES section below), autostart_blocking.sh and
++autostart.sh. The former is executed first and dwm will wait for its
++termination before starting. The latter is executed in the background before
++dwm enters its handler loop.
++.P
++Either of these files may be omitted.
+ .SH OPTIONS
+ .TP
+ .B \-v
+@@ -152,6 +160,21 @@ Toggles focused window between floating and tiled state.
+ .TP
+ .B Mod1\-Button3
+ Resize focused window while dragging. Tiled windows will be toggled to the floating state.
++.SH FILES
++The files containing programs to be started along with dwm are searched for in
++the following directories:
++.IP "1. $XDG_DATA_HOME/dwm"
++.IP "2. $HOME/.local/share/dwm"
++.IP "3. $HOME/.dwm"
++.P
++The first existing directory is scanned for any of the autostart files below.
++.TP 15
++autostart.sh
++This file is started as a shell background process before dwm enters its handler
++loop.
++.TP 15
++autostart_blocking.sh
++This file is started before any autostart.sh; dwm waits for its termination.
+ .SH CUSTOMIZATION
+ dwm is customized by creating a custom config.h and (re)compiling the source
+ code. This keeps it fast, secure and simple.
+diff --git a/dwm.c b/dwm.c
+index 4465af1..2156b49 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -29,6 +29,7 @@
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/types.h>
++#include <sys/stat.h>
+ #include <sys/wait.h>
+ #include <X11/cursorfont.h>
+ #include <X11/keysym.h>
+@@ -193,6 +194,7 @@ static void resizeclient(Client *c, int x, int y, int w, int h);
+ static void resizemouse(const Arg *arg);
+ static void restack(Monitor *m);
+ static void run(void);
++static void runautostart(void);
+ static void scan(void);
+ static int sendevent(Client *c, Atom proto);
+ static void sendmon(Client *c, Monitor *m);
+@@ -235,7 +237,11 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+ static void zoom(const Arg *arg);
+
+ /* variables */
++static const char autostartblocksh[] = "autostart_blocking.sh";
++static const char autostartsh[] = "autostart.sh";
+ static const char broken[] = "broken";
++static const char dwmdir[] = "dwm";
++static const char localshare[] = ".local/share";
+ static char stext[256];
+ static int screen;
+ static int sw, sh; /* X display screen geometry width, height */
+@@ -1380,6 +1386,83 @@ run(void)
+ handler[ev.type](&ev); /* call handler */
+ }
+
++void
++runautostart(void)
++{
++ char *pathpfx;
++ char *path;
++ char *xdgdatahome;
++ char *home;
++ struct stat sb;
++
++ if ((home = getenv("HOME")) == NULL)
++ /* this is almost impossible */
++ return;
++
++ /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm,
++ * otherwise use ~/.local/share/dwm as autostart script directory
++ */
++ xdgdatahome = getenv("XDG_DATA_HOME");
++ if (xdgdatahome != NULL && *xdgdatahome != '\0') {
++ /* space for path segments, separators and nul */
++ pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2);
++
++ if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) {
++ free(pathpfx);
++ return;
++ }
++ } else {
++ /* space for path segments, separators and nul */
++ pathpfx = ecalloc(1, strlen(home) + strlen(localshare)
++ + strlen(dwmdir) + 3);
++
++ if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) {
++ free(pathpfx);
++ return;
++ }
++ }
++
++ /* check if the autostart script directory exists */
++ if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) {
++ /* the XDG conformant path does not exist or is no directory
++ * so we try ~/.dwm instead
++ */
++ char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3);
++ if(pathpfx_new == NULL) {
++ free(pathpfx);
++ return;
++ }
++ pathpfx = pathpfx_new;
++
++ if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) {
++ free(pathpfx);
++ return;
++ }
++ }
++
++ /* try the blocking script first */
++ path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2);
++ if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) {
++ free(path);
++ free(pathpfx);
++ }
++
++ if (access(path, X_OK) == 0)
++ system(path);
++
++ /* now the non-blocking script */
++ if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) {
++ free(path);
++ free(pathpfx);
++ }
++
++ if (access(path, X_OK) == 0)
++ system(strcat(path, " &"));
++
++ free(pathpfx);
++ free(path);
++}
++
+ void
+ scan(void)
+ {
+@@ -2142,6 +2223,7 @@ main(int argc, char *argv[])
+ die("pledge");
+ #endif /* __OpenBSD__ */
+ scan();
++ runautostart();
+ run();
+ cleanup();
+ XCloseDisplay(dpy);
+--
+2.27.0
+
diff --git a/patches/vanitygaps.diff b/patches/vanitygaps.diff
new file mode 100644
index 0000000..287a263
--- /dev/null
+++ b/patches/vanitygaps.diff
@@ -0,0 +1,971 @@
+From 9709d08daa290c8c7319571cd9e6ef4ec40e7683 Mon Sep 17 00:00:00 2001
+From: bakkeby <bakkeby@gmail.com>
+Date: Wed, 6 May 2020 17:21:25 +0200
+Subject: [PATCH] vanitygaps - adds gaps to layouts
+
+This patch differentiates between inner and outer gaps as well as
+horizontal and vertical gaps.
+
+The logic of these layouts also aims to be pixel perfect by ensuring
+an even split of the available space and re-distributing the remainder
+among the available clients.
+---
+ config.def.h | 38 ++-
+ dwm.c | 35 +--
+ vanitygaps.c | 809 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 854 insertions(+), 28 deletions(-)
+ create mode 100644 vanitygaps.c
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..a886863 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -3,6 +3,11 @@
+ /* appearance */
+ static const unsigned int borderpx = 1; /* border pixel of windows */
+ static const unsigned int snap = 32; /* snap pixel */
++static const unsigned int gappih = 20; /* horiz inner gap between windows */
++static const unsigned int gappiv = 10; /* vert inner gap between windows */
++static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */
++static const unsigned int gappov = 30; /* vert outer gap between windows and screen edge */
++static int smartgaps = 0; /* 1 means no outer gap when there is only one window */
+ static const int showbar = 1; /* 0 means no bar */
+ static const int topbar = 1; /* 0 means bottom bar */
+ static const char *fonts[] = { "monospace:size=10" };
+@@ -36,11 +41,26 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95]
+ static const int nmaster = 1; /* number of clients in master area */
+ static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
+
++#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */
++#include "vanitygaps.c"
++
+ static const Layout layouts[] = {
+ /* symbol arrange function */
+ { "[]=", tile }, /* first entry is default */
+- { "><>", NULL }, /* no layout function means floating behavior */
+ { "[M]", monocle },
++ { "[@]", spiral },
++ { "[\\]", dwindle },
++ { "H[]", deck },
++ { "TTT", bstack },
++ { "===", bstackhoriz },
++ { "HHH", grid },
++ { "###", nrowgrid },
++ { "---", horizgrid },
++ { ":::", gaplessgrid },
++ { "|M|", centeredmaster },
++ { ">M>", centeredfloatingmaster },
++ { "><>", NULL }, /* no layout function means floating behavior */
++ { NULL, NULL },
+ };
+
+ /* key definitions */
+@@ -71,6 +91,22 @@ static Key keys[] = {
+ { MODKEY, XK_h, setmfact, {.f = -0.05} },
+ { MODKEY, XK_l, setmfact, {.f = +0.05} },
+ { MODKEY, XK_Return, zoom, {0} },
++ { MODKEY|Mod4Mask, XK_u, incrgaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_u, incrgaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_i, incrigaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_i, incrigaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_o, incrogaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_o, incrogaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_6, incrihgaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_6, incrihgaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_7, incrivgaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_7, incrivgaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_8, incrohgaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_9, incrovgaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_0, togglegaps, {0} },
++ { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+ { MODKEY|ShiftMask, XK_c, killclient, {0} },
+ { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
+diff --git a/dwm.c b/dwm.c
+index 4465af1..c3b2d82 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -119,6 +119,10 @@ struct Monitor {
+ int by; /* bar geometry */
+ int mx, my, mw, mh; /* screen size */
+ int wx, wy, ww, wh; /* window area */
++ int gappih; /* horizontal gap between windows */
++ int gappiv; /* vertical gap between windows */
++ int gappoh; /* horizontal outer gaps */
++ int gappov; /* vertical outer gaps */
+ unsigned int seltags;
+ unsigned int sellt;
+ unsigned int tagset[2];
+@@ -208,7 +212,6 @@ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+-static void tile(Monitor *);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
+ static void toggletag(const Arg *arg);
+@@ -638,6 +641,10 @@ createmon(void)
+ m->nmaster = nmaster;
+ m->showbar = showbar;
+ m->topbar = topbar;
++ m->gappih = gappih;
++ m->gappiv = gappiv;
++ m->gappoh = gappoh;
++ m->gappov = gappov;
+ m->lt[0] = &layouts[0];
+ m->lt[1] = &layouts[1 % LENGTH(layouts)];
+ strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+@@ -1670,32 +1676,6 @@ tagmon(const Arg *arg)
+ sendmon(selmon->sel, dirtomon(arg->i));
+ }
+
+-void
+-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++);
+- 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);
+- 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);
+- ty += HEIGHT(c);
+- }
+-}
+-
+ void
+ togglebar(const Arg *arg)
+ {
+diff --git a/vanitygaps.c b/vanitygaps.c
+new file mode 100644
+index 0000000..3f31593
+--- /dev/null
++++ b/vanitygaps.c
+@@ -0,0 +1,809 @@
++/* Key binding functions */
++static void defaultgaps(const Arg *arg);
++static void incrgaps(const Arg *arg);
++static void incrigaps(const Arg *arg);
++static void incrogaps(const Arg *arg);
++static void incrohgaps(const Arg *arg);
++static void incrovgaps(const Arg *arg);
++static void incrihgaps(const Arg *arg);
++static void incrivgaps(const Arg *arg);
++static void togglegaps(const Arg *arg);
++/* Layouts (delete the ones you do not need) */
++static void bstack(Monitor *m);
++static void bstackhoriz(Monitor *m);
++static void centeredmaster(Monitor *m);
++static void centeredfloatingmaster(Monitor *m);
++static void deck(Monitor *m);
++static void dwindle(Monitor *m);
++static void fibonacci(Monitor *m, int s);
++static void grid(Monitor *m);
++static void nrowgrid(Monitor *m);
++static void spiral(Monitor *m);
++static void tile(Monitor *m);
++/* Internals */
++static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc);
++static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr);
++static void setgaps(int oh, int ov, int ih, int iv);
++
++/* Settings */
++#if !PERTAG_PATCH
++static int enablegaps = 1;
++#endif // PERTAG_PATCH
++
++void
++setgaps(int oh, int ov, int ih, int iv)
++{
++ if (oh < 0) oh = 0;
++ if (ov < 0) ov = 0;
++ if (ih < 0) ih = 0;
++ if (iv < 0) iv = 0;
++
++ selmon->gappoh = oh;
++ selmon->gappov = ov;
++ selmon->gappih = ih;
++ selmon->gappiv = iv;
++ arrange(selmon);
++}
++
++void
++togglegaps(const Arg *arg)
++{
++ #if PERTAG_PATCH
++ selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag];
++ #else
++ enablegaps = !enablegaps;
++ #endif // PERTAG_PATCH
++ arrange(NULL);
++}
++
++void
++defaultgaps(const Arg *arg)
++{
++ setgaps(gappoh, gappov, gappih, gappiv);
++}
++
++void
++incrgaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh + arg->i,
++ selmon->gappov + arg->i,
++ selmon->gappih + arg->i,
++ selmon->gappiv + arg->i
++ );
++}
++
++void
++incrigaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh,
++ selmon->gappov,
++ selmon->gappih + arg->i,
++ selmon->gappiv + arg->i
++ );
++}
++
++void
++incrogaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh + arg->i,
++ selmon->gappov + arg->i,
++ selmon->gappih,
++ selmon->gappiv
++ );
++}
++
++void
++incrohgaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh + arg->i,
++ selmon->gappov,
++ selmon->gappih,
++ selmon->gappiv
++ );
++}
++
++void
++incrovgaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh,
++ selmon->gappov + arg->i,
++ selmon->gappih,
++ selmon->gappiv
++ );
++}
++
++void
++incrihgaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh,
++ selmon->gappov,
++ selmon->gappih + arg->i,
++ selmon->gappiv
++ );
++}
++
++void
++incrivgaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh,
++ selmon->gappov,
++ selmon->gappih,
++ selmon->gappiv + arg->i
++ );
++}
++
++void
++getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc)
++{
++ unsigned int n, oe, ie;
++ #if PERTAG_PATCH
++ oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag];
++ #else
++ oe = ie = enablegaps;
++ #endif // PERTAG_PATCH
++ Client *c;
++
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
++ if (smartgaps && n == 1) {
++ oe = 0; // outer gaps disabled when only one client
++ }
++
++ *oh = m->gappoh*oe; // outer horizontal gap
++ *ov = m->gappov*oe; // outer vertical gap
++ *ih = m->gappih*ie; // inner horizontal gap
++ *iv = m->gappiv*ie; // inner vertical gap
++ *nc = n; // number of clients
++}
++
++void
++getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
++{
++ unsigned int n;
++ float mfacts, sfacts;
++ int mtotal = 0, stotal = 0;
++ Client *c;
++
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
++ mfacts = MIN(n, m->nmaster);
++ sfacts = n - m->nmaster;
++
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
++ if (n < m->nmaster)
++ mtotal += msize / mfacts;
++ else
++ stotal += ssize / sfacts;
++
++ *mf = mfacts; // total factor of master area
++ *sf = sfacts; // total factor of stack area
++ *mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
++ *sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
++}
++
++/***
++ * Layouts
++ */
++
++/*
++ * Bottomstack layout + gaps
++ * https://dwm.suckless.org/patches/bottomstack/
++ */
++static void
++bstack(Monitor *m)
++{
++ unsigned int i, n;
++ int oh, ov, ih, iv;
++ int mx = 0, my = 0, mh = 0, mw = 0;
++ int sx = 0, sy = 0, sh = 0, sw = 0;
++ float mfacts, sfacts;
++ int mrest, srest;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ sh = mh = m->wh - 2*oh;
++ mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
++ sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
++
++ if (m->nmaster && n > m->nmaster) {
++ sh = (mh - ih) * (1 - m->mfact);
++ mh = mh - ih - sh;
++ sx = mx;
++ sy = my + mh + ih;
++ }
++
++ getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
++ if (i < m->nmaster) {
++ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
++ mx += WIDTH(c) + iv;
++ } else {
++ resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
++ sx += WIDTH(c) + iv;
++ }
++ }
++}
++
++static void
++bstackhoriz(Monitor *m)
++{
++ unsigned int i, n;
++ int oh, ov, ih, iv;
++ int mx = 0, my = 0, mh = 0, mw = 0;
++ int sx = 0, sy = 0, sh = 0, sw = 0;
++ float mfacts, sfacts;
++ int mrest, srest;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ mh = m->wh - 2*oh;
++ sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
++ mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
++ sw = m->ww - 2*ov;
++
++ if (m->nmaster && n > m->nmaster) {
++ sh = (mh - ih) * (1 - m->mfact);
++ mh = mh - ih - sh;
++ sy = my + mh + ih;
++ sh = m->wh - mh - 2*oh - ih * (n - m->nmaster);
++ }
++
++ getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest);
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
++ if (i < m->nmaster) {
++ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
++ mx += WIDTH(c) + iv;
++ } else {
++ resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
++ sy += HEIGHT(c) + ih;
++ }
++ }
++}
++
++/*
++ * Centred master layout + gaps
++ * https://dwm.suckless.org/patches/centeredmaster/
++ */
++void
++centeredmaster(Monitor *m)
++{
++ unsigned int i, n;
++ int oh, ov, ih, iv;
++ int mx = 0, my = 0, mh = 0, mw = 0;
++ int lx = 0, ly = 0, lw = 0, lh = 0;
++ int rx = 0, ry = 0, rw = 0, rh = 0;
++ float mfacts = 0, lfacts = 0, rfacts = 0;
++ int mtotal = 0, ltotal = 0, rtotal = 0;
++ int mrest = 0, lrest = 0, rrest = 0;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ /* initialize areas */
++ mx = m->wx + ov;
++ my = m->wy + oh;
++ mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
++ mw = m->ww - 2*ov;
++ lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
++ rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
++
++ if (m->nmaster && n > m->nmaster) {
++ /* go mfact box in the center if more than nmaster clients */
++ if (n - m->nmaster > 1) {
++ /* ||<-S->|<---M--->|<-S->|| */
++ mw = (m->ww - 2*ov - 2*iv) * m->mfact;
++ lw = (m->ww - mw - 2*ov - 2*iv) / 2;
++ rw = (m->ww - mw - 2*ov - 2*iv) - lw;
++ mx += lw + iv;
++ } else {
++ /* ||<---M--->|<-S->|| */
++ mw = (mw - iv) * m->mfact;
++ lw = 0;
++ rw = m->ww - mw - iv - 2*ov;
++ }
++ lx = m->wx + ov;
++ ly = m->wy + oh;
++ rx = mx + mw + iv;
++ ry = m->wy + oh;
++ }
++
++ /* calculate facts */
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
++ if (!m->nmaster || n < m->nmaster)
++ mfacts += 1;
++ else if ((n - m->nmaster) % 2)
++ lfacts += 1; // total factor of left hand stack area
++ else
++ rfacts += 1; // total factor of right hand stack area
++ }
++
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
++ if (!m->nmaster || n < m->nmaster)
++ mtotal += mh / mfacts;
++ else if ((n - m->nmaster) % 2)
++ ltotal += lh / lfacts;
++ else
++ rtotal += rh / rfacts;
++
++ mrest = mh - mtotal;
++ lrest = lh - ltotal;
++ rrest = rh - rtotal;
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
++ if (!m->nmaster || i < m->nmaster) {
++ /* nmaster clients are stacked vertically, in the center of the screen */
++ resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
++ my += HEIGHT(c) + ih;
++ } else {
++ /* stack clients are stacked vertically */
++ if ((i - m->nmaster) % 2 ) {
++ resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
++ ly += HEIGHT(c) + ih;
++ } else {
++ resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
++ ry += HEIGHT(c) + ih;
++ }
++ }
++ }
++}
++
++void
++centeredfloatingmaster(Monitor *m)
++{
++ unsigned int i, n;
++ float mfacts, sfacts;
++ float mivf = 1.0; // master inner vertical gap factor
++ int oh, ov, ih, iv, mrest, srest;
++ int mx = 0, my = 0, mh = 0, mw = 0;
++ int sx = 0, sy = 0, sh = 0, sw = 0;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ sh = mh = m->wh - 2*oh;
++ mw = m->ww - 2*ov - iv*(n - 1);
++ sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
++
++ if (m->nmaster && n > m->nmaster) {
++ mivf = 0.8;
++ /* go mfact box in the center if more than nmaster clients */
++ if (m->ww > m->wh) {
++ mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
++ mh = m->wh * 0.9;
++ } else {
++ mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
++ mh = m->wh * m->mfact;
++ }
++ mx = m->wx + (m->ww - mw) / 2;
++ my = m->wy + (m->wh - mh - 2*oh) / 2;
++
++ sx = m->wx + ov;
++ sy = m->wy + oh;
++ sh = m->wh - 2*oh;
++ }
++
++ getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++ if (i < m->nmaster) {
++ /* nmaster clients are stacked horizontally, in the center of the screen */
++ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
++ mx += WIDTH(c) + iv*mivf;
++ } else {
++ /* stack clients are stacked horizontally */
++ resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
++ sx += WIDTH(c) + iv;
++ }
++}
++
++/*
++ * Deck layout + gaps
++ * https://dwm.suckless.org/patches/deck/
++ */
++void
++deck(Monitor *m)
++{
++ unsigned int i, n;
++ int oh, ov, ih, iv;
++ int mx = 0, my = 0, mh = 0, mw = 0;
++ int sx = 0, sy = 0, sh = 0, sw = 0;
++ float mfacts, sfacts;
++ int mrest, srest;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
++ sw = mw = m->ww - 2*ov;
++
++ if (m->nmaster && n > m->nmaster) {
++ sw = (mw - iv) * (1 - m->mfact);
++ mw = mw - iv - sw;
++ sx = mx + mw + iv;
++ sh = m->wh - 2*oh;
++ }
++
++ getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
++
++ if (n - m->nmaster > 0) /* override layout symbol */
++ snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster);
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++ if (i < m->nmaster) {
++ resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
++ my += HEIGHT(c) + ih;
++ } else {
++ resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
++ }
++}
++
++/*
++ * Fibonacci layout + gaps
++ * https://dwm.suckless.org/patches/fibonacci/
++ */
++void
++fibonacci(Monitor *m, int s)
++{
++ unsigned int i, n;
++ int nx, ny, nw, nh;
++ int oh, ov, ih, iv;
++ int nv, hrest = 0, wrest = 0, r = 1;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ nx = m->wx + ov;
++ ny = m->wy + oh;
++ nw = m->ww - 2*ov;
++ nh = m->wh - 2*oh;
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
++ if (r) {
++ if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw))
++ || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) {
++ r = 0;
++ }
++ if (r && i < n - 1) {
++ if (i % 2) {
++ nv = (nh - ih) / 2;
++ hrest = nh - 2*nv - ih;
++ nh = nv;
++ } else {
++ nv = (nw - iv) / 2;
++ wrest = nw - 2*nv - iv;
++ nw = nv;
++ }
++
++ if ((i % 4) == 2 && !s)
++ nx += nw + iv;
++ else if ((i % 4) == 3 && !s)
++ ny += nh + ih;
++ }
++
++ if ((i % 4) == 0) {
++ if (s) {
++ ny += nh + ih;
++ nh += hrest;
++ }
++ else {
++ nh -= hrest;
++ ny -= nh + ih;
++ }
++ }
++ else if ((i % 4) == 1) {
++ nx += nw + iv;
++ nw += wrest;
++ }
++ else if ((i % 4) == 2) {
++ ny += nh + ih;
++ nh += hrest;
++ if (i < n - 1)
++ nw += wrest;
++ }
++ else if ((i % 4) == 3) {
++ if (s) {
++ nx += nw + iv;
++ nw -= wrest;
++ } else {
++ nw -= wrest;
++ nx -= nw + iv;
++ nh += hrest;
++ }
++ }
++ if (i == 0) {
++ if (n != 1) {
++ nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact);
++ wrest = 0;
++ }
++ ny = m->wy + oh;
++ }
++ else if (i == 1)
++ nw = m->ww - nw - iv - 2*ov;
++ i++;
++ }
++
++ resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
++ }
++}
++
++void
++dwindle(Monitor *m)
++{
++ fibonacci(m, 1);
++}
++
++void
++spiral(Monitor *m)
++{
++ fibonacci(m, 0);
++}
++
++/*
++ * Gappless grid layout + gaps (ironically)
++ * https://dwm.suckless.org/patches/gaplessgrid/
++ */
++void
++gaplessgrid(Monitor *m)
++{
++ unsigned int i, n;
++ int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
++ int oh, ov, ih, iv;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ /* grid dimensions */
++ for (cols = 0; cols <= n/2; cols++)
++ if (cols*cols >= n)
++ break;
++ if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
++ cols = 2;
++ rows = n/cols;
++ cn = rn = 0; // reset column no, row no, client count
++
++ ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
++ cw = (m->ww - 2*ov - iv * (cols - 1)) / cols;
++ rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
++ crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
++ x = m->wx + ov;
++ y = m->wy + oh;
++
++ for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) {
++ if (i/rows + 1 > cols - n%cols) {
++ rows = n/cols + 1;
++ ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
++ rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
++ }
++ resize(c,
++ x,
++ y + rn*(ch + ih) + MIN(rn, rrest),
++ cw + (cn < crest ? 1 : 0) - 2*c->bw,
++ ch + (rn < rrest ? 1 : 0) - 2*c->bw,
++ 0);
++ rn++;
++ if (rn >= rows) {
++ rn = 0;
++ x += cw + ih + (cn < crest ? 1 : 0);
++ cn++;
++ }
++ }
++}
++
++/*
++ * Gridmode layout + gaps
++ * https://dwm.suckless.org/patches/gridmode/
++ */
++void
++grid(Monitor *m)
++{
++ unsigned int i, n;
++ int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows;
++ int oh, ov, ih, iv;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++
++ /* grid dimensions */
++ for (rows = 0; rows <= n/2; rows++)
++ if (rows*rows >= n)
++ break;
++ cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
++
++ /* window geoms (cell height/width) */
++ ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1);
++ cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1);
++ chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
++ cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
++ cc = i / rows;
++ cr = i % rows;
++ cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest);
++ cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest);
++ resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False);
++ }
++}
++
++/*
++ * Horizontal grid layout + gaps
++ * https://dwm.suckless.org/patches/horizgrid/
++ */
++void
++horizgrid(Monitor *m) {
++ Client *c;
++ unsigned int n, i;
++ int oh, ov, ih, iv;
++ int mx = 0, my = 0, mh = 0, mw = 0;
++ int sx = 0, sy = 0, sh = 0, sw = 0;
++ int ntop, nbottom = 1;
++ float mfacts, sfacts;
++ int mrest, srest;
++
++ /* Count windows */
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ if (n <= 2)
++ ntop = n;
++ else {
++ ntop = n / 2;
++ nbottom = n - ntop;
++ }
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ sh = mh = m->wh - 2*oh;
++ sw = mw = m->ww - 2*ov;
++
++ if (n > ntop) {
++ sh = (mh - ih) / 2;
++ mh = mh - ih - sh;
++ sy = my + mh + ih;
++ mw = m->ww - 2*ov - iv * (ntop - 1);
++ sw = m->ww - 2*ov - iv * (nbottom - 1);
++ }
++
++ mfacts = ntop;
++ sfacts = nbottom;
++ mrest = mw - (mw / ntop) * ntop;
++ srest = sw - (sw / nbottom) * nbottom;
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++ if (i < ntop) {
++ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
++ mx += WIDTH(c) + iv;
++ } else {
++ resize(c, sx, sy, (sw / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
++ sx += WIDTH(c) + iv;
++ }
++}
++
++/*
++ * nrowgrid layout + gaps
++ * https://dwm.suckless.org/patches/nrowgrid/
++ */
++void
++nrowgrid(Monitor *m)
++{
++ unsigned int n;
++ int ri = 0, ci = 0; /* counters */
++ int oh, ov, ih, iv; /* vanitygap settings */
++ unsigned int cx, cy, cw, ch; /* client geometry */
++ unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */
++ unsigned int cols, rows = m->nmaster + 1;
++ Client *c;
++
++ /* count clients */
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++
++ /* nothing to do here */
++ if (n == 0)
++ return;
++
++ /* force 2 clients to always split vertically */
++ if (FORCE_VSPLIT && n == 2)
++ rows = 1;
++
++ /* never allow empty rows */
++ if (n < rows)
++ rows = n;
++
++ /* define first row */
++ cols = n / rows;
++ uc = cols;
++ cy = m->wy + oh;
++ ch = (m->wh - 2*oh - ih*(rows - 1)) / rows;
++ uh = ch;
++
++ for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) {
++ if (ci == cols) {
++ uw = 0;
++ ci = 0;
++ ri++;
++
++ /* next row */
++ cols = (n - uc) / (rows - ri);
++ uc += cols;
++ cy = m->wy + oh + uh + ih;
++ uh += ch + ih;
++ }
++
++ cx = m->wx + ov + uw;
++ cw = (m->ww - 2*ov - uw) / (cols - ci);
++ uw += cw + iv;
++
++ resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0);
++ }
++}
++
++/*
++ * Default tile layout + gaps
++ */
++static void
++tile(Monitor *m)
++{
++ unsigned int i, n;
++ int oh, ov, ih, iv;
++ int mx = 0, my = 0, mh = 0, mw = 0;
++ int sx = 0, sy = 0, sh = 0, sw = 0;
++ float mfacts, sfacts;
++ int mrest, srest;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
++ sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
++ sw = mw = m->ww - 2*ov;
++
++ if (m->nmaster && n > m->nmaster) {
++ sw = (mw - iv) * (1 - m->mfact);
++ mw = mw - iv - sw;
++ sx = mx + mw + iv;
++ }
++
++ getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++ if (i < m->nmaster) {
++ resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
++ my += HEIGHT(c) + ih;
++ } else {
++ resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
++ sy += HEIGHT(c) + ih;
++ }
++}
+\ No newline at end of file
+--
+2.19.1
+
diff --git a/vanitygaps.c b/vanitygaps.c
new file mode 100644
index 0000000..3f31593
--- /dev/null
+++ b/vanitygaps.c
@@ -0,0 +1,809 @@
+/* Key binding functions */
+static void defaultgaps(const Arg *arg);
+static void incrgaps(const Arg *arg);
+static void incrigaps(const Arg *arg);
+static void incrogaps(const Arg *arg);
+static void incrohgaps(const Arg *arg);
+static void incrovgaps(const Arg *arg);
+static void incrihgaps(const Arg *arg);
+static void incrivgaps(const Arg *arg);
+static void togglegaps(const Arg *arg);
+/* Layouts (delete the ones you do not need) */
+static void bstack(Monitor *m);
+static void bstackhoriz(Monitor *m);
+static void centeredmaster(Monitor *m);
+static void centeredfloatingmaster(Monitor *m);
+static void deck(Monitor *m);
+static void dwindle(Monitor *m);
+static void fibonacci(Monitor *m, int s);
+static void grid(Monitor *m);
+static void nrowgrid(Monitor *m);
+static void spiral(Monitor *m);
+static void tile(Monitor *m);
+/* Internals */
+static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc);
+static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr);
+static void setgaps(int oh, int ov, int ih, int iv);
+
+/* Settings */
+#if !PERTAG_PATCH
+static int enablegaps = 1;
+#endif // PERTAG_PATCH
+
+void
+setgaps(int oh, int ov, int ih, int iv)
+{
+ if (oh < 0) oh = 0;
+ if (ov < 0) ov = 0;
+ if (ih < 0) ih = 0;
+ if (iv < 0) iv = 0;
+
+ selmon->gappoh = oh;
+ selmon->gappov = ov;
+ selmon->gappih = ih;
+ selmon->gappiv = iv;
+ arrange(selmon);
+}
+
+void
+togglegaps(const Arg *arg)
+{
+ #if PERTAG_PATCH
+ selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag];
+ #else
+ enablegaps = !enablegaps;
+ #endif // PERTAG_PATCH
+ arrange(NULL);
+}
+
+void
+defaultgaps(const Arg *arg)
+{
+ setgaps(gappoh, gappov, gappih, gappiv);
+}
+
+void
+incrgaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh + arg->i,
+ selmon->gappov + arg->i,
+ selmon->gappih + arg->i,
+ selmon->gappiv + arg->i
+ );
+}
+
+void
+incrigaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh,
+ selmon->gappov,
+ selmon->gappih + arg->i,
+ selmon->gappiv + arg->i
+ );
+}
+
+void
+incrogaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh + arg->i,
+ selmon->gappov + arg->i,
+ selmon->gappih,
+ selmon->gappiv
+ );
+}
+
+void
+incrohgaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh + arg->i,
+ selmon->gappov,
+ selmon->gappih,
+ selmon->gappiv
+ );
+}
+
+void
+incrovgaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh,
+ selmon->gappov + arg->i,
+ selmon->gappih,
+ selmon->gappiv
+ );
+}
+
+void
+incrihgaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh,
+ selmon->gappov,
+ selmon->gappih + arg->i,
+ selmon->gappiv
+ );
+}
+
+void
+incrivgaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh,
+ selmon->gappov,
+ selmon->gappih,
+ selmon->gappiv + arg->i
+ );
+}
+
+void
+getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc)
+{
+ unsigned int n, oe, ie;
+ #if PERTAG_PATCH
+ oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag];
+ #else
+ oe = ie = enablegaps;
+ #endif // PERTAG_PATCH
+ Client *c;
+
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ if (smartgaps && n == 1) {
+ oe = 0; // outer gaps disabled when only one client
+ }
+
+ *oh = m->gappoh*oe; // outer horizontal gap
+ *ov = m->gappov*oe; // outer vertical gap
+ *ih = m->gappih*ie; // inner horizontal gap
+ *iv = m->gappiv*ie; // inner vertical gap
+ *nc = n; // number of clients
+}
+
+void
+getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
+{
+ unsigned int n;
+ float mfacts, sfacts;
+ int mtotal = 0, stotal = 0;
+ Client *c;
+
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ mfacts = MIN(n, m->nmaster);
+ sfacts = n - m->nmaster;
+
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
+ if (n < m->nmaster)
+ mtotal += msize / mfacts;
+ else
+ stotal += ssize / sfacts;
+
+ *mf = mfacts; // total factor of master area
+ *sf = sfacts; // total factor of stack area
+ *mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
+ *sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
+}
+
+/***
+ * Layouts
+ */
+
+/*
+ * Bottomstack layout + gaps
+ * https://dwm.suckless.org/patches/bottomstack/
+ */
+static void
+bstack(Monitor *m)
+{
+ unsigned int i, n;
+ int oh, ov, ih, iv;
+ int mx = 0, my = 0, mh = 0, mw = 0;
+ int sx = 0, sy = 0, sh = 0, sw = 0;
+ float mfacts, sfacts;
+ int mrest, srest;
+ Client *c;
+
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
+ if (n == 0)
+ return;
+
+ sx = mx = m->wx + ov;
+ sy = my = m->wy + oh;
+ sh = mh = m->wh - 2*oh;
+ mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
+ sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
+
+ if (m->nmaster && n > m->nmaster) {
+ sh = (mh - ih) * (1 - m->mfact);
+ mh = mh - ih - sh;
+ sx = mx;
+ sy = my + mh + ih;
+ }
+
+ getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
+
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
+ if (i < m->nmaster) {
+ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
+ mx += WIDTH(c) + iv;
+ } else {
+ resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
+ sx += WIDTH(c) + iv;
+ }
+ }
+}
+
+static void
+bstackhoriz(Monitor *m)
+{
+ unsigned int i, n;
+ int oh, ov, ih, iv;
+ int mx = 0, my = 0, mh = 0, mw = 0;
+ int sx = 0, sy = 0, sh = 0, sw = 0;
+ float mfacts, sfacts;
+ int mrest, srest;
+ Client *c;
+
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
+ if (n == 0)
+ return;
+
+ sx = mx = m->wx + ov;
+ sy = my = m->wy + oh;
+ mh = m->wh - 2*oh;
+ sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
+ mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
+ sw = m->ww - 2*ov;
+
+ if (m->nmaster && n > m->nmaster) {
+ sh = (mh - ih) * (1 - m->mfact);
+ mh = mh - ih - sh;
+ sy = my + mh + ih;
+ sh = m->wh - mh - 2*oh - ih * (n - m->nmaster);
+ }
+
+ getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest);
+
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
+ if (i < m->nmaster) {
+ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
+ mx += WIDTH(c) + iv;
+ } else {
+ resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
+ sy += HEIGHT(c) + ih;
+ }
+ }
+}
+
+/*
+ * Centred master layout + gaps
+ * https://dwm.suckless.org/patches/centeredmaster/
+ */
+void
+centeredmaster(Monitor *m)
+{
+ unsigned int i, n;
+ int oh, ov, ih, iv;
+ int mx = 0, my = 0, mh = 0, mw = 0;
+ int lx = 0, ly = 0, lw = 0, lh = 0;
+ int rx = 0, ry = 0, rw = 0, rh = 0;
+ float mfacts = 0, lfacts = 0, rfacts = 0;
+ int mtotal = 0, ltotal = 0, rtotal = 0;
+ int mrest = 0, lrest = 0, rrest = 0;
+ Client *c;
+
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
+ if (n == 0)
+ return;
+
+ /* initialize areas */
+ mx = m->wx + ov;
+ my = m->wy + oh;
+ mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
+ mw = m->ww - 2*ov;
+ lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
+ rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
+
+ if (m->nmaster && n > m->nmaster) {
+ /* go mfact box in the center if more than nmaster clients */
+ if (n - m->nmaster > 1) {
+ /* ||<-S->|<---M--->|<-S->|| */
+ mw = (m->ww - 2*ov - 2*iv) * m->mfact;
+ lw = (m->ww - mw - 2*ov - 2*iv) / 2;
+ rw = (m->ww - mw - 2*ov - 2*iv) - lw;
+ mx += lw + iv;
+ } else {
+ /* ||<---M--->|<-S->|| */
+ mw = (mw - iv) * m->mfact;
+ lw = 0;
+ rw = m->ww - mw - iv - 2*ov;
+ }
+ lx = m->wx + ov;
+ ly = m->wy + oh;
+ rx = mx + mw + iv;
+ ry = m->wy + oh;
+ }
+
+ /* calculate facts */
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
+ if (!m->nmaster || n < m->nmaster)
+ mfacts += 1;
+ else if ((n - m->nmaster) % 2)
+ lfacts += 1; // total factor of left hand stack area
+ else
+ rfacts += 1; // total factor of right hand stack area
+ }
+
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
+ if (!m->nmaster || n < m->nmaster)
+ mtotal += mh / mfacts;
+ else if ((n - m->nmaster) % 2)
+ ltotal += lh / lfacts;
+ else
+ rtotal += rh / rfacts;
+
+ mrest = mh - mtotal;
+ lrest = lh - ltotal;
+ rrest = rh - rtotal;
+
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
+ if (!m->nmaster || i < m->nmaster) {
+ /* nmaster clients are stacked vertically, in the center of the screen */
+ resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
+ my += HEIGHT(c) + ih;
+ } else {
+ /* stack clients are stacked vertically */
+ if ((i - m->nmaster) % 2 ) {
+ resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
+ ly += HEIGHT(c) + ih;
+ } else {
+ resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
+ ry += HEIGHT(c) + ih;
+ }
+ }
+ }
+}
+
+void
+centeredfloatingmaster(Monitor *m)
+{
+ unsigned int i, n;
+ float mfacts, sfacts;
+ float mivf = 1.0; // master inner vertical gap factor
+ int oh, ov, ih, iv, mrest, srest;
+ int mx = 0, my = 0, mh = 0, mw = 0;
+ int sx = 0, sy = 0, sh = 0, sw = 0;
+ Client *c;
+
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
+ if (n == 0)
+ return;
+
+ sx = mx = m->wx + ov;
+ sy = my = m->wy + oh;
+ sh = mh = m->wh - 2*oh;
+ mw = m->ww - 2*ov - iv*(n - 1);
+ sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
+
+ if (m->nmaster && n > m->nmaster) {
+ mivf = 0.8;
+ /* go mfact box in the center if more than nmaster clients */
+ if (m->ww > m->wh) {
+ mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
+ mh = m->wh * 0.9;
+ } else {
+ mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
+ mh = m->wh * m->mfact;
+ }
+ mx = m->wx + (m->ww - mw) / 2;
+ my = m->wy + (m->wh - mh - 2*oh) / 2;
+
+ sx = m->wx + ov;
+ sy = m->wy + oh;
+ sh = m->wh - 2*oh;
+ }
+
+ getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
+
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ if (i < m->nmaster) {
+ /* nmaster clients are stacked horizontally, in the center of the screen */
+ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
+ mx += WIDTH(c) + iv*mivf;
+ } else {
+ /* stack clients are stacked horizontally */
+ resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
+ sx += WIDTH(c) + iv;
+ }
+}
+
+/*
+ * Deck layout + gaps
+ * https://dwm.suckless.org/patches/deck/
+ */
+void
+deck(Monitor *m)
+{
+ unsigned int i, n;
+ int oh, ov, ih, iv;
+ int mx = 0, my = 0, mh = 0, mw = 0;
+ int sx = 0, sy = 0, sh = 0, sw = 0;
+ float mfacts, sfacts;
+ int mrest, srest;
+ Client *c;
+
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
+ if (n == 0)
+ return;
+
+ sx = mx = m->wx + ov;
+ sy = my = m->wy + oh;
+ sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
+ sw = mw = m->ww - 2*ov;
+
+ if (m->nmaster && n > m->nmaster) {
+ sw = (mw - iv) * (1 - m->mfact);
+ mw = mw - iv - sw;
+ sx = mx + mw + iv;
+ sh = m->wh - 2*oh;
+ }
+
+ getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
+
+ if (n - m->nmaster > 0) /* override layout symbol */
+ snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster);
+
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ if (i < m->nmaster) {
+ resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
+ my += HEIGHT(c) + ih;
+ } else {
+ resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
+ }
+}
+
+/*
+ * Fibonacci layout + gaps
+ * https://dwm.suckless.org/patches/fibonacci/
+ */
+void
+fibonacci(Monitor *m, int s)
+{
+ unsigned int i, n;
+ int nx, ny, nw, nh;
+ int oh, ov, ih, iv;
+ int nv, hrest = 0, wrest = 0, r = 1;
+ Client *c;
+
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
+ if (n == 0)
+ return;
+
+ nx = m->wx + ov;
+ ny = m->wy + oh;
+ nw = m->ww - 2*ov;
+ nh = m->wh - 2*oh;
+
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
+ if (r) {
+ if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw))
+ || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) {
+ r = 0;
+ }
+ if (r && i < n - 1) {
+ if (i % 2) {
+ nv = (nh - ih) / 2;
+ hrest = nh - 2*nv - ih;
+ nh = nv;
+ } else {
+ nv = (nw - iv) / 2;
+ wrest = nw - 2*nv - iv;
+ nw = nv;
+ }
+
+ if ((i % 4) == 2 && !s)
+ nx += nw + iv;
+ else if ((i % 4) == 3 && !s)
+ ny += nh + ih;
+ }
+
+ if ((i % 4) == 0) {
+ if (s) {
+ ny += nh + ih;
+ nh += hrest;
+ }
+ else {
+ nh -= hrest;
+ ny -= nh + ih;
+ }
+ }
+ else if ((i % 4) == 1) {
+ nx += nw + iv;
+ nw += wrest;
+ }
+ else if ((i % 4) == 2) {
+ ny += nh + ih;
+ nh += hrest;
+ if (i < n - 1)
+ nw += wrest;
+ }
+ else if ((i % 4) == 3) {
+ if (s) {
+ nx += nw + iv;
+ nw -= wrest;
+ } else {
+ nw -= wrest;
+ nx -= nw + iv;
+ nh += hrest;
+ }
+ }
+ if (i == 0) {
+ if (n != 1) {
+ nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact);
+ wrest = 0;
+ }
+ ny = m->wy + oh;
+ }
+ else if (i == 1)
+ nw = m->ww - nw - iv - 2*ov;
+ i++;
+ }
+
+ resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
+ }
+}
+
+void
+dwindle(Monitor *m)
+{
+ fibonacci(m, 1);
+}
+
+void
+spiral(Monitor *m)
+{
+ fibonacci(m, 0);
+}
+
+/*
+ * Gappless grid layout + gaps (ironically)
+ * https://dwm.suckless.org/patches/gaplessgrid/
+ */
+void
+gaplessgrid(Monitor *m)
+{
+ unsigned int i, n;
+ int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
+ int oh, ov, ih, iv;
+ Client *c;
+
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
+ if (n == 0)
+ return;
+
+ /* grid dimensions */
+ for (cols = 0; cols <= n/2; cols++)
+ if (cols*cols >= n)
+ break;
+ if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
+ cols = 2;
+ rows = n/cols;
+ cn = rn = 0; // reset column no, row no, client count
+
+ ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
+ cw = (m->ww - 2*ov - iv * (cols - 1)) / cols;
+ rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
+ crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
+ x = m->wx + ov;
+ y = m->wy + oh;
+
+ for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) {
+ if (i/rows + 1 > cols - n%cols) {
+ rows = n/cols + 1;
+ ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
+ rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
+ }
+ resize(c,
+ x,
+ y + rn*(ch + ih) + MIN(rn, rrest),
+ cw + (cn < crest ? 1 : 0) - 2*c->bw,
+ ch + (rn < rrest ? 1 : 0) - 2*c->bw,
+ 0);
+ rn++;
+ if (rn >= rows) {
+ rn = 0;
+ x += cw + ih + (cn < crest ? 1 : 0);
+ cn++;
+ }
+ }
+}
+
+/*
+ * Gridmode layout + gaps
+ * https://dwm.suckless.org/patches/gridmode/
+ */
+void
+grid(Monitor *m)
+{
+ unsigned int i, n;
+ int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows;
+ int oh, ov, ih, iv;
+ Client *c;
+
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
+
+ /* grid dimensions */
+ for (rows = 0; rows <= n/2; rows++)
+ if (rows*rows >= n)
+ break;
+ cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
+
+ /* window geoms (cell height/width) */
+ ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1);
+ cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1);
+ chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
+ cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
+ cc = i / rows;
+ cr = i % rows;
+ cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest);
+ cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest);
+ resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False);
+ }
+}
+
+/*
+ * Horizontal grid layout + gaps
+ * https://dwm.suckless.org/patches/horizgrid/
+ */
+void
+horizgrid(Monitor *m) {
+ Client *c;
+ unsigned int n, i;
+ int oh, ov, ih, iv;
+ int mx = 0, my = 0, mh = 0, mw = 0;
+ int sx = 0, sy = 0, sh = 0, sw = 0;
+ int ntop, nbottom = 1;
+ float mfacts, sfacts;
+ int mrest, srest;
+
+ /* Count windows */
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
+ if (n == 0)
+ return;
+
+ if (n <= 2)
+ ntop = n;
+ else {
+ ntop = n / 2;
+ nbottom = n - ntop;
+ }
+ sx = mx = m->wx + ov;
+ sy = my = m->wy + oh;
+ sh = mh = m->wh - 2*oh;
+ sw = mw = m->ww - 2*ov;
+
+ if (n > ntop) {
+ sh = (mh - ih) / 2;
+ mh = mh - ih - sh;
+ sy = my + mh + ih;
+ mw = m->ww - 2*ov - iv * (ntop - 1);
+ sw = m->ww - 2*ov - iv * (nbottom - 1);
+ }
+
+ mfacts = ntop;
+ sfacts = nbottom;
+ mrest = mw - (mw / ntop) * ntop;
+ srest = sw - (sw / nbottom) * nbottom;
+
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ if (i < ntop) {
+ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
+ mx += WIDTH(c) + iv;
+ } else {
+ resize(c, sx, sy, (sw / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
+ sx += WIDTH(c) + iv;
+ }
+}
+
+/*
+ * nrowgrid layout + gaps
+ * https://dwm.suckless.org/patches/nrowgrid/
+ */
+void
+nrowgrid(Monitor *m)
+{
+ unsigned int n;
+ int ri = 0, ci = 0; /* counters */
+ int oh, ov, ih, iv; /* vanitygap settings */
+ unsigned int cx, cy, cw, ch; /* client geometry */
+ unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */
+ unsigned int cols, rows = m->nmaster + 1;
+ Client *c;
+
+ /* count clients */
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
+
+ /* nothing to do here */
+ if (n == 0)
+ return;
+
+ /* force 2 clients to always split vertically */
+ if (FORCE_VSPLIT && n == 2)
+ rows = 1;
+
+ /* never allow empty rows */
+ if (n < rows)
+ rows = n;
+
+ /* define first row */
+ cols = n / rows;
+ uc = cols;
+ cy = m->wy + oh;
+ ch = (m->wh - 2*oh - ih*(rows - 1)) / rows;
+ uh = ch;
+
+ for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) {
+ if (ci == cols) {
+ uw = 0;
+ ci = 0;
+ ri++;
+
+ /* next row */
+ cols = (n - uc) / (rows - ri);
+ uc += cols;
+ cy = m->wy + oh + uh + ih;
+ uh += ch + ih;
+ }
+
+ cx = m->wx + ov + uw;
+ cw = (m->ww - 2*ov - uw) / (cols - ci);
+ uw += cw + iv;
+
+ resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0);
+ }
+}
+
+/*
+ * Default tile layout + gaps
+ */
+static void
+tile(Monitor *m)
+{
+ unsigned int i, n;
+ int oh, ov, ih, iv;
+ int mx = 0, my = 0, mh = 0, mw = 0;
+ int sx = 0, sy = 0, sh = 0, sw = 0;
+ float mfacts, sfacts;
+ int mrest, srest;
+ Client *c;
+
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
+ if (n == 0)
+ return;
+
+ sx = mx = m->wx + ov;
+ sy = my = m->wy + oh;
+ mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
+ sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
+ sw = mw = m->ww - 2*ov;
+
+ if (m->nmaster && n > m->nmaster) {
+ sw = (mw - iv) * (1 - m->mfact);
+ mw = mw - iv - sw;
+ sx = mx + mw + iv;
+ }
+
+ getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
+
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ if (i < m->nmaster) {
+ resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
+ my += HEIGHT(c) + ih;
+ } else {
+ resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
+ sy += HEIGHT(c) + ih;
+ }
+} \ No newline at end of file