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.

270 lines
4.9 KiB

18 years ago
18 years ago
18 years ago
  1. /* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
  2. * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
  3. * © 2007 Premysl Hruby <dfenze at gmail dot com>
  4. * See LICENSE file for license details. */
  5. #include "dwm.h"
  6. #include <stdlib.h>
  7. unsigned int blw = 0;
  8. Layout *lt = NULL;
  9. /* static */
  10. static unsigned int nlayouts = 0;
  11. static unsigned int masterw = MASTERWIDTH;
  12. static unsigned int nmaster = NMASTER;
  13. static void
  14. ban(Client *c) {
  15. if (c->isbanned)
  16. return;
  17. XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
  18. c->isbanned = True;
  19. }
  20. static void
  21. unban(Client *c) {
  22. if (!c->isbanned)
  23. return;
  24. XMoveWindow(dpy, c->win, c->x, c->y);
  25. c->isbanned = False;
  26. }
  27. static void
  28. tile(void) {
  29. unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
  30. Client *c;
  31. for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
  32. n++;
  33. /* window geoms */
  34. mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
  35. mw = (n > nmaster) ? (waw * masterw) / 1000 : waw;
  36. th = (n > nmaster) ? wah / (n - nmaster) : 0;
  37. tw = waw - mw;
  38. for(i = 0, c = clients; c; c = c->next)
  39. if(isvisible(c)) {
  40. unban(c);
  41. if(c->isfloating)
  42. continue;
  43. c->ismax = False;
  44. nx = wax;
  45. ny = way;
  46. if(i < nmaster) {
  47. ny += i * mh;
  48. nw = mw - 2 * c->border;
  49. nh = mh;
  50. if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */
  51. nh = wah - mh * i;
  52. nh -= 2 * c->border;
  53. }
  54. else { /* tile window */
  55. nx += mw;
  56. nw = tw - 2 * c->border;
  57. if(th > 2 * c->border) {
  58. ny += (i - nmaster) * th;
  59. nh = th;
  60. if(i + 1 == n) /* remainder */
  61. nh = wah - th * (i - nmaster);
  62. nh -= 2 * c->border;
  63. }
  64. else /* fallback if th <= 2 * c->border */
  65. nh = wah - 2 * c->border;
  66. }
  67. resize(c, nx, ny, nw, nh, False);
  68. i++;
  69. }
  70. else
  71. ban(c);
  72. focus(NULL);
  73. restack();
  74. }
  75. LAYOUTS
  76. /* extern */
  77. void
  78. floating(void) {
  79. Client *c;
  80. for(c = clients; c; c = c->next)
  81. if(isvisible(c)) {
  82. if(c->isbanned)
  83. XMoveWindow(dpy, c->win, c->x, c->y);
  84. c->isbanned = False;
  85. resize(c, c->x, c->y, c->w, c->h, True);
  86. }
  87. else
  88. ban(c);
  89. focus(NULL);
  90. restack();
  91. }
  92. void
  93. focusclient(const char *arg) {
  94. Client *c;
  95. if(!sel || !arg)
  96. return;
  97. if(atoi(arg) < 0) {
  98. for(c = sel->prev; c && !isvisible(c); c = c->prev);
  99. if(!c) {
  100. for(c = clients; c && c->next; c = c->next);
  101. for(; c && !isvisible(c); c = c->prev);
  102. }
  103. }
  104. else {
  105. for(c = sel->next; c && !isvisible(c); c = c->next);
  106. if(!c)
  107. for(c = clients; c && !isvisible(c); c = c->next);
  108. }
  109. if(c) {
  110. focus(c);
  111. restack();
  112. }
  113. }
  114. void
  115. incmasterw(const char *arg) {
  116. int i;
  117. if(lt->arrange != tile)
  118. return;
  119. if(!arg)
  120. masterw = MASTERWIDTH;
  121. else {
  122. i = atoi(arg);
  123. if(waw * (masterw + i) / 1000 >= waw - 2 * BORDERPX
  124. || waw * (masterw + i) / 1000 <= 2 * BORDERPX)
  125. return;
  126. masterw += i;
  127. }
  128. lt->arrange();
  129. }
  130. void
  131. incnmaster(const char *arg) {
  132. int i;
  133. if(!arg)
  134. nmaster = NMASTER;
  135. else {
  136. i = atoi(arg);
  137. if((lt->arrange != tile) || (nmaster + i < 1)
  138. || (wah / (nmaster + i) <= 2 * BORDERPX))
  139. return;
  140. nmaster += i;
  141. }
  142. if(sel)
  143. lt->arrange();
  144. else
  145. drawstatus();
  146. }
  147. void
  148. initlayouts(void) {
  149. unsigned int i, w;
  150. lt = &layout[0];
  151. nlayouts = sizeof layout / sizeof layout[0];
  152. for(blw = i = 0; i < nlayouts; i++) {
  153. w = textw(layout[i].symbol);
  154. if(w > blw)
  155. blw = w;
  156. }
  157. }
  158. Client *
  159. nexttiled(Client *c) {
  160. for(; c && (c->isfloating || !isvisible(c)); c = c->next);
  161. return c;
  162. }
  163. void
  164. restack(void) {
  165. Client *c;
  166. XEvent ev;
  167. drawstatus();
  168. if(!sel)
  169. return;
  170. if(sel->isfloating || lt->arrange == floating)
  171. XRaiseWindow(dpy, sel->win);
  172. if(lt->arrange != floating) {
  173. if(!sel->isfloating)
  174. XLowerWindow(dpy, sel->win);
  175. for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
  176. if(c == sel)
  177. continue;
  178. XLowerWindow(dpy, c->win);
  179. }
  180. }
  181. XSync(dpy, False);
  182. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  183. }
  184. void
  185. setlayout(const char *arg) {
  186. int i;
  187. if(!arg) {
  188. lt++;
  189. if(lt == layout + nlayouts)
  190. lt = layout;
  191. }
  192. else {
  193. i = atoi(arg);
  194. if(i < 0 || i >= nlayouts)
  195. return;
  196. lt = &layout[i];
  197. }
  198. if(sel)
  199. lt->arrange();
  200. else
  201. drawstatus();
  202. }
  203. void
  204. togglebar(const char *arg) {
  205. if(bpos == BarOff)
  206. bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
  207. else
  208. bpos = BarOff;
  209. updatebarpos();
  210. lt->arrange();
  211. }
  212. void
  213. togglemax(const char *arg) {
  214. XEvent ev;
  215. if(!sel || (lt->arrange != floating && !sel->isfloating) || sel->isfixed)
  216. return;
  217. if((sel->ismax = !sel->ismax)) {
  218. sel->rx = sel->x;
  219. sel->ry = sel->y;
  220. sel->rw = sel->w;
  221. sel->rh = sel->h;
  222. resize(sel, wax, way, waw - 2 * BORDERPX, wah - 2 * BORDERPX, True);
  223. }
  224. else
  225. resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
  226. drawstatus();
  227. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  228. }
  229. void
  230. zoom(const char *arg) {
  231. Client *c;
  232. if(!sel || lt->arrange == floating || sel->isfloating)
  233. return;
  234. if((c = sel) == nexttiled(clients))
  235. if(!(c = nexttiled(c->next)))
  236. return;
  237. detach(c);
  238. attach(c);
  239. focus(c);
  240. lt->arrange();
  241. }