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.

371 lines
6.3 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. Bool isvertical = VERTICALSTACK;
  60. StackPos stackpos = STACKPOS;
  61. void
  62. detach(Client *c) {
  63. if(c->prev)
  64. c->prev->next = c->next;
  65. if(c->next)
  66. c->next->prev = c->prev;
  67. if(c == clients)
  68. clients = c->next;
  69. c->next = c->prev = NULL;
  70. }
  71. void
  72. dofloat(Arg *arg) {
  73. Client *c;
  74. for(c = clients; c; c = c->next) {
  75. if(isvisible(c)) {
  76. resize(c, True, TopLeft);
  77. }
  78. else
  79. ban(c);
  80. }
  81. if(!sel || !isvisible(sel)) {
  82. for(c = stack; c && !isvisible(c); c = c->snext);
  83. focus(c);
  84. }
  85. restack();
  86. }
  87. /* This algorithm is based on a (M)aster area and a (S)tacking area.
  88. * It supports following arrangements:
  89. * SSMMM MMMMM MMMSS
  90. * SSMMM SSSSS MMMSS
  91. */
  92. void
  93. dotile(Arg *arg) {
  94. int i, n, stackw, stackh, tw, th;
  95. Client *c;
  96. for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
  97. n++;
  98. if(stackpos == StackBottom) {
  99. stackw = sw;
  100. stackh = sh - bh - master;
  101. }
  102. else {
  103. stackw = sw - master;
  104. stackh = sh - bh;
  105. }
  106. if(isvertical) {
  107. tw = stackw;
  108. if(n > 1)
  109. th = stackh / (n - 1);
  110. else
  111. th = stackh;
  112. }
  113. else {
  114. th = stackh;
  115. if(n > 1)
  116. tw = stackw / (n - 1);
  117. else
  118. tw = stackw;
  119. }
  120. for(i = 0, c = clients; c; c = c->next) {
  121. if(isvisible(c)) {
  122. if(c->isfloat) {
  123. resize(c, True, TopLeft);
  124. continue;
  125. }
  126. c->ismax = False;
  127. if(n == 1) { /* only 1 window */
  128. c->x = sx;
  129. c->y = sy + bh;
  130. c->w = sw - 2 * BORDERPX;
  131. c->h = sh - 2 * BORDERPX - bh;
  132. }
  133. else if(i == 0) { /* master window */
  134. c->x = sx;
  135. if(stackpos == StackLeft)
  136. c->x += master;
  137. c->y = sy + bh;
  138. if(isvertical) {
  139. c->w = master - 2 * BORDERPX;
  140. c->h = sh - 2 * BORDERPX - bh;
  141. }
  142. else {
  143. c->w = sw;
  144. c->h = master - 2 * BORDERPX;
  145. }
  146. }
  147. else if((isvertical && th > bh) || (!isvertical && tw > MINW)) {
  148. /* tile window */
  149. c->x = sx;
  150. if(isvertical)
  151. c->y = sy + (i - 1) * th + bh;
  152. else
  153. c->y = sy + bh;
  154. if(stackpos == StackRight)
  155. c->x += master;
  156. else if(stackpos == StackBottom)
  157. c->y += master;
  158. c->w = tw - 2 * BORDERPX;
  159. c->h = th - 2 * BORDERPX;
  160. if(i + 1 == n) { /* fixes for last tile to take up rest space */
  161. if(isvertical)
  162. c->h = sh - c->y - 2 * BORDERPX;
  163. else {
  164. if(stackpos == StackLeft)
  165. c->w = master - c->x - 2 * BORDERPX;
  166. else
  167. c->w = sw - c->x - 2 * BORDERPX;
  168. }
  169. }
  170. }
  171. else { /* fallback if th < bh resp. tw < MINW */
  172. c->x = sx;
  173. c->y = sy + bh;
  174. if(stackpos == StackRight)
  175. c->x += master;
  176. else if(stackpos == StackBottom)
  177. c->y += master;
  178. c->w = stackw - 2 * BORDERPX;
  179. c->h = stackh - 2 * BORDERPX;
  180. }
  181. resize(c, False, TopLeft);
  182. i++;
  183. }
  184. else
  185. ban(c);
  186. }
  187. if(!sel || !isvisible(sel)) {
  188. for(c = stack; c && !isvisible(c); c = c->snext);
  189. focus(c);
  190. }
  191. restack();
  192. }
  193. void
  194. focusnext(Arg *arg) {
  195. Client *c;
  196. if(!sel)
  197. return;
  198. if(!(c = getnext(sel->next)))
  199. c = getnext(clients);
  200. if(c) {
  201. focus(c);
  202. restack();
  203. }
  204. }
  205. void
  206. focusprev(Arg *arg) {
  207. Client *c;
  208. if(!sel)
  209. return;
  210. if(!(c = getprev(sel->prev))) {
  211. for(c = clients; c && c->next; c = c->next);
  212. c = getprev(c);
  213. }
  214. if(c) {
  215. focus(c);
  216. restack();
  217. }
  218. }
  219. Bool
  220. isvisible(Client *c) {
  221. unsigned int i;
  222. for(i = 0; i < ntags; i++)
  223. if(c->tags[i] && seltag[i])
  224. return True;
  225. return False;
  226. }
  227. void
  228. resizecol(Arg *arg) {
  229. unsigned int n;
  230. Client *c;
  231. for(n = 0, c = clients; c; c = c->next)
  232. if(isvisible(c) && !c->isfloat)
  233. n++;
  234. if(!sel || sel->isfloat || n < 2 || (arrange == dofloat))
  235. return;
  236. if(sel == getnext(clients)) {
  237. if(master + arg->i > sw - MINW || master + arg->i < MINW)
  238. return;
  239. master += arg->i;
  240. }
  241. else {
  242. if(master - arg->i > sw - MINW || master - arg->i < MINW)
  243. return;
  244. master -= arg->i;
  245. }
  246. arrange(NULL);
  247. }
  248. void
  249. restack(void) {
  250. Client *c;
  251. XEvent ev;
  252. if(!sel) {
  253. drawstatus();
  254. return;
  255. }
  256. if(sel->isfloat || arrange == dofloat) {
  257. XRaiseWindow(dpy, sel->win);
  258. XRaiseWindow(dpy, sel->twin);
  259. }
  260. if(arrange != dofloat)
  261. for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
  262. XLowerWindow(dpy, c->twin);
  263. XLowerWindow(dpy, c->win);
  264. }
  265. drawall();
  266. XSync(dpy, False);
  267. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  268. }
  269. void
  270. togglemode(Arg *arg) {
  271. arrange = (arrange == dofloat) ? dotile : dofloat;
  272. if(sel)
  273. arrange(NULL);
  274. else
  275. drawstatus();
  276. }
  277. void
  278. toggleview(Arg *arg) {
  279. unsigned int i;
  280. seltag[arg->i] = !seltag[arg->i];
  281. for(i = 0; i < ntags && !seltag[i]; i++);
  282. if(i == ntags)
  283. seltag[arg->i] = True; /* cannot toggle last view */
  284. reorder();
  285. arrange(NULL);
  286. }
  287. void
  288. view(Arg *arg) {
  289. unsigned int i;
  290. for(i = 0; i < ntags; i++)
  291. seltag[i] = False;
  292. seltag[arg->i] = True;
  293. reorder();
  294. arrange(NULL);
  295. }
  296. void
  297. viewall(Arg *arg) {
  298. unsigned int i;
  299. for(i = 0; i < ntags; i++)
  300. seltag[i] = True;
  301. reorder();
  302. arrange(NULL);
  303. }
  304. void
  305. zoom(Arg *arg) {
  306. unsigned int n;
  307. Client *c;
  308. if(!sel)
  309. return;
  310. if(sel->isfloat || (arrange == dofloat)) {
  311. togglemax(sel);
  312. return;
  313. }
  314. for(n = 0, c = clients; c; c = c->next)
  315. if(isvisible(c) && !c->isfloat)
  316. n++;
  317. if(n < 2 || (arrange == dofloat))
  318. return;
  319. if((c = sel) == nexttiled(clients))
  320. if(!(c = nexttiled(c->next)))
  321. return;
  322. detach(c);
  323. if(clients)
  324. clients->prev = c;
  325. c->next = clients;
  326. clients = c;
  327. focus(c);
  328. arrange(NULL);
  329. }