Configuration of dwm for Mac Computers
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.

397 lines
6.7 KiB

18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
  1. /*
  2. * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
  3. * See LICENSE file for license details.
  4. */
  5. #include "dwm.h"
  6. /* static */
  7. static Client *
  8. minclient(void) {
  9. Client *c, *min;
  10. if((clients && clients->isfloat) || arrange == dofloat)
  11. return clients; /* don't touch floating order */
  12. for(min = c = clients; c; c = c->next)
  13. if(c->weight < min->weight)
  14. min = c;
  15. return min;
  16. }
  17. static Client *
  18. nexttiled(Client *c) {
  19. for(c = getnext(c); c && c->isfloat; c = getnext(c->next));
  20. return c;
  21. }
  22. static void
  23. reorder(void) {
  24. Client *c, *newclients, *tail;
  25. newclients = tail = NULL;
  26. while((c = minclient())) {
  27. detach(c);
  28. if(tail) {
  29. c->prev = tail;
  30. tail->next = c;
  31. tail = c;
  32. }
  33. else
  34. tail = newclients = c;
  35. }
  36. clients = newclients;
  37. }
  38. static void
  39. togglemax(Client *c)
  40. {
  41. XEvent ev;
  42. if((c->ismax = !c->ismax)) {
  43. c->rx = c->x; c->x = sx;
  44. c->ry = c->y; c->y = bh;
  45. c->rw = c->w; c->w = sw - 2 * BORDERPX;
  46. c->rh = c->h; c->h = sh - bh - 2 * BORDERPX;
  47. }
  48. else {
  49. c->x = c->rx;
  50. c->y = c->ry;
  51. c->w = c->rw;
  52. c->h = c->rh;
  53. }
  54. resize(c, True, TopLeft);
  55. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  56. }
  57. /* extern */
  58. void (*arrange)(Arg *) = DEFMODE;
  59. StackPos stackpos = STACKPOS;
  60. void
  61. detach(Client *c) {
  62. if(c->prev)
  63. c->prev->next = c->next;
  64. if(c->next)
  65. c->next->prev = c->prev;
  66. if(c == clients)
  67. clients = c->next;
  68. c->next = c->prev = NULL;
  69. }
  70. void
  71. dofloat(Arg *arg) {
  72. Client *c;
  73. for(c = clients; c; c = c->next) {
  74. if(isvisible(c)) {
  75. resize(c, True, TopLeft);
  76. }
  77. else
  78. ban(c);
  79. }
  80. if(!sel || !isvisible(sel)) {
  81. for(c = stack; c && !isvisible(c); c = c->snext);
  82. focus(c);
  83. }
  84. restack();
  85. }
  86. /* This algorithm is based on a (M)aster area and a (S)tacking area.
  87. * It supports following arrangements:
  88. * SSMMM MMMMM MMMSS
  89. * SSMMM SSSSS MMMSS
  90. */
  91. void
  92. dotile(Arg *arg) {
  93. int i, n, stackw, stackh, tw, th;
  94. Client *c;
  95. for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
  96. n++;
  97. if(stackpos == StackBottom) {
  98. stackw = sw;
  99. stackh = sh - bh - master;
  100. }
  101. else {
  102. stackw = sw - master;
  103. stackh = sh - bh;
  104. }
  105. tw = stackw;
  106. if(n > 1)
  107. th = stackh / (n - 1);
  108. else
  109. th = stackh;
  110. for(i = 0, c = clients; c; c = c->next) {
  111. if(isvisible(c)) {
  112. if(c->isfloat) {
  113. resize(c, True, TopLeft);
  114. continue;
  115. }
  116. c->ismax = False;
  117. if(n == 1) { /* only 1 window */
  118. c->x = sx;
  119. c->y = sy + bh;
  120. c->w = sw - 2 * BORDERPX;
  121. c->h = sh - 2 * BORDERPX - bh;
  122. }
  123. else if(i == 0) { /* master window */
  124. switch(stackpos) {
  125. case StackLeft:
  126. c->x = sx + stackw;
  127. c->y = sy + bh;
  128. c->w = master - 2 * BORDERPX;
  129. c->h = sh - bh - 2 * BORDERPX;
  130. break;
  131. case StackBottom:
  132. c->x = sx;
  133. c->y = sy + bh;
  134. c->w = sw - 2 * BORDERPX;
  135. c->h = master - 2 * BORDERPX;
  136. break;
  137. case StackRight:
  138. c->x = sx;
  139. c->y = sy + bh;
  140. c->w = master - 2 * BORDERPX;
  141. c->h = sh - bh - 2 * BORDERPX;
  142. break;
  143. }
  144. }
  145. else if(th > bh) {
  146. /* tile window */
  147. c->w = tw - 2 * BORDERPX;
  148. c->h = th - 2 * BORDERPX;
  149. switch(stackpos) {
  150. case StackLeft:
  151. c->x = sx;
  152. c->y = sy + (i - 1) * th + bh;
  153. if(i + 1 == n)
  154. c->h = sh - c->y - 2 * BORDERPX;
  155. break;
  156. case StackBottom:
  157. c->x = sx;
  158. c->y = sy + master + (i - 1) * th + bh;
  159. if(i + 1 == n)
  160. c->h = sh - c->y - 2 * BORDERPX;
  161. break;
  162. case StackRight:
  163. c->x = sx + master;
  164. c->y = sy + (i - 1) * th + bh;
  165. if(i + 1 == n)
  166. c->h = sh - c->y - 2 * BORDERPX;
  167. break;
  168. }
  169. }
  170. else { /* fallback if th < bh */
  171. c->w = stackw - 2 * BORDERPX;
  172. c->h = stackh - 2 * BORDERPX;
  173. switch(stackpos) {
  174. case StackLeft:
  175. c->x = sx;
  176. c->y = sy + bh;
  177. break;
  178. case StackBottom:
  179. c->x = sx;
  180. c->y = sy + master;
  181. break;
  182. case StackRight:
  183. c->x = sx + master;
  184. c->y = sy + bh;
  185. break;
  186. }
  187. }
  188. resize(c, False, TopLeft);
  189. i++;
  190. }
  191. else
  192. ban(c);
  193. }
  194. if(!sel || !isvisible(sel)) {
  195. for(c = stack; c && !isvisible(c); c = c->snext);
  196. focus(c);
  197. }
  198. restack();
  199. }
  200. void
  201. focusnext(Arg *arg) {
  202. Client *c;
  203. if(!sel)
  204. return;
  205. if(!(c = getnext(sel->next)))
  206. c = getnext(clients);
  207. if(c) {
  208. focus(c);
  209. restack();
  210. }
  211. }
  212. void
  213. focusprev(Arg *arg) {
  214. Client *c;
  215. if(!sel)
  216. return;
  217. if(!(c = getprev(sel->prev))) {
  218. for(c = clients; c && c->next; c = c->next);
  219. c = getprev(c);
  220. }
  221. if(c) {
  222. focus(c);
  223. restack();
  224. }
  225. }
  226. Bool
  227. isvisible(Client *c) {
  228. unsigned int i;
  229. for(i = 0; i < ntags; i++)
  230. if(c->tags[i] && seltag[i])
  231. return True;
  232. return False;
  233. }
  234. void
  235. resizecol(Arg *arg) {
  236. unsigned int n;
  237. Client *c;
  238. for(n = 0, c = clients; c; c = c->next)
  239. if(isvisible(c) && !c->isfloat)
  240. n++;
  241. if(!sel || sel->isfloat || n < 2 || (arrange == dofloat))
  242. return;
  243. if(sel == getnext(clients)) {
  244. if(master + arg->i > sw - MINW || master + arg->i < MINW)
  245. return;
  246. master += arg->i;
  247. }
  248. else {
  249. if(master - arg->i > sw - MINW || master - arg->i < MINW)
  250. return;
  251. master -= arg->i;
  252. }
  253. arrange(NULL);
  254. }
  255. void
  256. restack(void) {
  257. Client *c;
  258. XEvent ev;
  259. if(!sel) {
  260. drawstatus();
  261. return;
  262. }
  263. if(sel->isfloat || arrange == dofloat) {
  264. XRaiseWindow(dpy, sel->win);
  265. XRaiseWindow(dpy, sel->twin);
  266. }
  267. if(arrange != dofloat)
  268. for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
  269. XLowerWindow(dpy, c->twin);
  270. XLowerWindow(dpy, c->win);
  271. }
  272. drawall();
  273. XSync(dpy, False);
  274. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  275. }
  276. void
  277. togglemode(Arg *arg) {
  278. arrange = (arrange == dofloat) ? dotile : dofloat;
  279. if(sel)
  280. arrange(NULL);
  281. else
  282. drawstatus();
  283. }
  284. void
  285. toggleview(Arg *arg) {
  286. unsigned int i;
  287. seltag[arg->i] = !seltag[arg->i];
  288. for(i = 0; i < ntags && !seltag[i]; i++);
  289. if(i == ntags)
  290. seltag[arg->i] = True; /* cannot toggle last view */
  291. reorder();
  292. arrange(NULL);
  293. }
  294. void
  295. togglestackpos(Arg *arg) {
  296. if(arrange == dofloat)
  297. return;
  298. if(stackpos == StackBottom)
  299. stackpos = STACKPOS;
  300. else
  301. stackpos = StackBottom;
  302. updatemaster();
  303. arrange(NULL);
  304. }
  305. void
  306. updatemaster(void) {
  307. master = ((stackpos == StackBottom ? sh - bh : sw) * MASTER) / 100;
  308. }
  309. void
  310. view(Arg *arg) {
  311. unsigned int i;
  312. for(i = 0; i < ntags; i++)
  313. seltag[i] = False;
  314. seltag[arg->i] = True;
  315. reorder();
  316. arrange(NULL);
  317. }
  318. void
  319. viewall(Arg *arg) {
  320. unsigned int i;
  321. for(i = 0; i < ntags; i++)
  322. seltag[i] = True;
  323. reorder();
  324. arrange(NULL);
  325. }
  326. void
  327. zoom(Arg *arg) {
  328. unsigned int n;
  329. Client *c;
  330. if(!sel)
  331. return;
  332. if(sel->isfloat || (arrange == dofloat)) {
  333. togglemax(sel);
  334. return;
  335. }
  336. for(n = 0, c = clients; c; c = c->next)
  337. if(isvisible(c) && !c->isfloat)
  338. n++;
  339. if(n < 2 || (arrange == dofloat))
  340. return;
  341. if((c = sel) == nexttiled(clients))
  342. if(!(c = nexttiled(c->next)))
  343. return;
  344. detach(c);
  345. if(clients)
  346. clients->prev = c;
  347. c->next = clients;
  348. clients = c;
  349. focus(c);
  350. arrange(NULL);
  351. }