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.

253 lines
3.8 KiB

  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. /* extern */
  7. void (*arrange)(Arg *) = DEFMODE;
  8. void
  9. dofloat(Arg *arg)
  10. {
  11. Client *c;
  12. for(c = clients; c; c = c->next) {
  13. c->ismax = False;
  14. if(isvisible(c)) {
  15. resize(c, True, TopLeft);
  16. }
  17. else
  18. ban(c);
  19. }
  20. if(!sel || !isvisible(sel))
  21. sel = getnext(clients);
  22. if(sel)
  23. focus(sel);
  24. else
  25. XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
  26. restack();
  27. }
  28. void
  29. dotile(Arg *arg)
  30. {
  31. int h, i, n, w;
  32. Client *c;
  33. w = sw - mw;
  34. for(n = 0, c = clients; c; c = c->next)
  35. if(isvisible(c) && !c->isfloat)
  36. n++;
  37. if(n > 1)
  38. h = (sh - bh) / (n - 1);
  39. else
  40. h = sh - bh;
  41. for(i = 0, c = clients; c; c = c->next) {
  42. c->ismax = False;
  43. if(isvisible(c)) {
  44. if(c->isfloat) {
  45. resize(c, True, TopLeft);
  46. continue;
  47. }
  48. if(n == 1) {
  49. c->x = sx;
  50. c->y = sy + bh;
  51. c->w = sw - 2;
  52. c->h = sh - 2 - bh;
  53. }
  54. else if(i == 0) {
  55. c->x = sx;
  56. c->y = sy + bh;
  57. c->w = mw - 2;
  58. c->h = sh - 2 - bh;
  59. }
  60. else if(h > bh) {
  61. c->x = sx + mw;
  62. c->y = sy + (i - 1) * h + bh;
  63. c->w = w - 2;
  64. if(i + 1 == n)
  65. c->h = sh - c->y - 2;
  66. else
  67. c->h = h - 2;
  68. }
  69. else { /* fallback if h < bh */
  70. c->x = sx + mw;
  71. c->y = sy + bh;
  72. c->w = w - 2;
  73. c->h = sh - 2 - bh;
  74. }
  75. resize(c, False, TopLeft);
  76. i++;
  77. }
  78. else
  79. ban(c);
  80. }
  81. if(!sel || !isvisible(sel))
  82. sel = getnext(clients);
  83. if(sel)
  84. focus(sel);
  85. else
  86. XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
  87. restack();
  88. }
  89. void
  90. focusnext(Arg *arg)
  91. {
  92. Client *c;
  93. if(!sel)
  94. return;
  95. if(!(c = getnext(sel->next)))
  96. c = getnext(clients);
  97. if(c) {
  98. focus(c);
  99. restack();
  100. }
  101. }
  102. void
  103. focusprev(Arg *arg)
  104. {
  105. Client *c;
  106. if(!sel)
  107. return;
  108. if(!(c = getprev(sel->prev))) {
  109. for(c = clients; c && c->next; c = c->next);
  110. c = getprev(c);
  111. }
  112. if(c) {
  113. focus(c);
  114. restack();
  115. }
  116. }
  117. Bool
  118. isvisible(Client *c)
  119. {
  120. unsigned int i;
  121. for(i = 0; i < ntags; i++)
  122. if(c->tags[i] && seltag[i])
  123. return True;
  124. return False;
  125. }
  126. void
  127. restack()
  128. {
  129. static unsigned int nwins = 0;
  130. static Window *wins = NULL;
  131. unsigned int f, fi, m, mi, n;
  132. Client *c;
  133. XEvent ev;
  134. for(f = 0, m = 0, c = clients; c; c = c->next)
  135. if(isvisible(c)) {
  136. if(c->isfloat || arrange == dofloat)
  137. f++;
  138. else
  139. m++;
  140. }
  141. if(!(n = 2 * (f + m))) {
  142. drawstatus();
  143. return;
  144. }
  145. if(nwins < n) {
  146. nwins = n;
  147. wins = erealloc(wins, nwins * sizeof(Window));
  148. }
  149. fi = 0;
  150. mi = 2 * f;
  151. if(sel->isfloat || arrange == dofloat) {
  152. wins[fi++] = sel->title;
  153. wins[fi++] = sel->win;
  154. }
  155. else {
  156. wins[mi++] = sel->title;
  157. wins[mi++] = sel->win;
  158. }
  159. for(c = clients; c; c = c->next)
  160. if(isvisible(c) && c != sel) {
  161. if(c->isfloat || arrange == dofloat) {
  162. wins[fi++] = c->title;
  163. wins[fi++] = c->win;
  164. }
  165. else {
  166. wins[mi++] = c->title;
  167. wins[mi++] = c->win;
  168. }
  169. }
  170. XRestackWindows(dpy, wins, n);
  171. drawall();
  172. XSync(dpy, False);
  173. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  174. }
  175. void
  176. togglemode(Arg *arg)
  177. {
  178. arrange = (arrange == dofloat) ? dotile : dofloat;
  179. if(sel)
  180. arrange(NULL);
  181. else
  182. drawstatus();
  183. }
  184. void
  185. toggleview(Arg *arg)
  186. {
  187. unsigned int i;
  188. seltag[arg->i] = !seltag[arg->i];
  189. for(i = 0; i < ntags && !seltag[i]; i++);
  190. if(i == ntags)
  191. seltag[arg->i] = True; /* cannot toggle last view */
  192. arrange(NULL);
  193. }
  194. void
  195. view(Arg *arg)
  196. {
  197. unsigned int i;
  198. for(i = 0; i < ntags; i++)
  199. seltag[i] = False;
  200. seltag[arg->i] = True;
  201. arrange(NULL);
  202. }
  203. void
  204. zoom(Arg *arg)
  205. {
  206. Client *c;
  207. if(!sel || (arrange != dotile) || sel->isfloat || sel->ismax)
  208. return;
  209. if(sel == getnext(clients)) {
  210. if((c = getnext(sel->next)))
  211. sel = c;
  212. else
  213. return;
  214. }
  215. /* pop */
  216. sel->prev->next = sel->next;
  217. if(sel->next)
  218. sel->next->prev = sel->prev;
  219. sel->prev = NULL;
  220. clients->prev = sel;
  221. sel->next = clients;
  222. clients = sel;
  223. focus(sel);
  224. arrange(NULL);
  225. }