dotfiles

[void/arch] linux dotfiles
git clone git://git.mdnr.space/dotfiles
Log | Files | Refs

vanitygaps.c (12589B)


      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 static void togglesmartgaps(const Arg *arg);
     12 
     13 /* Layouts */
     14 static void bstack(Monitor *m);
     15 static void centeredmaster(Monitor *m);
     16 static void centeredfloatingmaster(Monitor *m);
     17 static void deck(Monitor *m);
     18 static void dwindle(Monitor *m);
     19 static void fibonacci(Monitor *m, int s);
     20 static void spiral(Monitor *m);
     21 static void tile(Monitor *);
     22 
     23 /* Internals */
     24 static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc);
     25 static void setgaps(int oh, int ov, int ih, int iv);
     26 
     27 /* Settings */
     28 static int enablegaps = 1;
     29 
     30 static void
     31 setgaps(int oh, int ov, int ih, int iv)
     32 {
     33 	if (oh < 0) oh = 0;
     34 	if (ov < 0) ov = 0;
     35 	if (ih < 0) ih = 0;
     36 	if (iv < 0) iv = 0;
     37 
     38 	selmon->gappoh = oh;
     39 	selmon->gappov = ov;
     40 	selmon->gappih = ih;
     41 	selmon->gappiv = iv;
     42 	arrange(selmon);
     43 }
     44 
     45 static void
     46 togglegaps(const Arg *arg)
     47 {
     48 	enablegaps = !enablegaps;
     49 	arrange(NULL);
     50 }
     51 
     52 static void
     53 togglesmartgaps(const Arg *arg)
     54 {
     55 	smartgaps = !smartgaps;
     56 	arrange(NULL);
     57 }
     58 
     59 static void
     60 defaultgaps(const Arg *arg)
     61 {
     62 	setgaps(gappoh, gappov, gappih, gappiv);
     63 }
     64 
     65 static void
     66 incrgaps(const Arg *arg)
     67 {
     68 	setgaps(
     69 		selmon->gappoh + arg->i,
     70 		selmon->gappov + arg->i,
     71 		selmon->gappih + arg->i,
     72 		selmon->gappiv + arg->i
     73 	);
     74 }
     75 
     76 /* static void */
     77 /* incrigaps(const Arg *arg) */
     78 /* { */
     79 /* 	setgaps( */
     80 /* 		selmon->gappoh, */
     81 /* 		selmon->gappov, */
     82 /* 		selmon->gappih + arg->i, */
     83 /* 		selmon->gappiv + arg->i */
     84 /* 	); */
     85 /* } */
     86 
     87 /* static void */
     88 /* incrogaps(const Arg *arg) */
     89 /* { */
     90 /* 	setgaps( */
     91 /* 		selmon->gappoh + arg->i, */
     92 /* 		selmon->gappov + arg->i, */
     93 /* 		selmon->gappih, */
     94 /* 		selmon->gappiv */
     95 /* 	); */
     96 /* } */
     97 
     98 /* static void */
     99 /* incrohgaps(const Arg *arg) */
    100 /* { */
    101 /* 	setgaps( */
    102 /* 		selmon->gappoh + arg->i, */
    103 /* 		selmon->gappov, */
    104 /* 		selmon->gappih, */
    105 /* 		selmon->gappiv */
    106 /* 	); */
    107 /* } */
    108 
    109 /* static void */
    110 /* incrovgaps(const Arg *arg) */
    111 /* { */
    112 /* 	setgaps( */
    113 /* 		selmon->gappoh, */
    114 /* 		selmon->gappov + arg->i, */
    115 /* 		selmon->gappih, */
    116 /* 		selmon->gappiv */
    117 /* 	); */
    118 /* } */
    119 
    120 /* static void */
    121 /* incrihgaps(const Arg *arg) */
    122 /* { */
    123 /* 	setgaps( */
    124 /* 		selmon->gappoh, */
    125 /* 		selmon->gappov, */
    126 /* 		selmon->gappih + arg->i, */
    127 /* 		selmon->gappiv */
    128 /* 	); */
    129 /* } */
    130 
    131 /* static void */
    132 /* incrivgaps(const Arg *arg) */
    133 /* { */
    134 /* 	setgaps( */
    135 /* 		selmon->gappoh, */
    136 /* 		selmon->gappov, */
    137 /* 		selmon->gappih, */
    138 /* 		selmon->gappiv + arg->i */
    139 /* 	); */
    140 /* } */
    141 
    142 static void
    143 getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc)
    144 {
    145 	unsigned int n, oe, ie;
    146 	oe = ie = enablegaps;
    147 	Client *c;
    148 
    149 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
    150 	if (smartgaps && n == 1) {
    151 		oe = 0; // outer gaps disabled when only one client
    152 	}
    153 
    154 	*oh = m->gappoh*oe; // outer horizontal gap
    155 	*ov = m->gappov*oe; // outer vertical gap
    156 	*ih = m->gappih*ie; // inner horizontal gap
    157 	*iv = m->gappiv*ie; // inner vertical gap
    158 	*nc = n;            // number of clients
    159 }
    160 
    161 void
    162 getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
    163 {
    164 	unsigned int n;
    165 	float mfacts, sfacts;
    166 	int mtotal = 0, stotal = 0;
    167 	Client *c;
    168 
    169 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
    170 	mfacts = MIN(n, m->nmaster);
    171 	sfacts = n - m->nmaster;
    172 
    173 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
    174 		if (n < m->nmaster)
    175 			mtotal += msize / mfacts;
    176 		else
    177 			stotal += ssize / sfacts;
    178 
    179 	*mf = mfacts; // total factor of master area
    180 	*sf = sfacts; // total factor of stack area
    181 	*mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
    182 	*sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
    183 }
    184 
    185 /***
    186  * Layouts
    187  */
    188 
    189 /*
    190  * Bottomstack layout + gaps
    191  * https://dwm.suckless.org/patches/bottomstack/
    192  */
    193 
    194 static void
    195 bstack(Monitor *m)
    196 {
    197 	unsigned int i, n;
    198 	int mx = 0, my = 0, mh = 0, mw = 0;
    199 	int sx = 0, sy = 0, sh = 0, sw = 0;
    200 	float mfacts, sfacts;
    201 	int mrest, srest;
    202 	Client *c;
    203 
    204 	int oh, ov, ih, iv;
    205 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    206 
    207 	if (n == 0)
    208 		return;
    209 
    210 	sx = mx = m->wx + ov;
    211 	sy = my = m->wy + oh;
    212 	sh = mh = m->wh - 2*oh;
    213 	mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
    214 	sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
    215 
    216 	if (m->nmaster && n > m->nmaster) {
    217 		sh = (mh - ih) * (1 - m->mfact);
    218 		mh = (mh - ih) * m->mfact;
    219 		sx = mx;
    220 		sy = my + mh + ih;
    221 	}
    222 
    223 	getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
    224 
    225 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
    226 		if (i < m->nmaster) {
    227 			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
    228 			mx += WIDTH(c) + iv;
    229 		} else {
    230 			resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
    231 			sx += WIDTH(c) + iv;
    232 		}
    233 	}
    234 }
    235 
    236 /*
    237  * Centred master layout + gaps
    238  * https://dwm.suckless.org/patches/centeredmaster/
    239  */
    240 
    241 void
    242 centeredmaster(Monitor *m)
    243 {
    244 	unsigned int i, n;
    245 	int mx = 0, my = 0, mh = 0, mw = 0;
    246 	int lx = 0, ly = 0, lw = 0, lh = 0;
    247 	int rx = 0, ry = 0, rw = 0, rh = 0;
    248 	float mfacts = 0, lfacts = 0, rfacts = 0;
    249 	int mtotal = 0, ltotal = 0, rtotal = 0;
    250 	int mrest = 0, lrest = 0, rrest = 0;
    251 	Client *c;
    252 
    253 	int oh, ov, ih, iv;
    254 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    255 
    256 	if (n == 0)
    257 		return;
    258 
    259 	/* initialize areas */
    260 	mx = m->wx + ov;
    261 	my = m->wy + oh;
    262 	mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
    263 	mw = m->ww - 2*ov;
    264 	lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
    265 	rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
    266 
    267 	if (m->nmaster && n > m->nmaster) {
    268 		/* go mfact box in the center if more than nmaster clients */
    269 		if (n - m->nmaster > 1) {
    270 			/* ||<-S->|<---M--->|<-S->|| */
    271 			mw = (m->ww - 2*ov - 2*iv) * m->mfact;
    272 			lw = (m->ww - mw - 2*ov - 2*iv) / 2;
    273 			mx += lw + iv;
    274 		} else {
    275 			/* ||<---M--->|<-S->|| */
    276 			mw = (mw - iv) * m->mfact;
    277 			lw = m->ww - mw - iv - 2*ov;
    278 		}
    279 		rw = lw;
    280 		lx = m->wx + ov;
    281 		ly = m->wy + oh;
    282 		rx = mx + mw + iv;
    283 		ry = m->wy + oh;
    284 	}
    285 
    286 	/* calculate facts */
    287 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
    288 		if (!m->nmaster || n < m->nmaster)
    289 			mfacts += 1;
    290 		else if ((n - m->nmaster) % 2)
    291 			lfacts += 1; // total factor of left hand stack area
    292 		else
    293 			rfacts += 1; // total factor of right hand stack area
    294 	}
    295 
    296 	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
    297 		if (!m->nmaster || n < m->nmaster)
    298 			mtotal += mh / mfacts;
    299 		else if ((n - m->nmaster) % 2)
    300 			ltotal += lh / lfacts;
    301 		else
    302 			rtotal += rh / rfacts;
    303 
    304 	mrest = mh - mtotal;
    305 	lrest = lh - ltotal;
    306 	rrest = rh - rtotal;
    307 
    308 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
    309 		if (!m->nmaster || i < m->nmaster) {
    310 			/* nmaster clients are stacked vertically, in the center of the screen */
    311 			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
    312 			my += HEIGHT(c) + ih;
    313 		} else {
    314 			/* stack clients are stacked vertically */
    315 			if ((i - m->nmaster) % 2 ) {
    316 				resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
    317 				ly += HEIGHT(c) + ih;
    318 			} else {
    319 				resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
    320 				ry += HEIGHT(c) + ih;
    321 			}
    322 		}
    323 	}
    324 }
    325 
    326 void
    327 centeredfloatingmaster(Monitor *m)
    328 {
    329 	unsigned int i, n;
    330 	float mfacts, sfacts;
    331 	int mrest, srest;
    332 	int mx = 0, my = 0, mh = 0, mw = 0;
    333 	int sx = 0, sy = 0, sh = 0, sw = 0;
    334 	Client *c;
    335 
    336 	float mivf = 1.0; // master inner vertical gap factor
    337 	int oh, ov, ih, iv;
    338 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    339 
    340 	if (n == 0)
    341 		return;
    342 
    343 	sx = mx = m->wx + ov;
    344 	sy = my = m->wy + oh;
    345 	sh = mh = m->wh - 2*oh;
    346 	mw = m->ww - 2*ov - iv*(n - 1);
    347 	sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
    348 
    349 	if (m->nmaster && n > m->nmaster) {
    350 		mivf = 0.8;
    351 		/* go mfact box in the center if more than nmaster clients */
    352 		if (m->ww > m->wh) {
    353 			mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
    354 			mh = m->wh * 0.9 - 2*oh;
    355 		} else {
    356 			mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
    357 			mh = m->wh * m->mfact;
    358 		}
    359 		mx = m->wx + (m->ww - mw) / 2;
    360 		my = m->wy + (m->wh - mh) / 2;
    361 
    362 		sx = m->wx + ov;
    363 		sy = m->wy + oh;
    364 		sh = m->wh - 2*oh;
    365 	}
    366 
    367 	getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
    368 
    369 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    370 		if (i < m->nmaster) {
    371 			/* nmaster clients are stacked horizontally, in the center of the screen */
    372 			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
    373 			mx += WIDTH(c) + iv*mivf;
    374 		} else {
    375 			/* stack clients are stacked horizontally */
    376 			resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
    377 			sx += WIDTH(c) + iv;
    378 		}
    379 }
    380 
    381 /*
    382  * Deck layout + gaps
    383  * https://dwm.suckless.org/patches/deck/
    384  */
    385 
    386 static void
    387 deck(Monitor *m)
    388 {
    389 	unsigned int i, n;
    390 	int mx = 0, my = 0, mh = 0, mw = 0;
    391 	int sx = 0, sy = 0, sh = 0, sw = 0;
    392 	float mfacts, sfacts;
    393 	int mrest, srest;
    394 	Client *c;
    395 
    396 	int oh, ov, ih, iv;
    397 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    398 
    399 	if (n == 0)
    400 		return;
    401 
    402 	sx = mx = m->wx + ov;
    403 	sy = my = m->wy + oh;
    404 	sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
    405 	sw = mw = m->ww - 2*ov;
    406 
    407 	if (m->nmaster && n > m->nmaster) {
    408 		sw = (mw - iv) * (1 - m->mfact);
    409 		mw = (mw - iv) * m->mfact;
    410 		sx = mx + mw + iv;
    411 		sh = m->wh - 2*oh;
    412 	}
    413 
    414 	getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
    415 
    416 	if (n - m->nmaster > 0) /* override layout symbol */
    417 		snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster);
    418 
    419 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    420 		if (i < m->nmaster) {
    421 			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
    422 			my += HEIGHT(c) + ih;
    423 		} else {
    424 			resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
    425 		}
    426 }
    427 
    428 /*
    429  * Fibonacci layout + gaps
    430  * https://dwm.suckless.org/patches/fibonacci/
    431  */
    432 
    433 static void
    434 fibonacci(Monitor *m, int s)
    435 {
    436 	unsigned int i, n;
    437 	int nx, ny, nw, nh;
    438 	int oh, ov, ih, iv;
    439 	Client *c;
    440 
    441 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    442 
    443 	if (n == 0)
    444 		return;
    445 
    446 	nx = m->wx + ov;
    447 	ny = oh;
    448 	nw = m->ww - 2*ov;
    449 	nh = m->wh - 2*oh;
    450 
    451 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
    452 		if ((i % 2 && nh / 2 > 2*c->bw)
    453 		   || (!(i % 2) && nw / 2 > 2*c->bw)) {
    454 			if (i < n - 1) {
    455 				if (i % 2)
    456 					nh = (nh - ih) / 2;
    457 				else
    458 					nw = (nw - iv) / 2;
    459 
    460 				if ((i % 4) == 2 && !s)
    461 					nx += nw + iv;
    462 				else if ((i % 4) == 3 && !s)
    463 					ny += nh + ih;
    464 			}
    465 			if ((i % 4) == 0) {
    466 				if (s)
    467 					ny += nh + ih;
    468 				else
    469 					ny -= nh + ih;
    470 			}
    471 			else if ((i % 4) == 1)
    472 				nx += nw + iv;
    473 			else if ((i % 4) == 2)
    474 				ny += nh + ih;
    475 			else if ((i % 4) == 3) {
    476 				if (s)
    477 					nx += nw + iv;
    478 				else
    479 					nx -= nw + iv;
    480 			}
    481 			if (i == 0)	{
    482 				if (n != 1)
    483 					nw = (m->ww - 2*ov - iv) * m->mfact;
    484 				ny = m->wy + oh;
    485 			}
    486 			else if (i == 1)
    487 				nw = m->ww - nw - iv - 2*ov;
    488 			i++;
    489 		}
    490 
    491 		resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
    492 	}
    493 }
    494 
    495 static void
    496 dwindle(Monitor *m)
    497 {
    498 	fibonacci(m, 1);
    499 }
    500 
    501 static void
    502 spiral(Monitor *m)
    503 {
    504 	fibonacci(m, 0);
    505 }
    506 
    507 /*
    508  * Default tile layout + gaps
    509  */
    510 
    511 static void
    512 tile(Monitor *m)
    513 {
    514 	unsigned int i, n;
    515 	int mx = 0, my = 0, mh = 0, mw = 0;
    516 	int sx = 0, sy = 0, sh = 0, sw = 0;
    517 	float mfacts, sfacts;
    518 	int mrest, srest;
    519 	Client *c;
    520 
    521 
    522 	int oh, ov, ih, iv;
    523 	getgaps(m, &oh, &ov, &ih, &iv, &n);
    524 
    525 	if (n == 0)
    526 		return;
    527 
    528 	sx = mx = m->wx + ov;
    529 	sy = my = m->wy + oh;
    530 	mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
    531 	sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
    532 	sw = mw = m->ww - 2*ov;
    533 
    534 	if (m->nmaster && n > m->nmaster) {
    535 		sw = (mw - iv) * (1 - m->mfact);
    536 		mw = (mw - iv) * m->mfact;
    537 		sx = mx + mw + iv;
    538 	}
    539 
    540 	getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
    541 
    542 	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    543 		if (i < m->nmaster) {
    544 			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
    545 			my += HEIGHT(c) + ih;
    546 		} else {
    547 			resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
    548 			sy += HEIGHT(c) + ih;
    549 		}
    550 }