dwm-vanitygaps-6.2.diff (26032B) - raw


      1 From 9709d08daa290c8c7319571cd9e6ef4ec40e7683 Mon Sep 17 00:00:00 2001
      2 From: bakkeby <bakkeby@gmail.com>
      3 Date: Wed, 6 May 2020 17:21:25 +0200
      4 Subject: [PATCH] vanitygaps - adds gaps to layouts
      5 
      6 This patch differentiates between inner and outer gaps as well as
      7 horizontal and vertical gaps.
      8 
      9 The logic of these layouts also aims to be pixel perfect by ensuring
     10 an even split of the available space and re-distributing the remainder
     11 among the available clients.
     12 ---
     13  config.def.h |  38 ++-
     14  dwm.c        |  35 +--
     15  vanitygaps.c | 809 +++++++++++++++++++++++++++++++++++++++++++++++++++
     16  3 files changed, 854 insertions(+), 28 deletions(-)
     17  create mode 100644 vanitygaps.c
     18 
     19 diff --git a/config.def.h b/config.def.h
     20 index 1c0b587..a886863 100644
     21 --- a/config.def.h
     22 +++ b/config.def.h
     23 @@ -3,6 +3,11 @@
     24  /* appearance */
     25  static const unsigned int borderpx  = 1;        /* border pixel of windows */
     26  static const unsigned int snap      = 32;       /* snap pixel */
     27 +static const unsigned int gappih    = 20;       /* horiz inner gap between windows */
     28 +static const unsigned int gappiv    = 10;       /* vert inner gap between windows */
     29 +static const unsigned int gappoh    = 10;       /* horiz outer gap between windows and screen edge */
     30 +static const unsigned int gappov    = 30;       /* vert outer gap between windows and screen edge */
     31 +static       int smartgaps          = 0;        /* 1 means no outer gap when there is only one window */
     32  static const int showbar            = 1;        /* 0 means no bar */
     33  static const int topbar             = 1;        /* 0 means bottom bar */
     34  static const char *fonts[]          = { "monospace:size=10" };
     35 @@ -36,11 +41,26 @@ static const float mfact     = 0.55; /* factor of master area size [0.05..0.95]
     36  static const int nmaster     = 1;    /* number of clients in master area */
     37  static const int resizehints = 1;    /* 1 means respect size hints in tiled resizals */
     38  
     39 +#define FORCE_VSPLIT 1  /* nrowgrid layout: force two clients to always split vertically */
     40 +#include "vanitygaps.c"
     41 +
     42  static const Layout layouts[] = {
     43  	/* symbol     arrange function */
     44  	{ "[]=",      tile },    /* first entry is default */
     45 -	{ "><>",      NULL },    /* no layout function means floating behavior */
     46  	{ "[M]",      monocle },
     47 +	{ "[@]",      spiral },
     48 +	{ "[\\]",     dwindle },
     49 +	{ "H[]",      deck },
     50 +	{ "TTT",      bstack },
     51 +	{ "===",      bstackhoriz },
     52 +	{ "HHH",      grid },
     53 +	{ "###",      nrowgrid },
     54 +	{ "---",      horizgrid },
     55 +	{ ":::",      gaplessgrid },
     56 +	{ "|M|",      centeredmaster },
     57 +	{ ">M>",      centeredfloatingmaster },
     58 +	{ "><>",      NULL },    /* no layout function means floating behavior */
     59 +	{ NULL,       NULL },
     60  };
     61  
     62  /* key definitions */
     63 @@ -71,6 +91,22 @@ static Key keys[] = {
     64  	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
     65  	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
     66  	{ MODKEY,                       XK_Return, zoom,           {0} },
     67 +	{ MODKEY|Mod4Mask,              XK_u,      incrgaps,       {.i = +1 } },
     68 +	{ MODKEY|Mod4Mask|ShiftMask,    XK_u,      incrgaps,       {.i = -1 } },
     69 +	{ MODKEY|Mod4Mask,              XK_i,      incrigaps,      {.i = +1 } },
     70 +	{ MODKEY|Mod4Mask|ShiftMask,    XK_i,      incrigaps,      {.i = -1 } },
     71 +	{ MODKEY|Mod4Mask,              XK_o,      incrogaps,      {.i = +1 } },
     72 +	{ MODKEY|Mod4Mask|ShiftMask,    XK_o,      incrogaps,      {.i = -1 } },
     73 +	{ MODKEY|Mod4Mask,              XK_6,      incrihgaps,     {.i = +1 } },
     74 +	{ MODKEY|Mod4Mask|ShiftMask,    XK_6,      incrihgaps,     {.i = -1 } },
     75 +	{ MODKEY|Mod4Mask,              XK_7,      incrivgaps,     {.i = +1 } },
     76 +	{ MODKEY|Mod4Mask|ShiftMask,    XK_7,      incrivgaps,     {.i = -1 } },
     77 +	{ MODKEY|Mod4Mask,              XK_8,      incrohgaps,     {.i = +1 } },
     78 +	{ MODKEY|Mod4Mask|ShiftMask,    XK_8,      incrohgaps,     {.i = -1 } },
     79 +	{ MODKEY|Mod4Mask,              XK_9,      incrovgaps,     {.i = +1 } },
     80 +	{ MODKEY|Mod4Mask|ShiftMask,    XK_9,      incrovgaps,     {.i = -1 } },
     81 +	{ MODKEY|Mod4Mask,              XK_0,      togglegaps,     {0} },
     82 +	{ MODKEY|Mod4Mask|ShiftMask,    XK_0,      defaultgaps,    {0} },
     83  	{ MODKEY,                       XK_Tab,    view,           {0} },
     84  	{ MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
     85  	{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
     86 diff --git a/dwm.c b/dwm.c
     87 index 4465af1..c3b2d82 100644
     88 --- a/dwm.c
     89 +++ b/dwm.c
     90 @@ -119,6 +119,10 @@ struct Monitor {
     91  	int by;               /* bar geometry */
     92  	int mx, my, mw, mh;   /* screen size */
     93  	int wx, wy, ww, wh;   /* window area  */
     94 +	int gappih;           /* horizontal gap between windows */
     95 +	int gappiv;           /* vertical gap between windows */
     96 +	int gappoh;           /* horizontal outer gaps */
     97 +	int gappov;           /* vertical outer gaps */
     98  	unsigned int seltags;
     99  	unsigned int sellt;
    100  	unsigned int tagset[2];
    101 @@ -208,7 +212,6 @@ static void sigchld(int unused);
    102  static void spawn(const Arg *arg);
    103  static void tag(const Arg *arg);
    104  static void tagmon(const Arg *arg);
    105 -static void tile(Monitor *);
    106  static void togglebar(const Arg *arg);
    107  static void togglefloating(const Arg *arg);
    108  static void toggletag(const Arg *arg);
    109 @@ -638,6 +641,10 @@ createmon(void)
    110  	m->nmaster = nmaster;
    111  	m->showbar = showbar;
    112  	m->topbar = topbar;
    113 +	m->gappih = gappih;
    114 +	m->gappiv = gappiv;
    115 +	m->gappoh = gappoh;
    116 +	m->gappov = gappov;
    117  	m->lt[0] = &layouts[0];
    118  	m->lt[1] = &layouts[1 % LENGTH(layouts)];
    119  	strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
    120 @@ -1670,32 +1677,6 @@ tagmon(const Arg *arg)
    121  	sendmon(selmon->sel, dirtomon(arg->i));
    122  }
    123  
    124 -void
    125 -tile(Monitor *m)
    126 -{
    127 -	unsigned int i, n, h, mw, my, ty;
    128 -	Client *c;
    129 -
    130 -	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
    131 -	if (n == 0)
    132 -		return;
    133 -
    134 -	if (n > m->nmaster)
    135 -		mw = m->nmaster ? m->ww * m->mfact : 0;
    136 -	else
    137 -		mw = m->ww;
    138 -	for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    139 -		if (i < m->nmaster) {
    140 -			h = (m->wh - my) / (MIN(n, m->nmaster) - i);
    141 -			resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
    142 -			my += HEIGHT(c);
    143 -		} else {
    144 -			h = (m->wh - ty) / (n - i);
    145 -			resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
    146 -			ty += HEIGHT(c);
    147 -		}
    148 -}
    149 -
    150  void
    151  togglebar(const Arg *arg)
    152  {
    153 diff --git a/vanitygaps.c b/vanitygaps.c
    154 new file mode 100644
    155 index 0000000..3f31593
    156 --- /dev/null
    157 +++ b/vanitygaps.c
    158 @@ -0,0 +1,809 @@
    159 +/* Key binding functions */
    160 +static void defaultgaps(const Arg *arg);
    161 +static void incrgaps(const Arg *arg);
    162 +static void incrigaps(const Arg *arg);
    163 +static void incrogaps(const Arg *arg);
    164 +static void incrohgaps(const Arg *arg);
    165 +static void incrovgaps(const Arg *arg);
    166 +static void incrihgaps(const Arg *arg);
    167 +static void incrivgaps(const Arg *arg);
    168 +static void togglegaps(const Arg *arg);
    169 +/* Layouts (delete the ones you do not need) */
    170 +static void bstack(Monitor *m);
    171 +static void bstackhoriz(Monitor *m);
    172 +static void centeredmaster(Monitor *m);
    173 +static void centeredfloatingmaster(Monitor *m);
    174 +static void deck(Monitor *m);
    175 +static void dwindle(Monitor *m);
    176 +static void fibonacci(Monitor *m, int s);
    177 +static void grid(Monitor *m);
    178 +static void nrowgrid(Monitor *m);
    179 +static void spiral(Monitor *m);
    180 +static void tile(Monitor *m);
    181 +/* Internals */
    182 +static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc);
    183 +static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr);
    184 +static void setgaps(int oh, int ov, int ih, int iv);
    185 +
    186 +/* Settings */
    187 +#if !PERTAG_PATCH
    188 +static int enablegaps = 1;
    189 +#endif // PERTAG_PATCH
    190 +
    191 +void
    192 +setgaps(int oh, int ov, int ih, int iv)
    193 +{
    194 +	if (oh < 0) oh = 0;
    195 +	if (ov < 0) ov = 0;
    196 +	if (ih < 0) ih = 0;
    197 +	if (iv < 0) iv = 0;
    198 +
    199 +	selmon->gappoh = oh;
    200 +	selmon->gappov = ov;
    201 +	selmon->gappih = ih;
    202 +	selmon->gappiv = iv;
    203 +	arrange(selmon);
    204 +}
    205 +
    206 +void
    207 +togglegaps(const Arg *arg)
    208 +{
    209 +	#if PERTAG_PATCH
    210 +	selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag];
    211 +	#else
    212 +	enablegaps = !enablegaps;
    213 +	#endif // PERTAG_PATCH
    214 +	arrange(NULL);
    215 +}
    216 +
    217 +void
    218 +defaultgaps(const Arg *arg)
    219 +{
    220 +	setgaps(gappoh, gappov, gappih, gappiv);
    221 +}
    222 +
    223 +void
    224 +incrgaps(const Arg *arg)
    225 +{
    226 +	setgaps(
    227 +		selmon->gappoh + arg->i,
    228 +		selmon->gappov + arg->i,
    229 +		selmon->gappih + arg->i,
    230 +		selmon->gappiv + arg->i
    231 +	);
    232 +}
    233 +
    234 +void
    235 +incrigaps(const Arg *arg)
    236 +{
    237 +	setgaps(
    238 +		selmon->gappoh,
    239 +		selmon->gappov,
    240 +		selmon->gappih + arg->i,
    241 +		selmon->gappiv + arg->i
    242 +	);
    243 +}
    244 +
    245 +void
    246 +incrogaps(const Arg *arg)
    247 +{
    248 +	setgaps(
    249 +		selmon->gappoh + arg->i,
    250 +		selmon->gappov + arg->i,
    251 +		selmon->gappih,
    252 +		selmon->gappiv
    253 +	);
    254 +}
    255 +
    256 +void
    257 +incrohgaps(const Arg *arg)
    258 +{
    259 +	setgaps(
    260 +		selmon->gappoh + arg->i,
    261 +		selmon->gappov,
    262 +		selmon->gappih,
    263 +		selmon->gappiv
    264 +	);
    265 +}
    266 +
    267 +void
    268 +incrovgaps(const Arg *arg)
    269 +{
    270 +	setgaps(
    271 +		selmon->gappoh,
    272 +		selmon->gappov + arg->i,
    273 +		selmon->gappih,
    274 +		selmon->gappiv
    275 +	);
    276 +}
    277 +
    278 +void
    279 +incrihgaps(const Arg *arg)
    280 +{
    281 +	setgaps(
    282 +		selmon->gappoh,
    283 +		selmon->gappov,
    284 +		selmon->gappih + arg->i,
    285 +		selmon->gappiv
    286 +	);
    287 +}
    288 +
    289 +void
    290 +incrivgaps(const Arg *arg)
    291 +{
    292 +	setgaps(
    293 +		selmon->gappoh,
    294 +		selmon->gappov,
    295 +		selmon->gappih,
    296 +		selmon->gappiv + arg->i
    297 +	);
    298 +}
    299 +
    300 +void
    301 +getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc)
    302 +{
    303 +	unsigned int n, oe, ie;
    304 +	#if PERTAG_PATCH
    305 +	oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag];
    306 +	#else
    307 +	oe = ie = enablegaps;
    308 +	#endif // PERTAG_PATCH
    309 +	Client *c;
    310 +
    311 +	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
    312 +	if (smartgaps && n == 1) {
    313 +		oe = 0; // outer gaps disabled when only one client
    314 +	}
    315 +
    316 +	*oh = m->gappoh*oe; // outer horizontal gap
    317 +	*ov = m->gappov*oe; // outer vertical gap
    318 +	*ih = m->gappih*ie; // inner horizontal gap
    319 +	*iv = m->gappiv*ie; // inner vertical gap
    320 +	*nc = n;            // number of clients
    321 +}
    322 +
    323 +void
    324 +getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
    325 +{
    326 +	unsigned int n;
    327 +	float mfacts, sfacts;
    328 +	int mtotal = 0, stotal = 0;
    329 +	Client *c;
    330 +
    331 +	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
    332 +	mfacts = MIN(n, m->nmaster);
    333 +	sfacts = n - m->nmaster;
    334 +
    335 +	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
    336 +		if (n < m->nmaster)
    337 +			mtotal += msize / mfacts;
    338 +		else
    339 +			stotal += ssize / sfacts;
    340 +
    341 +	*mf = mfacts; // total factor of master area
    342 +	*sf = sfacts; // total factor of stack area
    343 +	*mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
    344 +	*sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
    345 +}
    346 +
    347 +/***
    348 + * Layouts
    349 + */
    350 +
    351 +/*
    352 + * Bottomstack layout + gaps
    353 + * https://dwm.suckless.org/patches/bottomstack/
    354 + */
    355 +static void
    356 +bstack(Monitor *m)
    357 +{
    358 +	unsigned int i, n;
    359 +	int oh, ov, ih, iv;
    360 +	int mx = 0, my = 0, mh = 0, mw = 0;
    361 +	int sx = 0, sy = 0, sh = 0, sw = 0;
    362 +	float mfacts, sfacts;
    363 +	int mrest, srest;
    364 +	Client *c;
    365 +
    366 +	getgaps(m, &oh, &ov, &ih, &iv, &n);
    367 +	if (n == 0)
    368 +		return;
    369 +
    370 +	sx = mx = m->wx + ov;
    371 +	sy = my = m->wy + oh;
    372 +	sh = mh = m->wh - 2*oh;
    373 +	mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
    374 +	sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
    375 +
    376 +	if (m->nmaster && n > m->nmaster) {
    377 +		sh = (mh - ih) * (1 - m->mfact);
    378 +		mh = mh - ih - sh;
    379 +		sx = mx;
    380 +		sy = my + mh + ih;
    381 +	}
    382 +
    383 +	getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
    384 +
    385 +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
    386 +		if (i < m->nmaster) {
    387 +			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
    388 +			mx += WIDTH(c) + iv;
    389 +		} else {
    390 +			resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
    391 +			sx += WIDTH(c) + iv;
    392 +		}
    393 +	}
    394 +}
    395 +
    396 +static void
    397 +bstackhoriz(Monitor *m)
    398 +{
    399 +	unsigned int i, n;
    400 +	int oh, ov, ih, iv;
    401 +	int mx = 0, my = 0, mh = 0, mw = 0;
    402 +	int sx = 0, sy = 0, sh = 0, sw = 0;
    403 +	float mfacts, sfacts;
    404 +	int mrest, srest;
    405 +	Client *c;
    406 +
    407 +	getgaps(m, &oh, &ov, &ih, &iv, &n);
    408 +	if (n == 0)
    409 +		return;
    410 +
    411 +	sx = mx = m->wx + ov;
    412 +	sy = my = m->wy + oh;
    413 +	mh = m->wh - 2*oh;
    414 +	sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
    415 +	mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
    416 +	sw = m->ww - 2*ov;
    417 +
    418 +	if (m->nmaster && n > m->nmaster) {
    419 +		sh = (mh - ih) * (1 - m->mfact);
    420 +		mh = mh - ih - sh;
    421 +		sy = my + mh + ih;
    422 +		sh = m->wh - mh - 2*oh - ih * (n - m->nmaster);
    423 +	}
    424 +
    425 +	getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest);
    426 +
    427 +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
    428 +		if (i < m->nmaster) {
    429 +			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
    430 +			mx += WIDTH(c) + iv;
    431 +		} else {
    432 +			resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
    433 +			sy += HEIGHT(c) + ih;
    434 +		}
    435 +	}
    436 +}
    437 +
    438 +/*
    439 + * Centred master layout + gaps
    440 + * https://dwm.suckless.org/patches/centeredmaster/
    441 + */
    442 +void
    443 +centeredmaster(Monitor *m)
    444 +{
    445 +	unsigned int i, n;
    446 +	int oh, ov, ih, iv;
    447 +	int mx = 0, my = 0, mh = 0, mw = 0;
    448 +	int lx = 0, ly = 0, lw = 0, lh = 0;
    449 +	int rx = 0, ry = 0, rw = 0, rh = 0;
    450 +	float mfacts = 0, lfacts = 0, rfacts = 0;
    451 +	int mtotal = 0, ltotal = 0, rtotal = 0;
    452 +	int mrest = 0, lrest = 0, rrest = 0;
    453 +	Client *c;
    454 +
    455 +	getgaps(m, &oh, &ov, &ih, &iv, &n);
    456 +	if (n == 0)
    457 +		return;
    458 +
    459 +	/* initialize areas */
    460 +	mx = m->wx + ov;
    461 +	my = m->wy + oh;
    462 +	mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
    463 +	mw = m->ww - 2*ov;
    464 +	lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
    465 +	rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
    466 +
    467 +	if (m->nmaster && n > m->nmaster) {
    468 +		/* go mfact box in the center if more than nmaster clients */
    469 +		if (n - m->nmaster > 1) {
    470 +			/* ||<-S->|<---M--->|<-S->|| */
    471 +			mw = (m->ww - 2*ov - 2*iv) * m->mfact;
    472 +			lw = (m->ww - mw - 2*ov - 2*iv) / 2;
    473 +			rw = (m->ww - mw - 2*ov - 2*iv) - lw;
    474 +			mx += lw + iv;
    475 +		} else {
    476 +			/* ||<---M--->|<-S->|| */
    477 +			mw = (mw - iv) * m->mfact;
    478 +			lw = 0;
    479 +			rw = m->ww - mw - iv - 2*ov;
    480 +		}
    481 +		lx = m->wx + ov;
    482 +		ly = m->wy + oh;
    483 +		rx = mx + mw + iv;
    484 +		ry = m->wy + oh;
    485 +	}
    486 +
    487 +	/* calculate facts */
    488 +	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
    489 +		if (!m->nmaster || n < m->nmaster)
    490 +			mfacts += 1;
    491 +		else if ((n - m->nmaster) % 2)
    492 +			lfacts += 1; // total factor of left hand stack area
    493 +		else
    494 +			rfacts += 1; // total factor of right hand stack area
    495 +	}
    496 +
    497 +	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
    498 +		if (!m->nmaster || n < m->nmaster)
    499 +			mtotal += mh / mfacts;
    500 +		else if ((n - m->nmaster) % 2)
    501 +			ltotal += lh / lfacts;
    502 +		else
    503 +			rtotal += rh / rfacts;
    504 +
    505 +	mrest = mh - mtotal;
    506 +	lrest = lh - ltotal;
    507 +	rrest = rh - rtotal;
    508 +
    509 +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
    510 +		if (!m->nmaster || i < m->nmaster) {
    511 +			/* nmaster clients are stacked vertically, in the center of the screen */
    512 +			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
    513 +			my += HEIGHT(c) + ih;
    514 +		} else {
    515 +			/* stack clients are stacked vertically */
    516 +			if ((i - m->nmaster) % 2 ) {
    517 +				resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
    518 +				ly += HEIGHT(c) + ih;
    519 +			} else {
    520 +				resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
    521 +				ry += HEIGHT(c) + ih;
    522 +			}
    523 +		}
    524 +	}
    525 +}
    526 +
    527 +void
    528 +centeredfloatingmaster(Monitor *m)
    529 +{
    530 +	unsigned int i, n;
    531 +	float mfacts, sfacts;
    532 +	float mivf = 1.0; // master inner vertical gap factor
    533 +	int oh, ov, ih, iv, mrest, srest;
    534 +	int mx = 0, my = 0, mh = 0, mw = 0;
    535 +	int sx = 0, sy = 0, sh = 0, sw = 0;
    536 +	Client *c;
    537 +
    538 +	getgaps(m, &oh, &ov, &ih, &iv, &n);
    539 +	if (n == 0)
    540 +		return;
    541 +
    542 +	sx = mx = m->wx + ov;
    543 +	sy = my = m->wy + oh;
    544 +	sh = mh = m->wh - 2*oh;
    545 +	mw = m->ww - 2*ov - iv*(n - 1);
    546 +	sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
    547 +
    548 +	if (m->nmaster && n > m->nmaster) {
    549 +		mivf = 0.8;
    550 +		/* go mfact box in the center if more than nmaster clients */
    551 +		if (m->ww > m->wh) {
    552 +			mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
    553 +			mh = m->wh * 0.9;
    554 +		} else {
    555 +			mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
    556 +			mh = m->wh * m->mfact;
    557 +		}
    558 +		mx = m->wx + (m->ww - mw) / 2;
    559 +		my = m->wy + (m->wh - mh - 2*oh) / 2;
    560 +
    561 +		sx = m->wx + ov;
    562 +		sy = m->wy + oh;
    563 +		sh = m->wh - 2*oh;
    564 +	}
    565 +
    566 +	getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
    567 +
    568 +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    569 +		if (i < m->nmaster) {
    570 +			/* nmaster clients are stacked horizontally, in the center of the screen */
    571 +			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
    572 +			mx += WIDTH(c) + iv*mivf;
    573 +		} else {
    574 +			/* stack clients are stacked horizontally */
    575 +			resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
    576 +			sx += WIDTH(c) + iv;
    577 +		}
    578 +}
    579 +
    580 +/*
    581 + * Deck layout + gaps
    582 + * https://dwm.suckless.org/patches/deck/
    583 + */
    584 +void
    585 +deck(Monitor *m)
    586 +{
    587 +	unsigned int i, n;
    588 +	int oh, ov, ih, iv;
    589 +	int mx = 0, my = 0, mh = 0, mw = 0;
    590 +	int sx = 0, sy = 0, sh = 0, sw = 0;
    591 +	float mfacts, sfacts;
    592 +	int mrest, srest;
    593 +	Client *c;
    594 +
    595 +	getgaps(m, &oh, &ov, &ih, &iv, &n);
    596 +	if (n == 0)
    597 +		return;
    598 +
    599 +	sx = mx = m->wx + ov;
    600 +	sy = my = m->wy + oh;
    601 +	sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
    602 +	sw = mw = m->ww - 2*ov;
    603 +
    604 +	if (m->nmaster && n > m->nmaster) {
    605 +		sw = (mw - iv) * (1 - m->mfact);
    606 +		mw = mw - iv - sw;
    607 +		sx = mx + mw + iv;
    608 +		sh = m->wh - 2*oh;
    609 +	}
    610 +
    611 +	getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
    612 +
    613 +	if (n - m->nmaster > 0) /* override layout symbol */
    614 +		snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster);
    615 +
    616 +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    617 +		if (i < m->nmaster) {
    618 +			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
    619 +			my += HEIGHT(c) + ih;
    620 +		} else {
    621 +			resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
    622 +		}
    623 +}
    624 +
    625 +/*
    626 + * Fibonacci layout + gaps
    627 + * https://dwm.suckless.org/patches/fibonacci/
    628 + */
    629 +void
    630 +fibonacci(Monitor *m, int s)
    631 +{
    632 +	unsigned int i, n;
    633 +	int nx, ny, nw, nh;
    634 +	int oh, ov, ih, iv;
    635 +	int nv, hrest = 0, wrest = 0, r = 1;
    636 +	Client *c;
    637 +
    638 +	getgaps(m, &oh, &ov, &ih, &iv, &n);
    639 +	if (n == 0)
    640 +		return;
    641 +
    642 +	nx = m->wx + ov;
    643 +	ny = m->wy + oh;
    644 +	nw = m->ww - 2*ov;
    645 +	nh = m->wh - 2*oh;
    646 +
    647 +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
    648 +		if (r) {
    649 +			if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw))
    650 +			   || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) {
    651 +				r = 0;
    652 +			}
    653 +			if (r && i < n - 1) {
    654 +				if (i % 2) {
    655 +					nv = (nh - ih) / 2;
    656 +					hrest = nh - 2*nv - ih;
    657 +					nh = nv;
    658 +				} else {
    659 +					nv = (nw - iv) / 2;
    660 +					wrest = nw - 2*nv - iv;
    661 +					nw = nv;
    662 +				}
    663 +
    664 +				if ((i % 4) == 2 && !s)
    665 +					nx += nw + iv;
    666 +				else if ((i % 4) == 3 && !s)
    667 +					ny += nh + ih;
    668 +			}
    669 +
    670 +			if ((i % 4) == 0) {
    671 +				if (s) {
    672 +					ny += nh + ih;
    673 +					nh += hrest;
    674 +				}
    675 +				else {
    676 +					nh -= hrest;
    677 +					ny -= nh + ih;
    678 +				}
    679 +			}
    680 +			else if ((i % 4) == 1) {
    681 +				nx += nw + iv;
    682 +				nw += wrest;
    683 +			}
    684 +			else if ((i % 4) == 2) {
    685 +				ny += nh + ih;
    686 +				nh += hrest;
    687 +				if (i < n - 1)
    688 +					nw += wrest;
    689 +			}
    690 +			else if ((i % 4) == 3) {
    691 +				if (s) {
    692 +					nx += nw + iv;
    693 +					nw -= wrest;
    694 +				} else {
    695 +					nw -= wrest;
    696 +					nx -= nw + iv;
    697 +					nh += hrest;
    698 +				}
    699 +			}
    700 +			if (i == 0)	{
    701 +				if (n != 1) {
    702 +					nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact);
    703 +					wrest = 0;
    704 +				}
    705 +				ny = m->wy + oh;
    706 +			}
    707 +			else if (i == 1)
    708 +				nw = m->ww - nw - iv - 2*ov;
    709 +			i++;
    710 +		}
    711 +
    712 +		resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
    713 +	}
    714 +}
    715 +
    716 +void
    717 +dwindle(Monitor *m)
    718 +{
    719 +	fibonacci(m, 1);
    720 +}
    721 +
    722 +void
    723 +spiral(Monitor *m)
    724 +{
    725 +	fibonacci(m, 0);
    726 +}
    727 +
    728 +/*
    729 + * Gappless grid layout + gaps (ironically)
    730 + * https://dwm.suckless.org/patches/gaplessgrid/
    731 + */
    732 +void
    733 +gaplessgrid(Monitor *m)
    734 +{
    735 +	unsigned int i, n;
    736 +	int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
    737 +	int oh, ov, ih, iv;
    738 +	Client *c;
    739 +
    740 +	getgaps(m, &oh, &ov, &ih, &iv, &n);
    741 +	if (n == 0)
    742 +		return;
    743 +
    744 +	/* grid dimensions */
    745 +	for (cols = 0; cols <= n/2; cols++)
    746 +		if (cols*cols >= n)
    747 +			break;
    748 +	if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
    749 +		cols = 2;
    750 +	rows = n/cols;
    751 +	cn = rn = 0; // reset column no, row no, client count
    752 +
    753 +	ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
    754 +	cw = (m->ww - 2*ov - iv * (cols - 1)) / cols;
    755 +	rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
    756 +	crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
    757 +	x = m->wx + ov;
    758 +	y = m->wy + oh;
    759 +
    760 +	for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) {
    761 +		if (i/rows + 1 > cols - n%cols) {
    762 +			rows = n/cols + 1;
    763 +			ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
    764 +			rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
    765 +		}
    766 +		resize(c,
    767 +			x,
    768 +			y + rn*(ch + ih) + MIN(rn, rrest),
    769 +			cw + (cn < crest ? 1 : 0) - 2*c->bw,
    770 +			ch + (rn < rrest ? 1 : 0) - 2*c->bw,
    771 +			0);
    772 +		rn++;
    773 +		if (rn >= rows) {
    774 +			rn = 0;
    775 +			x += cw + ih + (cn < crest ? 1 : 0);
    776 +			cn++;
    777 +		}
    778 +	}
    779 +}
    780 +
    781 +/*
    782 + * Gridmode layout + gaps
    783 + * https://dwm.suckless.org/patches/gridmode/
    784 + */
    785 +void
    786 +grid(Monitor *m)
    787 +{
    788 +	unsigned int i, n;
    789 +	int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows;
    790 +	int oh, ov, ih, iv;
    791 +	Client *c;
    792 +
    793 +	getgaps(m, &oh, &ov, &ih, &iv, &n);
    794 +
    795 +	/* grid dimensions */
    796 +	for (rows = 0; rows <= n/2; rows++)
    797 +		if (rows*rows >= n)
    798 +			break;
    799 +	cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
    800 +
    801 +	/* window geoms (cell height/width) */
    802 +	ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1);
    803 +	cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1);
    804 +	chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
    805 +	cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
    806 +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
    807 +		cc = i / rows;
    808 +		cr = i % rows;
    809 +		cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest);
    810 +		cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest);
    811 +		resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False);
    812 +	}
    813 +}
    814 +
    815 +/*
    816 + * Horizontal grid layout + gaps
    817 + * https://dwm.suckless.org/patches/horizgrid/
    818 + */
    819 +void
    820 +horizgrid(Monitor *m) {
    821 +	Client *c;
    822 +	unsigned int n, i;
    823 +	int oh, ov, ih, iv;
    824 +	int mx = 0, my = 0, mh = 0, mw = 0;
    825 +	int sx = 0, sy = 0, sh = 0, sw = 0;
    826 +	int ntop, nbottom = 1;
    827 +	float mfacts, sfacts;
    828 +	int mrest, srest;
    829 +
    830 +	/* Count windows */
    831 +	getgaps(m, &oh, &ov, &ih, &iv, &n);
    832 +	if (n == 0)
    833 +		return;
    834 +
    835 +	if (n <= 2)
    836 +		ntop = n;
    837 +	else {
    838 +		ntop = n / 2;
    839 +		nbottom = n - ntop;
    840 +	}
    841 +	sx = mx = m->wx + ov;
    842 +	sy = my = m->wy + oh;
    843 +	sh = mh = m->wh - 2*oh;
    844 +	sw = mw = m->ww - 2*ov;
    845 +
    846 +	if (n > ntop) {
    847 +		sh = (mh - ih) / 2;
    848 +		mh = mh - ih - sh;
    849 +		sy = my + mh + ih;
    850 +		mw = m->ww - 2*ov - iv * (ntop - 1);
    851 +		sw = m->ww - 2*ov - iv * (nbottom - 1);
    852 +	}
    853 +
    854 +	mfacts = ntop;
    855 +	sfacts = nbottom;
    856 +	mrest = mw - (mw / ntop) * ntop;
    857 +	srest = sw - (sw / nbottom) * nbottom;
    858 +
    859 +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    860 +		if (i < ntop) {
    861 +			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
    862 +			mx += WIDTH(c) + iv;
    863 +		} else {
    864 +			resize(c, sx, sy, (sw / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
    865 +			sx += WIDTH(c) + iv;
    866 +		}
    867 +}
    868 +
    869 +/*
    870 + * nrowgrid layout + gaps
    871 + * https://dwm.suckless.org/patches/nrowgrid/
    872 + */
    873 +void
    874 +nrowgrid(Monitor *m)
    875 +{
    876 +	unsigned int n;
    877 +	int ri = 0, ci = 0;  /* counters */
    878 +	int oh, ov, ih, iv;                         /* vanitygap settings */
    879 +	unsigned int cx, cy, cw, ch;                /* client geometry */
    880 +	unsigned int uw = 0, uh = 0, uc = 0;        /* utilization trackers */
    881 +	unsigned int cols, rows = m->nmaster + 1;
    882 +	Client *c;
    883 +
    884 +	/* count clients */
    885 +	getgaps(m, &oh, &ov, &ih, &iv, &n);
    886 +
    887 +	/* nothing to do here */
    888 +	if (n == 0)
    889 +		return;
    890 +
    891 +	/* force 2 clients to always split vertically */
    892 +	if (FORCE_VSPLIT && n == 2)
    893 +		rows = 1;
    894 +
    895 +	/* never allow empty rows */
    896 +	if (n < rows)
    897 +		rows = n;
    898 +
    899 +	/* define first row */
    900 +	cols = n / rows;
    901 +	uc = cols;
    902 +	cy = m->wy + oh;
    903 +	ch = (m->wh - 2*oh - ih*(rows - 1)) / rows;
    904 +	uh = ch;
    905 +
    906 +	for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) {
    907 +		if (ci == cols) {
    908 +			uw = 0;
    909 +			ci = 0;
    910 +			ri++;
    911 +
    912 +			/* next row */
    913 +			cols = (n - uc) / (rows - ri);
    914 +			uc += cols;
    915 +			cy = m->wy + oh + uh + ih;
    916 +			uh += ch + ih;
    917 +		}
    918 +
    919 +		cx = m->wx + ov + uw;
    920 +		cw = (m->ww - 2*ov - uw) / (cols - ci);
    921 +		uw += cw + iv;
    922 +
    923 +		resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0);
    924 +	}
    925 +}
    926 +
    927 +/*
    928 + * Default tile layout + gaps
    929 + */
    930 +static void
    931 +tile(Monitor *m)
    932 +{
    933 +	unsigned int i, n;
    934 +	int oh, ov, ih, iv;
    935 +	int mx = 0, my = 0, mh = 0, mw = 0;
    936 +	int sx = 0, sy = 0, sh = 0, sw = 0;
    937 +	float mfacts, sfacts;
    938 +	int mrest, srest;
    939 +	Client *c;
    940 +
    941 +	getgaps(m, &oh, &ov, &ih, &iv, &n);
    942 +	if (n == 0)
    943 +		return;
    944 +
    945 +	sx = mx = m->wx + ov;
    946 +	sy = my = m->wy + oh;
    947 +	mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
    948 +	sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
    949 +	sw = mw = m->ww - 2*ov;
    950 +
    951 +	if (m->nmaster && n > m->nmaster) {
    952 +		sw = (mw - iv) * (1 - m->mfact);
    953 +		mw = mw - iv - sw;
    954 +		sx = mx + mw + iv;
    955 +	}
    956 +
    957 +	getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
    958 +
    959 +	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    960 +		if (i < m->nmaster) {
    961 +			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
    962 +			my += HEIGHT(c) + ih;
    963 +		} else {
    964 +			resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
    965 +			sy += HEIGHT(c) + ih;
    966 +		}
    967 +}
    968 \ No newline at end of file
    969 -- 
    970 2.19.1
    971