dwm-vanitygaps-6.2.diff 25 KB

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