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