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.

249 lines
4.4 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. drawstatus();
  149. if(!sel)
  150. return;
  151. if(sel->isfloating || lt->arrange == floating)
  152. XRaiseWindow(dpy, sel->win);
  153. if(lt->arrange != floating) {
  154. if(!sel->isfloating)
  155. XLowerWindow(dpy, sel->win);
  156. for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
  157. if(c == sel)
  158. continue;
  159. XLowerWindow(dpy, c->win);
  160. }
  161. }
  162. XSync(dpy, False);
  163. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  164. }
  165. void
  166. setlayout(const char *arg) {
  167. int i;
  168. if(!arg) {
  169. lt++;
  170. if(lt == layout + nlayouts)
  171. lt = layout;
  172. }
  173. else {
  174. i = atoi(arg);
  175. if(i < 0 || i >= nlayouts)
  176. return;
  177. lt = &layout[i];
  178. }
  179. if(sel)
  180. lt->arrange();
  181. else
  182. drawstatus();
  183. }
  184. void
  185. togglebar(const char *arg) {
  186. if(bpos == BarOff)
  187. bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
  188. else
  189. bpos = BarOff;
  190. updatebarpos();
  191. lt->arrange();
  192. }
  193. void
  194. togglemax(const char *arg) {
  195. XEvent ev;
  196. if(!sel || (lt->arrange != floating && !sel->isfloating) || sel->isfixed)
  197. return;
  198. if((sel->ismax = !sel->ismax)) {
  199. sel->rx = sel->x;
  200. sel->ry = sel->y;
  201. sel->rw = sel->w;
  202. sel->rh = sel->h;
  203. resize(sel, wax, way, waw - 2 * sel->border, wah - 2 * sel->border, True);
  204. }
  205. else
  206. resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
  207. drawstatus();
  208. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  209. }
  210. void
  211. zoom(const char *arg) {
  212. Client *c;
  213. if(!sel || lt->arrange == floating || sel->isfloating)
  214. return;
  215. if((c = sel) == nexttiled(clients))
  216. if(!(c = nexttiled(c->next)))
  217. return;
  218. detach(c);
  219. attach(c);
  220. focus(c);
  221. lt->arrange();
  222. }