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.

319 lines
5.3 KiB

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