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.

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