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.

282 lines
4.2 KiB

19 years ago
19 years ago
19 years ago
19 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. /* extern */
  7. void (*arrange)(Arg *) = DEFMODE;
  8. void
  9. attach(Client *c)
  10. {
  11. Client *first = getnext(clients);
  12. if(!first) {
  13. if(clients) {
  14. for(first = clients; first->next; first = first->next);
  15. first->next = c;
  16. c->prev = first;
  17. }
  18. else
  19. clients = c;
  20. }
  21. else if(first == clients) {
  22. c->next = clients;
  23. clients->prev = c;
  24. clients = c;
  25. }
  26. else {
  27. first->prev->next = c;
  28. c->prev = first->prev;
  29. first->prev = c;
  30. c->next = first;
  31. }
  32. }
  33. void
  34. detach(Client *c)
  35. {
  36. if(c->prev)
  37. c->prev->next = c->next;
  38. if(c->next)
  39. c->next->prev = c->prev;
  40. if(c == clients)
  41. clients = c->next;
  42. c->next = c->prev = NULL;
  43. }
  44. void
  45. dofloat(Arg *arg)
  46. {
  47. Client *c;
  48. for(c = clients; c; c = c->next) {
  49. c->ismax = False;
  50. if(isvisible(c)) {
  51. resize(c, True, TopLeft);
  52. }
  53. else
  54. ban(c);
  55. }
  56. if(!sel || !isvisible(sel))
  57. sel = getnext(clients);
  58. if(sel)
  59. focus(sel);
  60. else
  61. XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
  62. restack();
  63. }
  64. void
  65. dotile(Arg *arg)
  66. {
  67. int h, i, n, w;
  68. Client *c;
  69. w = sw - mw;
  70. for(n = 0, c = clients; c; c = c->next)
  71. if(isvisible(c) && !c->isfloat)
  72. n++;
  73. if(n > 1)
  74. h = (sh - bh) / (n - 1);
  75. else
  76. h = sh - bh;
  77. for(i = 0, c = clients; c; c = c->next) {
  78. c->ismax = False;
  79. if(isvisible(c)) {
  80. if(c->isfloat) {
  81. resize(c, True, TopLeft);
  82. continue;
  83. }
  84. if(n == 1) {
  85. c->x = sx;
  86. c->y = sy + bh;
  87. c->w = sw - 2;
  88. c->h = sh - 2 - bh;
  89. }
  90. else if(i == 0) {
  91. c->x = sx;
  92. c->y = sy + bh;
  93. c->w = mw - 2;
  94. c->h = sh - 2 - bh;
  95. }
  96. else if(h > bh) {
  97. c->x = sx + mw;
  98. c->y = sy + (i - 1) * h + bh;
  99. c->w = w - 2;
  100. if(i + 1 == n)
  101. c->h = sh - c->y - 2;
  102. else
  103. c->h = h - 2;
  104. }
  105. else { /* fallback if h < bh */
  106. c->x = sx + mw;
  107. c->y = sy + bh;
  108. c->w = w - 2;
  109. c->h = sh - 2 - bh;
  110. }
  111. resize(c, False, TopLeft);
  112. i++;
  113. }
  114. else
  115. ban(c);
  116. }
  117. if(!sel || !isvisible(sel))
  118. sel = getnext(clients);
  119. if(sel)
  120. focus(sel);
  121. else
  122. XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
  123. restack();
  124. }
  125. void
  126. focusnext(Arg *arg)
  127. {
  128. Client *c;
  129. if(!sel)
  130. return;
  131. if(!(c = getnext(sel->next)))
  132. c = getnext(clients);
  133. if(c) {
  134. focus(c);
  135. restack();
  136. }
  137. }
  138. void
  139. focusprev(Arg *arg)
  140. {
  141. Client *c;
  142. if(!sel)
  143. return;
  144. if(!(c = getprev(sel->prev))) {
  145. for(c = clients; c && c->next; c = c->next);
  146. c = getprev(c);
  147. }
  148. if(c) {
  149. focus(c);
  150. restack();
  151. }
  152. }
  153. Bool
  154. isvisible(Client *c)
  155. {
  156. unsigned int i;
  157. for(i = 0; i < ntags; i++)
  158. if(c->tags[i] && seltag[i])
  159. return True;
  160. return False;
  161. }
  162. void
  163. restack()
  164. {
  165. static unsigned int nwins = 0;
  166. static Window *wins = NULL;
  167. unsigned int f, fi, m, mi, n;
  168. Client *c;
  169. XEvent ev;
  170. for(f = 0, m = 0, c = clients; c; c = c->next)
  171. if(isvisible(c)) {
  172. if(c->isfloat || arrange == dofloat)
  173. f++;
  174. else
  175. m++;
  176. }
  177. if(!(n = 2 * (f + m))) {
  178. drawstatus();
  179. return;
  180. }
  181. if(nwins < n) {
  182. nwins = n;
  183. wins = erealloc(wins, nwins * sizeof(Window));
  184. }
  185. fi = 0;
  186. mi = 2 * f;
  187. if(sel->isfloat || arrange == dofloat) {
  188. wins[fi++] = sel->twin;
  189. wins[fi++] = sel->win;
  190. }
  191. else {
  192. wins[mi++] = sel->twin;
  193. wins[mi++] = sel->win;
  194. }
  195. for(c = clients; c; c = c->next)
  196. if(isvisible(c) && c != sel) {
  197. if(c->isfloat || arrange == dofloat) {
  198. wins[fi++] = c->twin;
  199. wins[fi++] = c->win;
  200. }
  201. else {
  202. wins[mi++] = c->twin;
  203. wins[mi++] = c->win;
  204. }
  205. }
  206. XRestackWindows(dpy, wins, n);
  207. drawall();
  208. XSync(dpy, False);
  209. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  210. }
  211. void
  212. togglemode(Arg *arg)
  213. {
  214. arrange = (arrange == dofloat) ? dotile : dofloat;
  215. if(sel)
  216. arrange(NULL);
  217. else
  218. drawstatus();
  219. }
  220. void
  221. toggleview(Arg *arg)
  222. {
  223. unsigned int i;
  224. seltag[arg->i] = !seltag[arg->i];
  225. for(i = 0; i < ntags && !seltag[i]; i++);
  226. if(i == ntags)
  227. seltag[arg->i] = True; /* cannot toggle last view */
  228. arrange(NULL);
  229. }
  230. void
  231. view(Arg *arg)
  232. {
  233. unsigned int i;
  234. for(i = 0; i < ntags; i++)
  235. seltag[i] = False;
  236. seltag[arg->i] = True;
  237. arrange(NULL);
  238. }
  239. void
  240. zoom(Arg *arg)
  241. {
  242. Client *c = sel;
  243. if(!c || (arrange != dotile) || c->isfloat || c->ismax)
  244. return;
  245. if(c == getnext(clients))
  246. if(!(c = getnext(c->next)))
  247. return;
  248. detach(c);
  249. attach(c);
  250. focus(c);
  251. arrange(NULL);
  252. }