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.

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