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