sites

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

dwm-cfacts-vanitygaps-6.4_combo.diff (27606B)


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