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