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.

314 lines
5.2 KiB

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