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