comparison config/dwm/vanitygaps.c @ 0:face7f4d84f7

Initial commit
author Yasuri <yasuri@charliesmp.net>
date Mon, 28 Sep 2026 13:10:19 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:face7f4d84f7
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 }