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.

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