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