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