Configuration file for DWM on MacBook Air
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.

298 lines
5.6 KiB

  1. /* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
  2. * See LICENSE file for license details.
  3. */
  4. #include "dwm.h"
  5. #include <regex.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <sys/types.h>
  10. #include <X11/Xutil.h>
  11. void (*arrange)(void) = DEFMODE;
  12. unsigned int master = MASTER;
  13. unsigned int nmaster = NMASTER;
  14. /* static */
  15. typedef struct {
  16. const char *prop;
  17. const char *tags;
  18. Bool isfloat;
  19. } Rule;
  20. typedef struct {
  21. regex_t *propregex;
  22. regex_t *tagregex;
  23. } Regexps;
  24. TAGS
  25. RULES
  26. static Regexps *regexps = NULL;
  27. static unsigned int len = 0;
  28. /* extern */
  29. void
  30. compileregexps(void) {
  31. unsigned int i;
  32. regex_t *reg;
  33. if(regexps)
  34. return;
  35. len = sizeof rule / sizeof rule[0];
  36. regexps = emallocz(len * sizeof(Regexps));
  37. for(i = 0; i < len; i++) {
  38. if(rule[i].prop) {
  39. reg = emallocz(sizeof(regex_t));
  40. if(regcomp(reg, rule[i].prop, REG_EXTENDED))
  41. free(reg);
  42. else
  43. regexps[i].propregex = reg;
  44. }
  45. if(rule[i].tags) {
  46. reg = emallocz(sizeof(regex_t));
  47. if(regcomp(reg, rule[i].tags, REG_EXTENDED))
  48. free(reg);
  49. else
  50. regexps[i].tagregex = reg;
  51. }
  52. }
  53. }
  54. void
  55. dofloat(void) {
  56. Client *c;
  57. for(c = clients; c; c = c->next) {
  58. if(isvisible(c)) {
  59. if(c->isbanned)
  60. XMoveWindow(dpy, c->win, c->x, c->y);
  61. c->isbanned = False;
  62. resize(c, c->x, c->y, c->w, c->h, True);
  63. }
  64. else {
  65. c->isbanned = True;
  66. XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
  67. }
  68. }
  69. if(!sel || !isvisible(sel)) {
  70. for(c = stack; c && !isvisible(c); c = c->snext);
  71. focus(c);
  72. }
  73. restack();
  74. }
  75. void
  76. dotile(void) {
  77. unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
  78. Client *c;
  79. for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
  80. n++;
  81. /* window geoms */
  82. mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
  83. mw = (n > nmaster) ? (waw * master) / 1000 : waw;
  84. th = (n > nmaster) ? wah / (n - nmaster) : 0;
  85. tw = waw - mw;
  86. for(i = 0, c = clients; c; c = c->next)
  87. if(isvisible(c)) {
  88. if(c->isbanned)
  89. XMoveWindow(dpy, c->win, c->x, c->y);
  90. c->isbanned = False;
  91. if(c->isfloat)
  92. continue;
  93. c->ismax = False;
  94. nx = wax;
  95. ny = way;
  96. if(i < nmaster) {
  97. ny += i * mh;
  98. nw = mw - 2 * BORDERPX;
  99. nh = mh - 2 * BORDERPX;
  100. }
  101. else { /* tile window */
  102. nx += mw;
  103. nw = tw - 2 * BORDERPX;
  104. if(th > 2 * BORDERPX) {
  105. ny += (i - nmaster) * th;
  106. nh = th - 2 * BORDERPX;
  107. }
  108. else /* fallback if th <= 2 * BORDERPX */
  109. nh = wah - 2 * BORDERPX;
  110. }
  111. resize(c, nx, ny, nw, nh, False);
  112. i++;
  113. }
  114. else {
  115. c->isbanned = True;
  116. XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
  117. }
  118. if(!sel || !isvisible(sel)) {
  119. for(c = stack; c && !isvisible(c); c = c->snext);
  120. focus(c);
  121. }
  122. restack();
  123. }
  124. void
  125. incnmaster(Arg *arg) {
  126. if((arrange == dofloat) || (nmaster + arg->i < 1)
  127. || (wah / (nmaster + arg->i) <= 2 * BORDERPX))
  128. return;
  129. nmaster += arg->i;
  130. if(sel)
  131. arrange();
  132. else
  133. drawstatus();
  134. }
  135. Bool
  136. isvisible(Client *c) {
  137. unsigned int i;
  138. for(i = 0; i < ntags; i++)
  139. if(c->tags[i] && seltag[i])
  140. return True;
  141. return False;
  142. }
  143. void
  144. resizemaster(Arg *arg) {
  145. if(arrange != dotile)
  146. return;
  147. if(arg->i == 0)
  148. master = MASTER;
  149. else {
  150. if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
  151. || waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
  152. return;
  153. master += arg->i;
  154. }
  155. arrange();
  156. }
  157. void
  158. restack(void) {
  159. Client *c;
  160. XEvent ev;
  161. drawstatus();
  162. if(!sel)
  163. return;
  164. if(sel->isfloat || arrange == dofloat)
  165. XRaiseWindow(dpy, sel->win);
  166. if(arrange != dofloat) {
  167. if(!sel->isfloat)
  168. XLowerWindow(dpy, sel->win);
  169. for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
  170. if(c == sel)
  171. continue;
  172. XLowerWindow(dpy, c->win);
  173. }
  174. }
  175. XSync(dpy, False);
  176. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  177. }
  178. void
  179. settags(Client *c, Client *trans) {
  180. char prop[512];
  181. unsigned int i, j;
  182. regmatch_t tmp;
  183. Bool matched = trans != NULL;
  184. XClassHint ch = { 0 };
  185. if(matched)
  186. for(i = 0; i < ntags; i++)
  187. c->tags[i] = trans->tags[i];
  188. else {
  189. XGetClassHint(dpy, c->win, &ch);
  190. snprintf(prop, sizeof prop, "%s:%s:%s",
  191. ch.res_class ? ch.res_class : "",
  192. ch.res_name ? ch.res_name : "", c->name);
  193. for(i = 0; i < len; i++)
  194. if(regexps[i].propregex && !regexec(regexps[i].propregex, prop, 1, &tmp, 0)) {
  195. c->isfloat = rule[i].isfloat;
  196. for(j = 0; regexps[i].tagregex && j < ntags; j++) {
  197. if(!regexec(regexps[i].tagregex, tags[j], 1, &tmp, 0)) {
  198. matched = True;
  199. c->tags[j] = True;
  200. }
  201. }
  202. }
  203. if(ch.res_class)
  204. XFree(ch.res_class);
  205. if(ch.res_name)
  206. XFree(ch.res_name);
  207. }
  208. if(!matched)
  209. for(i = 0; i < ntags; i++)
  210. c->tags[i] = seltag[i];
  211. }
  212. void
  213. tag(Arg *arg) {
  214. unsigned int i;
  215. if(!sel)
  216. return;
  217. for(i = 0; i < ntags; i++)
  218. sel->tags[i] = (arg->i == -1) ? True : False;
  219. if(arg->i >= 0 && arg->i < ntags)
  220. sel->tags[arg->i] = True;
  221. arrange();
  222. }
  223. void
  224. togglefloat(Arg *arg) {
  225. if(!sel || arrange == dofloat)
  226. return;
  227. sel->isfloat = !sel->isfloat;
  228. arrange();
  229. }
  230. void
  231. toggletag(Arg *arg) {
  232. unsigned int i;
  233. if(!sel)
  234. return;
  235. sel->tags[arg->i] = !sel->tags[arg->i];
  236. for(i = 0; i < ntags && !sel->tags[i]; i++);
  237. if(i == ntags)
  238. sel->tags[arg->i] = True;
  239. arrange();
  240. }
  241. void
  242. togglemode(Arg *arg) {
  243. arrange = (arrange == dofloat) ? dotile : dofloat;
  244. if(sel)
  245. arrange();
  246. else
  247. drawstatus();
  248. }
  249. void
  250. toggleview(Arg *arg) {
  251. unsigned int i;
  252. seltag[arg->i] = !seltag[arg->i];
  253. for(i = 0; i < ntags && !seltag[i]; i++);
  254. if(i == ntags)
  255. seltag[arg->i] = True; /* cannot toggle last view */
  256. arrange();
  257. }
  258. void
  259. view(Arg *arg) {
  260. unsigned int i;
  261. for(i = 0; i < ntags; i++)
  262. seltag[i] = (arg->i == -1) ? True : False;
  263. if(arg->i >= 0 && arg->i < ntags)
  264. seltag[arg->i] = True;
  265. arrange();
  266. }