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