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.

308 lines
4.5 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. focus(getnext(clients));
  69. restack();
  70. }
  71. void
  72. dotile(Arg *arg)
  73. {
  74. int h, i, n, w;
  75. Client *c;
  76. maximized = False;
  77. w = sw - mw;
  78. for(n = 0, c = clients; c; c = c->next)
  79. if(isvisible(c) && !c->isfloat)
  80. n++;
  81. if(n > 1)
  82. h = (sh - bh) / (n - 1);
  83. else
  84. h = sh - bh;
  85. for(i = 0, c = clients; c; c = c->next) {
  86. if(isvisible(c)) {
  87. if(c->isfloat) {
  88. resize(c, True, TopLeft);
  89. continue;
  90. }
  91. if(n == 1) {
  92. c->x = sx;
  93. c->y = sy + bh;
  94. c->w = sw - 2;
  95. c->h = sh - 2 - bh;
  96. }
  97. else if(i == 0) {
  98. c->x = sx;
  99. c->y = sy + bh;
  100. c->w = mw - 2;
  101. c->h = sh - 2 - bh;
  102. }
  103. else if(h > bh) {
  104. c->x = sx + mw;
  105. c->y = sy + (i - 1) * h + bh;
  106. c->w = w - 2;
  107. if(i + 1 == n)
  108. c->h = sh - c->y - 2;
  109. else
  110. c->h = h - 2;
  111. }
  112. else { /* fallback if h < bh */
  113. c->x = sx + mw;
  114. c->y = sy + bh;
  115. c->w = w - 2;
  116. c->h = sh - 2 - bh;
  117. }
  118. resize(c, False, TopLeft);
  119. i++;
  120. }
  121. else
  122. ban(c);
  123. }
  124. if(!sel || !isvisible(sel))
  125. focus(getnext(clients));
  126. restack();
  127. }
  128. void
  129. focusnext(Arg *arg)
  130. {
  131. Client *c;
  132. if(!sel)
  133. return;
  134. if(!(c = getnext(sel->next)))
  135. c = getnext(clients);
  136. if(c) {
  137. focus(c);
  138. restack();
  139. }
  140. }
  141. void
  142. focusprev(Arg *arg)
  143. {
  144. Client *c;
  145. if(!sel)
  146. return;
  147. if(!(c = getprev(sel->prev))) {
  148. for(c = clients; c && c->next; c = c->next);
  149. c = getprev(c);
  150. }
  151. if(c) {
  152. focus(c);
  153. restack();
  154. }
  155. }
  156. Bool
  157. isvisible(Client *c)
  158. {
  159. unsigned int i;
  160. for(i = 0; i < ntags; i++)
  161. if(c->tags[i] && seltag[i])
  162. return True;
  163. return False;
  164. }
  165. void
  166. resizecol(Arg *arg)
  167. {
  168. unsigned int n;
  169. Client *c;
  170. for(n = 0, c = clients; c; c = c->next)
  171. if(isvisible(c) && !c->isfloat)
  172. n++;
  173. if(!sel || sel->isfloat || n < 2 || (arrange != dotile) || maximized)
  174. return;
  175. if(sel == getnext(clients)) {
  176. if(mw + arg->i > sw - 100 || mw + arg->i < 100)
  177. return;
  178. mw += arg->i;
  179. }
  180. else {
  181. if(mw - arg->i > sw - 100 || mw - arg->i < 100)
  182. return;
  183. mw -= arg->i;
  184. }
  185. arrange(NULL);
  186. }
  187. void
  188. restack()
  189. {
  190. Client *c;
  191. XEvent ev;
  192. if(!sel) {
  193. drawstatus();
  194. return;
  195. }
  196. if(sel->isfloat || arrange == dofloat) {
  197. XRaiseWindow(dpy, sel->win);
  198. XRaiseWindow(dpy, sel->twin);
  199. }
  200. if(arrange != dofloat)
  201. for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
  202. XLowerWindow(dpy, c->twin);
  203. XLowerWindow(dpy, c->win);
  204. }
  205. drawall();
  206. XSync(dpy, False);
  207. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  208. }
  209. void
  210. togglemode(Arg *arg)
  211. {
  212. arrange = (arrange == dofloat) ? dotile : dofloat;
  213. if(sel)
  214. arrange(NULL);
  215. else
  216. drawstatus();
  217. }
  218. void
  219. toggleview(Arg *arg)
  220. {
  221. unsigned int i;
  222. seltag[arg->i] = !seltag[arg->i];
  223. for(i = 0; i < ntags && !seltag[i]; i++);
  224. if(i == ntags)
  225. seltag[arg->i] = True; /* cannot toggle last view */
  226. reorder();
  227. arrange(NULL);
  228. }
  229. void
  230. view(Arg *arg)
  231. {
  232. unsigned int i;
  233. for(i = 0; i < ntags; i++)
  234. seltag[i] = False;
  235. seltag[arg->i] = True;
  236. reorder();
  237. arrange(NULL);
  238. }
  239. void
  240. viewall(Arg *arg)
  241. {
  242. unsigned int i;
  243. for(i = 0; i < ntags; i++)
  244. seltag[i] = True;
  245. reorder();
  246. arrange(NULL);
  247. }
  248. void
  249. zoom(Arg *arg)
  250. {
  251. unsigned int n;
  252. Client *c;
  253. for(n = 0, c = clients; c; c = c->next)
  254. if(isvisible(c) && !c->isfloat)
  255. n++;
  256. if(!sel || sel->isfloat || n < 2 || (arrange != dotile) || maximized)
  257. return;
  258. if((c = sel) == nexttiled(clients))
  259. if(!(c = nexttiled(c->next)))
  260. return;
  261. detach(c);
  262. if(clients)
  263. clients->prev = c;
  264. c->next = clients;
  265. clients = c;
  266. focus(c);
  267. arrange(NULL);
  268. }