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.

401 lines
6.8 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
  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 + bh;
  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. int s;
  237. unsigned int n;
  238. Client *c;
  239. for(n = 0, c = clients; c; c = c->next)
  240. if(isvisible(c) && !c->isfloat)
  241. n++;
  242. if(!sel || sel->isfloat || n < 2 || (arrange == dofloat))
  243. return;
  244. s = stackpos == StackBottom ? sh - bh : sw;
  245. if(sel == getnext(clients)) {
  246. if(master + arg->i > s - MINW || master + arg->i < MINW)
  247. return;
  248. master += arg->i;
  249. }
  250. else {
  251. if(master - arg->i > s - MINW || master - arg->i < MINW)
  252. return;
  253. master -= arg->i;
  254. }
  255. arrange(NULL);
  256. }
  257. void
  258. restack(void) {
  259. Client *c;
  260. XEvent ev;
  261. if(!sel) {
  262. drawstatus();
  263. return;
  264. }
  265. if(sel->isfloat || arrange == dofloat) {
  266. XRaiseWindow(dpy, sel->win);
  267. XRaiseWindow(dpy, sel->twin);
  268. }
  269. if(arrange != dofloat) {
  270. if(!sel->isfloat) {
  271. XLowerWindow(dpy, sel->twin);
  272. XLowerWindow(dpy, sel->win);
  273. }
  274. for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
  275. if(c == sel)
  276. continue;
  277. XLowerWindow(dpy, c->twin);
  278. XLowerWindow(dpy, c->win);
  279. }
  280. }
  281. drawall();
  282. XSync(dpy, False);
  283. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  284. }
  285. void
  286. togglemode(Arg *arg) {
  287. arrange = (arrange == dofloat) ? dotile : dofloat;
  288. if(sel)
  289. arrange(NULL);
  290. else
  291. drawstatus();
  292. }
  293. void
  294. toggleview(Arg *arg) {
  295. unsigned int i;
  296. seltag[arg->i] = !seltag[arg->i];
  297. for(i = 0; i < ntags && !seltag[i]; i++);
  298. if(i == ntags)
  299. seltag[arg->i] = True; /* cannot toggle last view */
  300. reorder();
  301. arrange(NULL);
  302. }
  303. void
  304. togglestackpos(Arg *arg) {
  305. if(arrange == dofloat)
  306. return;
  307. if(stackpos == StackBottom)
  308. stackpos = STACKPOS;
  309. else
  310. stackpos = StackBottom;
  311. master = ((stackpos == StackBottom ? sh - bh : sw) * MASTER) / 100;
  312. arrange(NULL);
  313. }
  314. void
  315. view(Arg *arg) {
  316. unsigned int i;
  317. for(i = 0; i < ntags; i++)
  318. seltag[i] = False;
  319. seltag[arg->i] = True;
  320. reorder();
  321. arrange(NULL);
  322. }
  323. void
  324. viewall(Arg *arg) {
  325. unsigned int i;
  326. for(i = 0; i < ntags; i++)
  327. seltag[i] = True;
  328. reorder();
  329. arrange(NULL);
  330. }
  331. void
  332. zoom(Arg *arg) {
  333. unsigned int n;
  334. Client *c;
  335. if(!sel)
  336. return;
  337. if(sel->isfloat || (arrange == dofloat)) {
  338. togglemax(sel);
  339. return;
  340. }
  341. for(n = 0, c = clients; c; c = c->next)
  342. if(isvisible(c) && !c->isfloat)
  343. n++;
  344. if(n < 2 || (arrange == dofloat))
  345. return;
  346. if((c = sel) == nexttiled(clients))
  347. if(!(c = nexttiled(c->next)))
  348. return;
  349. detach(c);
  350. if(clients)
  351. clients->prev = c;
  352. c->next = clients;
  353. clients = c;
  354. focus(c);
  355. arrange(NULL);
  356. }