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