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.

255 lines
4.6 KiB

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