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.

313 lines
4.5 KiB

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