Another copy of my dotfiles. Because I don't completely trust GitHub.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

435 lines
14 KiB

  1. /* Flexwintitle properties, you can override these in your config.h if you want. */
  2. #ifndef FLEXWINTITLE_BORDERS
  3. #define FLEXWINTITLE_BORDERS 1 // 0 = off, 1 = on
  4. #endif
  5. #ifndef FLEXWINTITLE_SHOWFLOATING
  6. #define FLEXWINTITLE_SHOWFLOATING 0 // whether to show titles for floating windows, hidden clients are always shown
  7. #endif
  8. #ifndef FLEXWINTITLE_MASTERWEIGHT
  9. #define FLEXWINTITLE_MASTERWEIGHT 9 // master weight compared to stack, hidden and floating window titles
  10. #endif
  11. #ifndef FLEXWINTITLE_STACKWEIGHT
  12. #define FLEXWINTITLE_STACKWEIGHT 3 // stack weight compared to master, hidden and floating window titles
  13. #endif
  14. #ifndef FLEXWINTITLE_HIDDENWEIGHT
  15. #define FLEXWINTITLE_HIDDENWEIGHT 1 // hidden window title weight
  16. #endif
  17. #ifndef FLEXWINTITLE_FLOATWEIGHT
  18. #define FLEXWINTITLE_FLOATWEIGHT 1 // floating window title weight, set to 0 to not show floating windows
  19. #endif
  20. #define SCHEMEFOR(c) getschemefor(m, c, groupactive == c)
  21. enum { GRP_NOSELECTION, GRP_MASTER, GRP_STACK1, GRP_STACK2, GRP_FLOAT, GRP_HIDDEN };
  22. int
  23. width_flexwintitle(Bar *bar, BarArg *a)
  24. {
  25. return a->w;
  26. }
  27. int
  28. draw_flexwintitle(Bar *bar, BarArg *a)
  29. {
  30. drw_rect(drw, a->x, a->y, a->w, a->h, 1, 1);
  31. return flextitlecalculate(bar->mon, a->x, a->w, -1, flextitledraw, NULL, a);
  32. }
  33. int
  34. click_flexwintitle(Bar *bar, Arg *arg, BarArg *a)
  35. {
  36. flextitlecalculate(bar->mon, 0, a->w, a->x, flextitleclick, arg, a);
  37. return ClkWinTitle;
  38. }
  39. Client *
  40. flextitledrawarea(Monitor *m, Client *c, int x, int r, int w, int max_clients, int scheme, int draw_tiled, int draw_hidden, int draw_floating,
  41. int passx, void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), Arg *arg, BarArg *barg)
  42. {
  43. int i;
  44. for (i = 0; c && i < max_clients; c = c->next) {
  45. if (
  46. ISVISIBLE(c) &&
  47. (
  48. (draw_tiled && !c->isfloating && !HIDDEN(c)) ||
  49. (draw_floating && c->isfloating && !HIDDEN(c)) ||
  50. (draw_hidden && HIDDEN(c))
  51. )
  52. ) {
  53. tabfn(m, c, passx, x, w + (i < r ? 1 : 0), scheme, arg, barg);
  54. x += w + (i < r ? 1 : 0);
  55. i++;
  56. }
  57. }
  58. return c;
  59. }
  60. int
  61. getschemefor(Monitor *m, int group, int activegroup)
  62. {
  63. switch (group) {
  64. case GRP_NOSELECTION:
  65. case GRP_MASTER:
  66. case GRP_STACK1:
  67. case GRP_STACK2:
  68. #if BSTACK_LAYOUT
  69. if (m->lt[m->sellt]->arrange == &bstack)
  70. return (activegroup ? SchemeFlexActLTR : SchemeFlexInaLTR);
  71. #endif // BSTACK_LAYOUT
  72. #if BSTACKHORIZ_LAYOUT
  73. if (m->lt[m->sellt]->arrange == &bstackhoriz) {
  74. if (group == GRP_MASTER)
  75. return (activegroup ? SchemeFlexActLTR : SchemeFlexInaLTR);
  76. else
  77. return (activegroup ? SchemeFlexActTTB : SchemeFlexInaTTB);
  78. }
  79. #endif // BSTACKHORIZ_LAYOUT
  80. #if CENTEREDMASTER_LAYOUT
  81. if (m->lt[m->sellt]->arrange == &centeredmaster)
  82. return (activegroup ? SchemeFlexActTTB : SchemeFlexInaTTB);
  83. #endif // CENTEREDMASTER_LAYOUT
  84. #if CENTEREDFLOATINGMASTER_LAYOUT
  85. if (m->lt[m->sellt]->arrange == &centeredfloatingmaster)
  86. return (activegroup ? SchemeFlexActLTR : SchemeFlexInaLTR);
  87. #endif // CENTEREDFLOATINGMASTER_LAYOUT
  88. #if COLUMNS_LAYOUT
  89. if (m->lt[m->sellt]->arrange == &col) {
  90. if (group == GRP_MASTER)
  91. return (activegroup ? SchemeFlexActLTR : SchemeFlexInaLTR);
  92. else
  93. return (activegroup ? SchemeFlexActTTB : SchemeFlexInaTTB);
  94. }
  95. #endif // COLUMNS_LAYOUT
  96. #if DECK_LAYOUT
  97. if (m->lt[m->sellt]->arrange == &deck) {
  98. if (group == GRP_MASTER)
  99. return (activegroup ? SchemeFlexActTTB : SchemeFlexInaTTB);
  100. else
  101. return (activegroup ? SchemeFlexActMONO : SchemeFlexInaMONO);
  102. }
  103. #endif // DECK_LAYOUT
  104. #if FIBONACCI_DWINDLE_LAYOUT
  105. if (m->lt[m->sellt]->arrange == &dwindle)
  106. return (activegroup ? SchemeFlexActDWDL : SchemeFlexInaDWDL);
  107. #endif // FIBONACCI_DWINDLE_LAYOUT
  108. #if FIBONACCI_SPIRAL_LAYOUT
  109. if (m->lt[m->sellt]->arrange == &spiral)
  110. return (activegroup ? SchemeFlexActSPRL : SchemeFlexInaSPRL);
  111. #endif // FIBONACCI_SPIRAL_LAYOUT
  112. #if FLEXTILE_DELUXE_LAYOUT
  113. if (m->lt[m->sellt]->arrange == &flextile)
  114. return (activegroup ? SchemeFlexActTTB + m->ltaxis[group] : SchemeFlexInaTTB + m->ltaxis[group]);
  115. #endif // FLEXTILE_DELUXE_LAYOUT
  116. #if GAPPLESSGRID_LAYOUT
  117. if (m->lt[m->sellt]->arrange == &gaplessgrid)
  118. return (activegroup ? SchemeFlexActGRID : SchemeFlexInaGRID);
  119. #endif // GAPPLESSGRID_LAYOUT
  120. #if GRIDMODE_LAYOUT
  121. if (m->lt[m->sellt]->arrange == &grid)
  122. return (activegroup ? SchemeFlexActGRDM : SchemeFlexInaGRDM);
  123. #endif // GRIDMODE_LAYOUT
  124. #if HORIZGRID_LAYOUT
  125. if (m->lt[m->sellt]->arrange == &horizgrid)
  126. return (activegroup ? SchemeFlexActHGRD : SchemeFlexInaHGRD);
  127. #endif // HORIZGRID_LAYOUT
  128. #if NROWGRID_LAYOUT
  129. if (m->lt[m->sellt]->arrange == &nrowgrid)
  130. return (activegroup ? SchemeFlexActGRD1 : SchemeFlexInaGRD1);
  131. #endif // NROWGRID_LAYOUT
  132. #if TILE_LAYOUT
  133. if (m->lt[m->sellt]->arrange == &tile)
  134. return (activegroup ? SchemeFlexActTTB : SchemeFlexInaTTB);
  135. #endif // TILE_LAYOUT
  136. #if MONOCLE_LAYOUT
  137. if (m->lt[m->sellt]->arrange == &monocle)
  138. return (activegroup ? SchemeFlexActMONO : SchemeFlexInaMONO);
  139. #endif // MONOCLE_LAYOUT
  140. return SchemeTitleNorm;
  141. case GRP_HIDDEN:
  142. return SchemeHid;
  143. case GRP_FLOAT:
  144. return (activegroup ? SchemeFlexActFloat : SchemeFlexInaFloat);
  145. }
  146. return SchemeTitleNorm;
  147. }
  148. int
  149. getselschemefor(int scheme)
  150. {
  151. if (scheme == SchemeFlexActFloat || scheme == SchemeFlexInaFloat)
  152. return SchemeFlexSelFloat;
  153. if (scheme >= SchemeFlexInaTTB)
  154. return scheme + SchemeFlexInaTTB - SchemeFlexActTTB;
  155. if (scheme >= SchemeFlexActTTB)
  156. return scheme + SchemeFlexSelTTB - SchemeFlexActTTB;
  157. return SchemeTitleSel;
  158. }
  159. void
  160. flextitledraw(Monitor *m, Client *c, int unused, int x, int w, int tabscheme, Arg *arg, BarArg *barg)
  161. {
  162. if (!c)
  163. return;
  164. int i, nclienttags = 0, nviewtags = 0, pad = lrpad / 2;
  165. int clientscheme = (
  166. c == selmon->sel
  167. ? getselschemefor(tabscheme)
  168. : HIDDEN(c)
  169. ? SchemeHid
  170. : c->isurgent
  171. ? SchemeUrg
  172. : tabscheme
  173. );
  174. drw_setscheme(drw, scheme[clientscheme]);
  175. XSetWindowBorder(dpy, c->win, scheme[clientscheme][ColBorder].pixel);
  176. if (w <= TEXTW("A") - lrpad + pad) // reduce text padding if wintitle is too small
  177. pad = (w - TEXTW("A") + lrpad < 0 ? 0 : (w - TEXTW("A") + lrpad) / 2);
  178. #if BAR_CENTEREDWINDOWNAME_PATCH
  179. else if (TEXTW(c->name) < w)
  180. pad = (w - TEXTW(c->name) + lrpad) / 2;
  181. #endif // BAR_CENTEREDWINDOWNAME_PATCH
  182. drw_text(drw, x, barg->y, w, barg->h, pad, c->name, 0, False);
  183. drawstateindicator(m, c, 1, x + 2, barg->y, w, barg->h, 0, 0, 0);
  184. if (FLEXWINTITLE_BORDERS) {
  185. XSetForeground(drw->dpy, drw->gc, scheme[SchemeSel][ColBorder].pixel);
  186. XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, barg->y, 1, barg->h);
  187. XFillRectangle(drw->dpy, drw->drawable, drw->gc, x + w - (x + w >= barg->w ? 1 : 0), barg->y, 1, barg->h);
  188. }
  189. /* Optional tags icons */
  190. for (i = 0; i < NUMTAGS; i++) {
  191. if ((m->tagset[m->seltags] >> i) & 1)
  192. nviewtags++;
  193. if ((c->tags >> i) & 1)
  194. nclienttags++;
  195. }
  196. if (TAGSINDICATOR == 2 || nclienttags > 1 || nviewtags > 1)
  197. drawindicator(m, c, 1, x, barg->y, w, barg->h, 0, 0, 0, INDICATOR_RIGHT_TAGS);
  198. }
  199. #ifndef HIDDEN
  200. #define HIDDEN(C) 0
  201. #endif
  202. void
  203. flextitleclick(Monitor *m, Client *c, int passx, int x, int w, int unused, Arg *arg, BarArg *barg)
  204. {
  205. if (passx >= x && passx <= x + w)
  206. arg->v = c;
  207. }
  208. int
  209. flextitlecalculate(
  210. Monitor *m, int offx, int tabw, int passx,
  211. void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg),
  212. Arg *arg, BarArg *barg
  213. ) {
  214. Client *c;
  215. int n, center = 0, mirror = 0, fixed = 0; // layout configuration
  216. int clientsnmaster = 0, clientsnstack = 0, clientsnfloating = 0, clientsnhidden = 0;
  217. int i, w, r, num = 0, den, fulllayout = 0;
  218. int clientsnstack2 = 0;
  219. int groupactive = 0;
  220. int selidx = 0;
  221. int dualstack = 0;
  222. int rw, rr;
  223. int mas_x = offx, st1_x = offx, st2_x = offx, hid_x = offx, flt_x = offx;
  224. int mas_w, st1_w, st2_w, hid_w;
  225. for (i = 0, c = m->clients; c; c = c->next) {
  226. if (!ISVISIBLE(c))
  227. continue;
  228. if (HIDDEN(c)) {
  229. if (FLEXWINTITLE_HIDDENWEIGHT)
  230. clientsnhidden++;
  231. continue;
  232. }
  233. if (c->isfloating) {
  234. if (FLEXWINTITLE_FLOATWEIGHT)
  235. clientsnfloating++;
  236. continue;
  237. }
  238. if (m->sel == c)
  239. selidx = i;
  240. if (i < m->nmaster)
  241. clientsnmaster++;
  242. #if FLEXTILE_DELUXE_LAYOUT
  243. else if (m->nstack) {
  244. if (clientsnstack < m->nstack)
  245. clientsnstack++;
  246. else
  247. clientsnstack2++;
  248. }
  249. #endif // FLEXTILE_DELUXE_LAYOUT
  250. else if ((i - m->nmaster) % 2)
  251. clientsnstack2++;
  252. else
  253. clientsnstack++;
  254. i++;
  255. }
  256. if (!m->sel)
  257. groupactive = GRP_NOSELECTION;
  258. else if (HIDDEN(m->sel))
  259. groupactive = GRP_HIDDEN;
  260. else if (m->sel->isfloating)
  261. groupactive = GRP_FLOAT;
  262. else if (selidx < clientsnmaster)
  263. groupactive = GRP_MASTER;
  264. else if (selidx < clientsnmaster + clientsnstack)
  265. groupactive = GRP_STACK1;
  266. else if (selidx < clientsnmaster + clientsnstack + clientsnstack2)
  267. groupactive = GRP_STACK2;
  268. n = clientsnmaster + clientsnstack + clientsnstack2 + clientsnfloating + clientsnhidden;
  269. if (n == 0)
  270. return 0;
  271. #if FLEXTILE_DELUXE_LAYOUT
  272. else if (m->lt[m->sellt]->arrange == &flextile) {
  273. int layout = m->ltaxis[LAYOUT];
  274. if (layout < 0) {
  275. mirror = 1;
  276. layout *= -1;
  277. }
  278. if (layout > FLOATING_MASTER) {
  279. layout -= FLOATING_MASTER;
  280. fixed = 1;
  281. }
  282. if (layout == SPLIT_HORIZONTAL_DUAL_STACK || layout == SPLIT_HORIZONTAL_DUAL_STACK_FIXED)
  283. dualstack = 1;
  284. else if (layout == SPLIT_CENTERED_VERTICAL && (fixed || n - m->nmaster > 1))
  285. center = 1;
  286. else if (layout == FLOATING_MASTER)
  287. center = 1;
  288. else if (layout == SPLIT_CENTERED_HORIZONTAL) {
  289. if (fixed || n - m->nmaster > 1)
  290. center = 1;
  291. }
  292. }
  293. #endif // FLEXTILE_DELUXE_LAYOUT
  294. #if CENTEREDMASTER_LAYOUT
  295. else if (m->lt[m->sellt]->arrange == &centeredmaster && (fixed || n - m->nmaster > 1))
  296. center = 1;
  297. #endif // CENTEREDMASTER_LAYOUT
  298. #if CENTEREDFLOATINGMASTER_LAYOUT
  299. else if (m->lt[m->sellt]->arrange == &centeredfloatingmaster)
  300. center = 1;
  301. #endif // CENTEREDFLOATINGMASTER_LAYOUT
  302. /* Certain layouts have no master / stack areas */
  303. if (!m->lt[m->sellt]->arrange // floating layout
  304. || (!n || (!fixed && m->nmaster && n <= m->nmaster)) // no master
  305. #if MONOCLE_LAYOUT
  306. || m->lt[m->sellt]->arrange == &monocle
  307. #endif // MONOCLE_LAYOUT
  308. #if GRIDMODE_LAYOUT
  309. || m->lt[m->sellt]->arrange == &grid
  310. #endif // GRIDMODE_LAYOUT
  311. #if HORIZGRID_LAYOUT
  312. || m->lt[m->sellt]->arrange == &horizgrid
  313. #endif // HORIZGRID_LAYOUT
  314. #if GAPPLESSGRID_LAYOUT
  315. || m->lt[m->sellt]->arrange == &gaplessgrid
  316. #endif // GAPPLESSGRID_LAYOUT
  317. #if NROWGRID_LAYOUT
  318. || m->lt[m->sellt]->arrange == &nrowgrid
  319. #endif // NROWGRID_LAYOUT
  320. #if FLEXTILE_DELUXE_LAYOUT
  321. || (m->lt[m->sellt]->arrange == &flextile && m->ltaxis[LAYOUT] == NO_SPLIT)
  322. #endif // FLEXTILE_DELUXE_LAYOUT
  323. )
  324. fulllayout = 1;
  325. num = tabw;
  326. c = m->clients;
  327. /* floating mode */
  328. if ((fulllayout && FLEXWINTITLE_FLOATWEIGHT > 0) || clientsnmaster + clientsnstack == 0 || !m->lt[m->sellt]->arrange) {
  329. den = clientsnmaster + clientsnstack + clientsnstack2 + clientsnfloating + clientsnhidden;
  330. w = num / den;
  331. r = num % den; // rest
  332. c = flextitledrawarea(m, c, mas_x, r, w, den, !m->lt[m->sellt]->arrange ? SchemeFlexActFloat : SCHEMEFOR(GRP_MASTER), 1, FLEXWINTITLE_HIDDENWEIGHT, FLEXWINTITLE_FLOATWEIGHT, passx, tabfn, arg, barg); // floating
  333. /* no master and stack mode, e.g. monocole, grid layouts, fibonacci */
  334. } else if (fulllayout) {
  335. den = clientsnmaster + clientsnstack + clientsnstack2 + clientsnhidden;
  336. w = num / den;
  337. r = num % den; // rest
  338. c = flextitledrawarea(m, c, mas_x, r, w, den, SCHEMEFOR(GRP_MASTER), 1, FLEXWINTITLE_HIDDENWEIGHT, 0, passx, tabfn, arg, barg); // full
  339. /* tiled mode */
  340. } else {
  341. den = clientsnmaster * FLEXWINTITLE_MASTERWEIGHT + (clientsnstack + clientsnstack2) * FLEXWINTITLE_STACKWEIGHT + clientsnfloating * FLEXWINTITLE_FLOATWEIGHT + clientsnhidden * FLEXWINTITLE_HIDDENWEIGHT;
  342. w = num / den; // weight width per client
  343. r = num % den; // weight rest width
  344. rw = r / n; // rest incr per client
  345. rr = r % n; // rest rest
  346. #if FLEXTILE_DELUXE_LAYOUT
  347. if ((!center && !dualstack) || (center && n <= m->nmaster + (m->nstack ? m->nstack : 1)))
  348. #else
  349. if ((!center && !dualstack) || (center && n <= m->nmaster + 1))
  350. #endif // FLEXTILE_DELUXE_LAYOUT
  351. {
  352. clientsnstack += clientsnstack2;
  353. clientsnstack2 = 0;
  354. if (groupactive == GRP_STACK2)
  355. groupactive = GRP_STACK1;
  356. }
  357. mas_w = clientsnmaster * rw + w * clientsnmaster * FLEXWINTITLE_MASTERWEIGHT + (rr > 0 ? MIN(rr, clientsnmaster) : 0);
  358. rr -= clientsnmaster;
  359. st1_w = clientsnstack * (rw + w * FLEXWINTITLE_STACKWEIGHT) + (rr > 0 ? MIN(rr, clientsnstack) : 0);
  360. rr -= clientsnstack;
  361. st2_w = clientsnstack2 * (rw + w * FLEXWINTITLE_STACKWEIGHT) + (rr > 0 ? MIN(rr, clientsnstack2) : 0);
  362. rr -= clientsnstack2;
  363. hid_w = clientsnhidden * (rw + w * FLEXWINTITLE_HIDDENWEIGHT) + (rr > 0 ? MIN(rr, clientsnhidden) : 0);
  364. rr -= clientsnhidden;
  365. rr = r % n;
  366. if (mirror) {
  367. if (center && clientsnstack2) {
  368. mas_x = st1_x + st1_w;
  369. st2_x = mas_x + mas_w;
  370. hid_x = st2_x + st2_w;
  371. } else {
  372. if (clientsnstack2) {
  373. st2_x = st1_x + st1_w;
  374. mas_x = st2_x + st2_w;
  375. } else
  376. mas_x = st1_x + st1_w;
  377. hid_x = mas_x + mas_w;
  378. }
  379. } else {
  380. if (center && clientsnstack2) {
  381. mas_x = st2_x + st2_w;
  382. st1_x = mas_x + mas_w;
  383. hid_x = st1_x + st1_w;
  384. } else {
  385. st1_x = mas_x + mas_w;
  386. if (clientsnstack2) {
  387. st2_x = st1_x + st1_w;
  388. hid_x = st2_x + st2_w;
  389. } else
  390. hid_x = st1_x + st1_w;
  391. }
  392. }
  393. flt_x = hid_x + hid_w;
  394. c = flextitledrawarea(m, c, mas_x, rr, w * FLEXWINTITLE_MASTERWEIGHT + rw, clientsnmaster, SCHEMEFOR(GRP_MASTER), 1, 0, 0, passx, tabfn, arg, barg); // master
  395. rr -= clientsnmaster;
  396. c = flextitledrawarea(m, c, st1_x, rr, w * FLEXWINTITLE_STACKWEIGHT + rw, clientsnstack, SCHEMEFOR(GRP_STACK1), 1, 0, 0, passx, tabfn, arg, barg); // stack1
  397. rr -= clientsnstack;
  398. if (clientsnstack2) {
  399. c = flextitledrawarea(m, c, st2_x, rr, w * FLEXWINTITLE_STACKWEIGHT + rw, clientsnstack2, SCHEMEFOR(GRP_STACK2), 1, 0, 0, passx, tabfn, arg, barg); // stack2
  400. rr -= clientsnstack2;
  401. }
  402. c = flextitledrawarea(m, m->clients, hid_x, rr, w * FLEXWINTITLE_HIDDENWEIGHT + rw, clientsnhidden, SCHEMEFOR(GRP_HIDDEN), 0, 1, 0, passx, tabfn, arg, barg); // hidden
  403. rr -= clientsnhidden;
  404. c = flextitledrawarea(m, m->clients, flt_x, rr, w * FLEXWINTITLE_FLOATWEIGHT + rw, clientsnfloating, SCHEMEFOR(GRP_FLOAT), 0, 0, 1, passx, tabfn, arg, barg); // floating
  405. }
  406. return 1;
  407. }