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.

312 lines
4.6 KiB

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