From 429ae687291d9a06a84fe2ef1a4f40bcb17cc015 Mon Sep 17 00:00:00 2001 From: memL0rz Date: Wed, 18 Sep 2024 19:09:25 +0000 Subject: [PATCH] vanitygaps added --- config.def.h | 41 +- dwm.c | 58 +- patches/dwm-cfacts-vanitygaps-6.4_combo.diff | 1018 ++++++++++++++++++ vanitygaps.c | 822 ++++++++++++++ 4 files changed, 1909 insertions(+), 30 deletions(-) create mode 100644 patches/dwm-cfacts-vanitygaps-6.4_combo.diff create mode 100644 vanitygaps.c diff --git a/config.def.h b/config.def.h index 9efa774..357dc6f 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" }; @@ -37,11 +42,26 @@ static const int nmaster = 1; /* number of clients in master area */ static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ +#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,7 +91,26 @@ static const Key keys[] = { { MODKEY, XK_d, incnmaster, {.i = -1 } }, { MODKEY, XK_h, setmfact, {.f = -0.05} }, { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, + { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, + { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, { 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 67c6b2b..2a623f7 100644 --- a/dwm.c +++ b/dwm.c @@ -87,6 +87,7 @@ typedef struct Client Client; struct Client { char name[256]; float mina, maxa; + float cfact; int x, y, w, h; int oldx, oldy, oldw, oldh; int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; @@ -119,6 +120,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]; @@ -201,6 +206,7 @@ static void setclientstate(Client *c, long state); static void setfocus(Client *c); static void setfullscreen(Client *c, int fullscreen); static void setlayout(const Arg *arg); +static void setcfact(const Arg *arg); static void setmfact(const Arg *arg); static void setup(void); static void seturgent(Client *c, int urg); @@ -208,7 +214,6 @@ static void showhide(Client *c); static void spawn(const Arg *arg); static void tag(const Arg *arg); static void tagmon(const Arg *arg); -static void tile(Monitor *m); static void togglebar(const Arg *arg); static void togglefloating(const Arg *arg); static void toggletag(const Arg *arg); @@ -641,6 +646,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); @@ -1043,6 +1052,7 @@ manage(Window w, XWindowAttributes *wa) c->w = c->oldw = wa->width; c->h = c->oldh = wa->height; c->oldbw = wa->border_width; + c->cfact = 1.0; updatetitle(c); if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { @@ -1521,6 +1531,24 @@ setlayout(const Arg *arg) drawbar(selmon); } +void +setcfact(const Arg *arg) { + float f; + Client *c; + + c = selmon->sel; + + if(!arg || !c || !selmon->lt[selmon->sellt]->arrange) + return; + f = arg->f + c->cfact; + if(arg->f == 0.0) + f = 1.0; + else if(f < 0.25 || f > 4.0) + return; + c->cfact = f; + arrange(selmon); +} + /* arg > 1.0 will set mfact absolutely */ void setmfact(const Arg *arg) @@ -1684,34 +1712,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); - 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) { diff --git a/patches/dwm-cfacts-vanitygaps-6.4_combo.diff b/patches/dwm-cfacts-vanitygaps-6.4_combo.diff new file mode 100644 index 0000000..db2cc14 --- /dev/null +++ b/patches/dwm-cfacts-vanitygaps-6.4_combo.diff @@ -0,0 +1,1018 @@ +diff --git a/config.def.h b/config.def.h +index 9efa774..357dc6f 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" }; +@@ -37,11 +42,26 @@ static const int nmaster = 1; /* number of clients in master area */ + static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ + static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ + ++#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,7 +91,26 @@ static const Key keys[] = { + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, ++ { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, ++ { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, ++ { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, + { 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 f1d86b2..5bbd733 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -87,6 +87,7 @@ typedef struct Client Client; + struct Client { + char name[256]; + float mina, maxa; ++ float cfact; + int x, y, w, h; + int oldx, oldy, oldw, oldh; + int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; +@@ -119,6 +120,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]; +@@ -201,6 +206,7 @@ static void setclientstate(Client *c, long state); + static void setfocus(Client *c); + static void setfullscreen(Client *c, int fullscreen); + static void setlayout(const Arg *arg); ++static void setcfact(const Arg *arg); + static void setmfact(const Arg *arg); + static void setup(void); + static void seturgent(Client *c, int urg); +@@ -208,7 +214,6 @@ static void showhide(Client *c); + static void spawn(const Arg *arg); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); +-static void tile(Monitor *m); + static void togglebar(const Arg *arg); + static void togglefloating(const Arg *arg); + static void toggletag(const Arg *arg); +@@ -641,6 +646,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); +@@ -1043,6 +1052,7 @@ manage(Window w, XWindowAttributes *wa) + c->w = c->oldw = wa->width; + c->h = c->oldh = wa->height; + c->oldbw = wa->border_width; ++ c->cfact = 1.0; + + updatetitle(c); + if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { +@@ -1521,6 +1531,24 @@ setlayout(const Arg *arg) + drawbar(selmon); + } + ++void ++setcfact(const Arg *arg) { ++ float f; ++ Client *c; ++ ++ c = selmon->sel; ++ ++ if(!arg || !c || !selmon->lt[selmon->sellt]->arrange) ++ return; ++ f = arg->f + c->cfact; ++ if(arg->f == 0.0) ++ f = 1.0; ++ else if(f < 0.25 || f > 4.0) ++ return; ++ c->cfact = f; ++ arrange(selmon); ++} ++ + /* arg > 1.0 will set mfact absolutely */ + void + setmfact(const Arg *arg) +@@ -1684,34 +1712,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); +- 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) + { +diff --git a/vanitygaps.c b/vanitygaps.c +new file mode 100644 +index 0000000..1a816b6 +--- /dev/null ++++ b/vanitygaps.c +@@ -0,0 +1,822 @@ ++/* 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 = 0, sfacts = 0; ++ int mtotal = 0, stotal = 0; ++ Client *c; ++ ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) ++ if (n < m->nmaster) ++ mfacts += c->cfact; ++ else ++ sfacts += c->cfact; ++ ++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) ++ if (n < m->nmaster) ++ mtotal += msize * (c->cfact / mfacts); ++ else ++ stotal += ssize * (c->cfact / sfacts); ++ ++ *mf = mfacts; // total factor of master area ++ *sf = sfacts; // total factor of stack area ++ *mr = msize - mtotal; // the remainder (rest) of pixels after a cfacts master split ++ *sr = ssize - stotal; // the remainder (rest) of pixels after a cfacts 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 * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); ++ mx += WIDTH(c) + iv; ++ } else { ++ resize(c, sx, sy, sw * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 += c->cfact; ++ else if ((n - m->nmaster) % 2) ++ lfacts += c->cfact; // total factor of left hand stack area ++ else ++ rfacts += c->cfact; // 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 * (c->cfact / mfacts); ++ else if ((n - m->nmaster) % 2) ++ ltotal += lh * (c->cfact / lfacts); ++ else ++ rtotal += rh * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 = 0, sfacts = 0; ++ int mrest, srest, mtotal = 0, stotal = 0; ++ ++ /* 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); ++ } ++ ++ /* calculate facts */ ++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) ++ if (i < ntop) ++ mfacts += c->cfact; ++ else ++ sfacts += c->cfact; ++ ++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) ++ if (i < ntop) ++ mtotal += mh * (c->cfact / mfacts); ++ else ++ stotal += sw * (c->cfact / sfacts); ++ ++ mrest = mh - mtotal; ++ srest = sw - stotal; ++ ++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) ++ if (i < ntop) { ++ resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); ++ mx += WIDTH(c) + iv; ++ } else { ++ resize(c, sx, sy, sw * (c->cfact / 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 * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); ++ my += HEIGHT(c) + ih; ++ } else { ++ resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); ++ sy += HEIGHT(c) + ih; ++ } ++} +\ No newline at end of file diff --git a/vanitygaps.c b/vanitygaps.c new file mode 100644 index 0000000..1a816b6 --- /dev/null +++ b/vanitygaps.c @@ -0,0 +1,822 @@ +/* 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 = 0, sfacts = 0; + int mtotal = 0, stotal = 0; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) + if (n < m->nmaster) + mfacts += c->cfact; + else + sfacts += c->cfact; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) + if (n < m->nmaster) + mtotal += msize * (c->cfact / mfacts); + else + stotal += ssize * (c->cfact / sfacts); + + *mf = mfacts; // total factor of master area + *sf = sfacts; // total factor of stack area + *mr = msize - mtotal; // the remainder (rest) of pixels after a cfacts master split + *sr = ssize - stotal; // the remainder (rest) of pixels after a cfacts 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 * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c) + iv; + } else { + resize(c, sx, sy, sw * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 += c->cfact; + else if ((n - m->nmaster) % 2) + lfacts += c->cfact; // total factor of left hand stack area + else + rfacts += c->cfact; // 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 * (c->cfact / mfacts); + else if ((n - m->nmaster) % 2) + ltotal += lh * (c->cfact / lfacts); + else + rtotal += rh * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 * (c->cfact / 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 = 0, sfacts = 0; + int mrest, srest, mtotal = 0, stotal = 0; + + /* 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); + } + + /* calculate facts */ + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < ntop) + mfacts += c->cfact; + else + sfacts += c->cfact; + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < ntop) + mtotal += mh * (c->cfact / mfacts); + else + stotal += sw * (c->cfact / sfacts); + + mrest = mh - mtotal; + srest = sw - stotal; + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < ntop) { + resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c) + iv; + } else { + resize(c, sx, sy, sw * (c->cfact / 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 * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); + my += HEIGHT(c) + ih; + } else { + resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); + sy += HEIGHT(c) + ih; + } +} \ No newline at end of file