layouts.c (19151B) - raw


      1 /* Key binding functions */
      2 // static void defaultgaps(const Arg *arg);
      3 static void incrgaps(const Arg *arg);
      4 // static void incrigaps(const Arg *arg);
      5 // static void incrogaps(const Arg *arg);
      6 // static void incrohgaps(const Arg *arg);
      7 // static void incrovgaps(const Arg *arg);
      8 // static void incrihgaps(const Arg *arg);
      9 // static void incrivgaps(const Arg *arg);
     10 static void togglegaps(const Arg *arg);
     11 /* Layouts (delete the ones you do not need) */
     12 static void bstack(Monitor *m);
     13 // static void bstackhoriz(Monitor *m);
     14 // static void centeredmaster(Monitor *m);
     15 // static void centeredfloatingmaster(Monitor *m);
     16 static void deck(Monitor *m);
     17 // static void dwindle(Monitor *m);
     18 // static void fibonacci(Monitor *m, int s);
     19 // static void grid(Monitor *m);
     20 // static void nrowgrid(Monitor *m);
     21 // static void spiral(Monitor *m);
     22 static void tile(Monitor *m);
     23 static void monocle(Monitor *m);
     24 /* Internals */
     25 static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc);
     26 static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr);
     27 static void setgaps(int oh, int ov, int ih, int iv);
     28 
     29 /* Settings */
     30 #if !PERTAG_PATCH
     31 static int enablegaps = 1;
     32 #endif // PERTAG_PATCH
     33 
     34 void
     35 setgaps(int oh, int ov, int ih, int iv)
     36 {
     37 	if (oh < 0) oh = 0;
     38 	if (ov < 0) ov = 0;
     39 	if (ih < 0) ih = 0;
     40 	if (iv < 0) iv = 0;
     41 
     42 	selmon->gappoh = oh;
     43 	selmon->gappov = ov;
     44 	selmon->gappih = ih;
     45 	selmon->gappiv = iv;
     46 	arrange(selmon);
     47 }
     48 
     49 void
     50 togglegaps(const Arg *arg)
     51 {
     52 	#if PERTAG_PATCH
     53 	selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag];
     54 	#else
     55 	enablegaps = !enablegaps;
     56 	#endif // PERTAG_PATCH
     57 	arrange(NULL);
     58 }
     59 
     60 /*void
     61 defaultgaps(const Arg *arg)
     62 {
     63 	setgaps(gappoh, gappov, gappih, gappiv);
     64 }*/
     65 
     66 void
     67 incrgaps(const Arg *arg)
     68 {
     69 	setgaps(
     70 		selmon->gappoh + arg->i,
     71 		selmon->gappov + arg->i,
     72 		selmon->gappih + arg->i,
     73 		selmon->gappiv + arg->i
     74 	);
     75 }
     76 
     77 /*void
     78 incrigaps(const Arg *arg)
     79 {
     80 	setgaps(
     81 		selmon->gappoh,
     82 		selmon->gappov,
     83 		selmon->gappih + arg->i,
     84 		selmon->gappiv + arg->i
     85 	);
     86 }*/
     87 
     88 /*void
     89 incrogaps(const Arg *arg)
     90 {
     91 	setgaps(
     92 		selmon->gappoh + arg->i,
     93 		selmon->gappov + arg->i,
     94 		selmon->gappih,
     95 		selmon->gappiv
     96 	);
     97 }*/
     98 
     99 /*void
    100 incrohgaps(const Arg *arg)
    101 {
    102 	setgaps(
    103 		selmon->gappoh + arg->i,
    104 		selmon->gappov,
    105 		selmon->gappih,
    106 		selmon->gappiv
    107 	);
    108 }*/
    109 
    110 /*void
    111 incrovgaps(const Arg *arg)
    112 {
    113 	setgaps(
    114 		selmon->gappoh,
    115 		selmon->gappov + arg->i,
    116 		selmon->gappih,
    117 		selmon->gappiv
    118 	);
    119 }*/
    120 
    121 /*void
    122 incrihgaps(const Arg *arg)
    123 {
    124 	setgaps(
    125 		selmon->gappoh,
    126 		selmon->gappov,
    127 		selmon->gappih + arg->i,
    128 		selmon->gappiv
    129 	);
    130 }*/
    131 
    132 /*void
    133 incrivgaps(const Arg *arg)
    134 {
    135 	setgaps(
    136 		selmon->gappoh,
    137 		selmon->gappov,
    138 		selmon->gappih,
    139 		selmon->gappiv + arg->i
    140 	);
    141 }*/
    142 
    143 void
    144 getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc)
    145 {
    146 	unsigned int n, oe, ie;
    147 	#if PERTAG_PATCH
    148 	oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag];
    149 	#else
    150 	oe = ie = enablegaps;
    151 	#endif // PERTAG_PATCH
    152 	Client *c;
    153 
    154 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
    155 	if (smartgaps && n == 1) {
    156 		oe = 0; // outer gaps disabled when only one client
    157 	}
    158 
    159 	*oh = m->gappoh*oe; // outer horizontal gap
    160 	*ov = m->gappov*oe; // outer vertical gap
    161 	*ih = m->gappih*ie; // inner horizontal gap
    162 	*iv = m->gappiv*ie; // inner vertical gap
    163 	*nc = n;            // number of clients
    164 }
    165 
    166 void
    167 getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
    168 {
    169 	unsigned int n;
    170 	float mfacts, sfacts;
    171 	int mtotal = 0, stotal = 0;
    172 	Client *c;
    173 
    174 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
    175 	mfacts = MIN(n, m->nmaster);
    176 	sfacts = n - m->nmaster;
    177 
    178 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
    179 		if (n < m->nmaster)
    180 			mtotal += msize / mfacts;
    181 		else
    182 			stotal += ssize / sfacts;
    183 
    184 	*mf = mfacts; // total factor of master area
    185 	*sf = sfacts; // total factor of stack area
    186 	*mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
    187 	*sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
    188 }
    189 
    190 /***
    191  * Layouts
    192  */
    193 
    194 /*
    195  * Bottomstack layout + gaps
    196  * https://dwm.suckless.org/patches/bottomstack/
    197  */
    198 void
    199 bstack(Monitor *m)
    200 {
    201 	unsigned int i, n;
    202 	int oh, ov, ih, iv;
    203 	int mx = 0, my = 0, mh = 0, mw = 0;
    204 	int sx = 0, sy = 0, sh = 0, sw = 0;
    205 	float mfacts, sfacts;
    206 	int mrest, srest;
    207 	Client *c;
    208 
    209 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    210 	if (n == 0)
    211 		return;
    212 
    213 	sx = mx = m->wx + ov;
    214 	sy = my = m->wy + oh;
    215 	sh = mh = m->wh - 2*oh;
    216 	mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
    217 	sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
    218 
    219 	if (m->nmaster && n > m->nmaster) {
    220 		sh = (mh - ih) * (1 - m->mfact);
    221 		mh = mh - ih - sh;
    222 		sx = mx;
    223 		sy = my + mh + ih;
    224 	}
    225 
    226 	getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
    227 
    228 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
    229 		if (i < m->nmaster) {
    230 			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
    231 			mx += WIDTH(c) + iv;
    232 		} else {
    233 			resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
    234 			sx += WIDTH(c) + iv;
    235 		}
    236 	}
    237 }
    238 
    239 /*void
    240 bstackhoriz(Monitor *m)
    241 {
    242 	unsigned int i, n;
    243 	int oh, ov, ih, iv;
    244 	int mx = 0, my = 0, mh = 0, mw = 0;
    245 	int sx = 0, sy = 0, sh = 0, sw = 0;
    246 	float mfacts, sfacts;
    247 	int mrest, srest;
    248 	Client *c;
    249 
    250 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    251 	if (n == 0)
    252 		return;
    253 
    254 	sx = mx = m->wx + ov;
    255 	sy = my = m->wy + oh;
    256 	mh = m->wh - 2*oh;
    257 	sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
    258 	mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
    259 	sw = m->ww - 2*ov;
    260 
    261 	if (m->nmaster && n > m->nmaster) {
    262 		sh = (mh - ih) * (1 - m->mfact);
    263 		mh = mh - ih - sh;
    264 		sy = my + mh + ih;
    265 		sh = m->wh - mh - 2*oh - ih * (n - m->nmaster);
    266 	}
    267 
    268 	getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest);
    269 
    270 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
    271 		if (i < m->nmaster) {
    272 			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
    273 			mx += WIDTH(c) + iv;
    274 		} else {
    275 			resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
    276 			sy += HEIGHT(c) + ih;
    277 		}
    278 	}
    279 }*/
    280 
    281 /*
    282  * Centred master layout + gaps
    283  * https://dwm.suckless.org/patches/centeredmaster/
    284  */
    285 /*void
    286 centeredmaster(Monitor *m)
    287 {
    288 	unsigned int i, n;
    289 	int oh, ov, ih, iv;
    290 	int mx = 0, my = 0, mh = 0, mw = 0;
    291 	int lx = 0, ly = 0, lw = 0, lh = 0;
    292 	int rx = 0, ry = 0, rw = 0, rh = 0;
    293 	float mfacts = 0, lfacts = 0, rfacts = 0;
    294 	int mtotal = 0, ltotal = 0, rtotal = 0;
    295 	int mrest = 0, lrest = 0, rrest = 0;
    296 	Client *c;
    297 
    298 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    299 	if (n == 0)
    300 		return;
    301 
    302 	// initialize areas
    303 	mx = m->wx + ov;
    304 	my = m->wy + oh;
    305 	mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
    306 	mw = m->ww - 2*ov;
    307 	lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
    308 	rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
    309 
    310 	if (m->nmaster && n > m->nmaster) {
    311 		// go mfact box in the center if more than nmaster clients
    312 		if (n - m->nmaster > 1) {
    313 			// ||<-S->|<---M--->|<-S->||
    314 			mw = (m->ww - 2*ov - 2*iv) * m->mfact;
    315 			lw = (m->ww - mw - 2*ov - 2*iv) / 2;
    316 			rw = (m->ww - mw - 2*ov - 2*iv) - lw;
    317 			mx += lw + iv;
    318 		} else {
    319 			// ||<---M--->|<-S->||
    320 			mw = (mw - iv) * m->mfact;
    321 			lw = 0;
    322 			rw = m->ww - mw - iv - 2*ov;
    323 		}
    324 		lx = m->wx + ov;
    325 		ly = m->wy + oh;
    326 		rx = mx + mw + iv;
    327 		ry = m->wy + oh;
    328 	}
    329 
    330 	// calculate facts
    331 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
    332 		if (!m->nmaster || n < m->nmaster)
    333 			mfacts += 1;
    334 		else if ((n - m->nmaster) % 2)
    335 			lfacts += 1; // total factor of left hand stack area
    336 		else
    337 			rfacts += 1; // total factor of right hand stack area
    338 	}
    339 
    340 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
    341 		if (!m->nmaster || n < m->nmaster)
    342 			mtotal += mh / mfacts;
    343 		else if ((n - m->nmaster) % 2)
    344 			ltotal += lh / lfacts;
    345 		else
    346 			rtotal += rh / rfacts;
    347 
    348 	mrest = mh - mtotal;
    349 	lrest = lh - ltotal;
    350 	rrest = rh - rtotal;
    351 
    352 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
    353 		if (!m->nmaster || i < m->nmaster) {
    354 			// nmaster clients are stacked vertically, in the center of the screen
    355 			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
    356 			my += HEIGHT(c) + ih;
    357 		} else {
    358 			// stack clients are stacked vertically
    359 			if ((i - m->nmaster) % 2 ) {
    360 				resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
    361 				ly += HEIGHT(c) + ih;
    362 			} else {
    363 				resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
    364 				ry += HEIGHT(c) + ih;
    365 			}
    366 		}
    367 	}
    368 }*/
    369 
    370 /*void
    371 centeredfloatingmaster(Monitor *m)
    372 {
    373 	unsigned int i, n;
    374 	float mfacts, sfacts;
    375 	float mivf = 1.0; // master inner vertical gap factor
    376 	int oh, ov, ih, iv, mrest, srest;
    377 	int mx = 0, my = 0, mh = 0, mw = 0;
    378 	int sx = 0, sy = 0, sh = 0, sw = 0;
    379 	Client *c;
    380 
    381 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    382 	if (n == 0)
    383 		return;
    384 
    385 	sx = mx = m->wx + ov;
    386 	sy = my = m->wy + oh;
    387 	sh = mh = m->wh - 2*oh;
    388 	mw = m->ww - 2*ov - iv*(n - 1);
    389 	sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
    390 
    391 	if (m->nmaster && n > m->nmaster) {
    392 		mivf = 0.8;
    393 		// go mfact box in the center if more than nmaster clients
    394 		if (m->ww > m->wh) {
    395 			mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
    396 			mh = m->wh * 0.9;
    397 		} else {
    398 			mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
    399 			mh = m->wh * m->mfact;
    400 		}
    401 		mx = m->wx + (m->ww - mw) / 2;
    402 		my = m->wy + (m->wh - mh - 2*oh) / 2;
    403 
    404 		sx = m->wx + ov;
    405 		sy = m->wy + oh;
    406 		sh = m->wh - 2*oh;
    407 	}
    408 
    409 	getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
    410 
    411 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    412 		if (i < m->nmaster) {
    413 			// nmaster clients are stacked horizontally, in the center of the screen
    414 			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
    415 			mx += WIDTH(c) + iv*mivf;
    416 		} else {
    417 			// stack clients are stacked horizontally
    418 			resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
    419 			sx += WIDTH(c) + iv;
    420 		}
    421 }*/
    422 
    423 /*
    424  * Deck layout + gaps
    425  * https://dwm.suckless.org/patches/deck/
    426  */
    427 void
    428 deck(Monitor *m)
    429 {
    430 	unsigned int i, n;
    431 	int oh, ov, ih, iv;
    432 	int mx = 0, my = 0, mh = 0, mw = 0;
    433 	int sx = 0, sy = 0, sh = 0, sw = 0;
    434 	float mfacts, sfacts;
    435 	int mrest, srest;
    436 	Client *c;
    437 
    438 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    439 	if (n == 0)
    440 		return;
    441 
    442 	sx = mx = m->wx + ov;
    443 	sy = my = m->wy + oh;
    444 	sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
    445 	sw = mw = m->ww - 2*ov;
    446 
    447 	if (m->nmaster && n > m->nmaster) {
    448 		sw = (mw - iv) * (1 - m->mfact);
    449 		mw = mw - iv - sw;
    450 		sx = mx + mw + iv;
    451 		sh = m->wh - 2*oh;
    452 	}
    453 
    454 	getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
    455 
    456 	if (n - m->nmaster > 0) // override layout symbol
    457 		snprintf(m->ltsymbol, sizeof m->ltsymbol, "[]%d", n - m->nmaster);
    458 
    459 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    460 		if (i < m->nmaster) {
    461 			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
    462 			my += HEIGHT(c) + ih;
    463 		} else {
    464 			resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
    465 		}
    466 }
    467 
    468 /*
    469  * Fibonacci layout + gaps
    470  * https://dwm.suckless.org/patches/fibonacci/
    471  */
    472 /*void
    473 fibonacci(Monitor *m, int s)
    474 {
    475 	unsigned int i, n;
    476 	int nx, ny, nw, nh;
    477 	int oh, ov, ih, iv;
    478 	int nv, hrest = 0, wrest = 0, r = 1;
    479 	Client *c;
    480 
    481 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    482 	if (n == 0)
    483 		return;
    484 
    485 	nx = m->wx + ov;
    486 	ny = m->wy + oh;
    487 	nw = m->ww - 2*ov;
    488 	nh = m->wh - 2*oh;
    489 
    490 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
    491 		if (r) {
    492 			if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw))
    493 			   || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) {
    494 				r = 0;
    495 			}
    496 			if (r && i < n - 1) {
    497 				if (i % 2) {
    498 					nv = (nh - ih) / 2;
    499 					hrest = nh - 2*nv - ih;
    500 					nh = nv;
    501 				} else {
    502 					nv = (nw - iv) / 2;
    503 					wrest = nw - 2*nv - iv;
    504 					nw = nv;
    505 				}
    506 
    507 				if ((i % 4) == 2 && !s)
    508 					nx += nw + iv;
    509 				else if ((i % 4) == 3 && !s)
    510 					ny += nh + ih;
    511 			}
    512 
    513 			if ((i % 4) == 0) {
    514 				if (s) {
    515 					ny += nh + ih;
    516 					nh += hrest;
    517 				}
    518 				else {
    519 					nh -= hrest;
    520 					ny -= nh + ih;
    521 				}
    522 			}
    523 			else if ((i % 4) == 1) {
    524 				nx += nw + iv;
    525 				nw += wrest;
    526 			}
    527 			else if ((i % 4) == 2) {
    528 				ny += nh + ih;
    529 				nh += hrest;
    530 				if (i < n - 1)
    531 					nw += wrest;
    532 			}
    533 			else if ((i % 4) == 3) {
    534 				if (s) {
    535 					nx += nw + iv;
    536 					nw -= wrest;
    537 				} else {
    538 					nw -= wrest;
    539 					nx -= nw + iv;
    540 					nh += hrest;
    541 				}
    542 			}
    543 			if (i == 0)	{
    544 				if (n != 1) {
    545 					nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact);
    546 					wrest = 0;
    547 				}
    548 				ny = m->wy + oh;
    549 			}
    550 			else if (i == 1)
    551 				nw = m->ww - nw - iv - 2*ov;
    552 			i++;
    553 		}
    554 
    555 		resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
    556 	}
    557 }*/
    558 
    559 /*void
    560 dwindle(Monitor *m)
    561 {
    562 	fibonacci(m, 1);
    563 }*/
    564 
    565 /*void
    566 spiral(Monitor *m)
    567 {
    568 	fibonacci(m, 0);
    569 }*/
    570 
    571 /*
    572  * Gappless grid layout + gaps (ironically)
    573  * https://dwm.suckless.org/patches/gaplessgrid/
    574  */
    575 /*void
    576 gaplessgrid(Monitor *m)
    577 {
    578 	unsigned int i, n;
    579 	int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
    580 	int oh, ov, ih, iv;
    581 	Client *c;
    582 
    583 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    584 	if (n == 0)
    585 		return;
    586 
    587 	// grid dimensions
    588 	for (cols = 0; cols <= n/2; cols++)
    589 		if (cols*cols >= n)
    590 			break;
    591 	if (n == 5) // set layout against the general calculation: not 1:2:2, but 2:3
    592 		cols = 2;
    593 	rows = n/cols;
    594 	cn = rn = 0; // reset column no, row no, client count
    595 
    596 	ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
    597 	cw = (m->ww - 2*ov - iv * (cols - 1)) / cols;
    598 	rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
    599 	crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
    600 	x = m->wx + ov;
    601 	y = m->wy + oh;
    602 
    603 	for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) {
    604 		if (i/rows + 1 > cols - n%cols) {
    605 			rows = n/cols + 1;
    606 			ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
    607 			rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
    608 		}
    609 		resize(c,
    610 			x,
    611 			y + rn*(ch + ih) + MIN(rn, rrest),
    612 			cw + (cn < crest ? 1 : 0) - 2*c->bw,
    613 			ch + (rn < rrest ? 1 : 0) - 2*c->bw,
    614 			0);
    615 		rn++;
    616 		if (rn >= rows) {
    617 			rn = 0;
    618 			x += cw + ih + (cn < crest ? 1 : 0);
    619 			cn++;
    620 		}
    621 	}
    622 }*/
    623 
    624 /*
    625  * Gridmode layout + gaps
    626  * https://dwm.suckless.org/patches/gridmode/
    627  */
    628 /*void
    629 grid(Monitor *m)
    630 {
    631 	unsigned int i, n;
    632 	int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows;
    633 	int oh, ov, ih, iv;
    634 	Client *c;
    635 
    636 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    637 
    638 	// grid dimensions
    639 	for (rows = 0; rows <= n/2; rows++)
    640 		if (rows*rows >= n)
    641 			break;
    642 	cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
    643 
    644 	// window geoms (cell height/width)
    645 	ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1);
    646 	cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1);
    647 	chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
    648 	cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
    649 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
    650 		cc = i / rows;
    651 		cr = i % rows;
    652 		cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest);
    653 		cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest);
    654 		resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False);
    655 	}
    656 }*/
    657 
    658 /*
    659  * Horizontal grid layout + gaps
    660  * https://dwm.suckless.org/patches/horizgrid/
    661  */
    662 /*void
    663 horizgrid(Monitor *m) {
    664 	Client *c;
    665 	unsigned int n, i;
    666 	int oh, ov, ih, iv;
    667 	int mx = 0, my = 0, mh = 0, mw = 0;
    668 	int sx = 0, sy = 0, sh = 0, sw = 0;
    669 	int ntop, nbottom = 1;
    670 	float mfacts, sfacts;
    671 	int mrest, srest;
    672 
    673 	// Count windows
    674 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    675 	if (n == 0)
    676 		return;
    677 
    678 	if (n <= 2)
    679 		ntop = n;
    680 	else {
    681 		ntop = n / 2;
    682 		nbottom = n - ntop;
    683 	}
    684 	sx = mx = m->wx + ov;
    685 	sy = my = m->wy + oh;
    686 	sh = mh = m->wh - 2*oh;
    687 	sw = mw = m->ww - 2*ov;
    688 
    689 	if (n > ntop) {
    690 		sh = (mh - ih) / 2;
    691 		mh = mh - ih - sh;
    692 		sy = my + mh + ih;
    693 		mw = m->ww - 2*ov - iv * (ntop - 1);
    694 		sw = m->ww - 2*ov - iv * (nbottom - 1);
    695 	}
    696 
    697 	mfacts = ntop;
    698 	sfacts = nbottom;
    699 	mrest = mw - (mw / ntop) * ntop;
    700 	srest = sw - (sw / nbottom) * nbottom;
    701 
    702 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    703 		if (i < ntop) {
    704 			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
    705 			mx += WIDTH(c) + iv;
    706 		} else {
    707 			resize(c, sx, sy, (sw / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
    708 			sx += WIDTH(c) + iv;
    709 		}
    710 }*/
    711 
    712 /*
    713  * nrowgrid layout + gaps
    714  * https://dwm.suckless.org/patches/nrowgrid/
    715  */
    716 /*void
    717 nrowgrid(Monitor *m)
    718 {
    719 	unsigned int n;
    720 	int ri = 0, ci = 0;  // counters
    721 	int oh, ov, ih, iv;                         // vanitygap settings
    722 	unsigned int cx, cy, cw, ch;                // client geometry
    723 	unsigned int uw = 0, uh = 0, uc = 0;        // utilization trackers
    724 	unsigned int cols, rows = m->nmaster + 1;
    725 	Client *c;
    726 
    727 	// count clients
    728 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    729 
    730 	// nothing to do here
    731 	if (n == 0)
    732 		return;
    733 
    734 	// force 2 clients to always split vertically
    735 	if (FORCE_VSPLIT && n == 2)
    736 		rows = 1;
    737 
    738 	// never allow empty rows
    739 	if (n < rows)
    740 		rows = n;
    741 
    742 	// define first row
    743 	cols = n / rows;
    744 	uc = cols;
    745 	cy = m->wy + oh;
    746 	ch = (m->wh - 2*oh - ih*(rows - 1)) / rows;
    747 	uh = ch;
    748 
    749 	for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) {
    750 		if (ci == cols) {
    751 			uw = 0;
    752 			ci = 0;
    753 			ri++;
    754 
    755 			// next row
    756 			cols = (n - uc) / (rows - ri);
    757 			uc += cols;
    758 			cy = m->wy + oh + uh + ih;
    759 			uh += ch + ih;
    760 		}
    761 
    762 		cx = m->wx + ov + uw;
    763 		cw = (m->ww - 2*ov - uw) / (cols - ci);
    764 		uw += cw + iv;
    765 
    766 		resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0);
    767 	}
    768 }*/
    769 
    770 /*
    771  * Default tile layout + gaps
    772  */
    773 void
    774 tile(Monitor *m)
    775 {
    776 	unsigned int i, n;
    777 	int oh, ov, ih, iv;
    778 	int mx = 0, my = 0, mh = 0, mw = 0;
    779 	int sx = 0, sy = 0, sh = 0, sw = 0;
    780 	float mfacts, sfacts;
    781 	int mrest, srest;
    782 	Client *c;
    783 
    784 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    785 	if (n == 0)
    786 		return;
    787 
    788 	sx = mx = m->wx + ov;
    789 	sy = my = m->wy + oh;
    790 	mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
    791 	sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
    792 	sw = mw = m->ww - 2*ov;
    793 
    794 	if (m->nmaster && n > m->nmaster) {
    795 		sw = (mw - iv) * (1 - m->mfact);
    796 		mw = mw - iv - sw;
    797 		sx = mx + mw + iv;
    798 	}
    799 
    800 	getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
    801 
    802 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    803 		if (i < m->nmaster) {
    804 			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
    805 			if (my + HEIGHT(c) + ih < m->wh)
    806 				my += HEIGHT(c) + ih;
    807 		} else {
    808 			resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
    809 			if (sy + HEIGHT(c) + ih < m->wh)
    810 				sy += HEIGHT(c) + ih;
    811 		}
    812 }
    813 
    814 void
    815 monocle(Monitor *m)
    816 {
    817 	unsigned int n = 0;
    818 	Client *c;
    819 
    820 	for (c = m->clients; c; c = c->next)
    821 		if (ISVISIBLE(c))
    822 			n++;
    823 	if (n > 0) // override layout symbol
    824 		snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
    825 	for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
    826 		resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
    827 }
    828