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.

185 lines
3.4 KiB

  1. /* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
  2. * See LICENSE file for license details.
  3. */
  4. #include "dwm.h"
  5. unsigned int master = MASTER;
  6. unsigned int nmaster = NMASTER;
  7. unsigned int blw = 0;
  8. Layout *lt = NULL;
  9. /* static */
  10. static unsigned int nlayouts = 0;
  11. static void
  12. tile(void) {
  13. unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
  14. Client *c;
  15. for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
  16. n++;
  17. /* window geoms */
  18. mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
  19. mw = (n > nmaster) ? (waw * master) / 1000 : waw;
  20. th = (n > nmaster) ? wah / (n - nmaster) : 0;
  21. tw = waw - mw;
  22. for(i = 0, c = clients; c; c = c->next)
  23. if(isvisible(c)) {
  24. if(c->isbanned)
  25. XMoveWindow(dpy, c->win, c->x, c->y);
  26. c->isbanned = False;
  27. if(c->isversatile)
  28. continue;
  29. c->ismax = False;
  30. nx = wax;
  31. ny = way;
  32. if(i < nmaster) {
  33. ny += i * mh;
  34. nw = mw - 2 * BORDERPX;
  35. nh = mh - 2 * BORDERPX;
  36. }
  37. else { /* tile window */
  38. nx += mw;
  39. nw = tw - 2 * BORDERPX;
  40. if(th > 2 * BORDERPX) {
  41. ny += (i - nmaster) * th;
  42. nh = th - 2 * BORDERPX;
  43. }
  44. else /* fallback if th <= 2 * BORDERPX */
  45. nh = wah - 2 * BORDERPX;
  46. }
  47. resize(c, nx, ny, nw, nh, False);
  48. i++;
  49. }
  50. else {
  51. c->isbanned = True;
  52. XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
  53. }
  54. if(!sel || !isvisible(sel)) {
  55. for(c = stack; c && !isvisible(c); c = c->snext);
  56. focus(c);
  57. }
  58. restack();
  59. }
  60. LAYOUTS
  61. /* extern */
  62. void
  63. incnmaster(Arg *arg) {
  64. if((lt->arrange != tile) || (nmaster + arg->i < 1)
  65. || (wah / (nmaster + arg->i) <= 2 * BORDERPX))
  66. return;
  67. nmaster += arg->i;
  68. if(sel)
  69. lt->arrange();
  70. else
  71. drawstatus();
  72. }
  73. void
  74. initlayouts(void) {
  75. unsigned int i, w;
  76. lt = &layout[0];
  77. nlayouts = sizeof layout / sizeof layout[0];
  78. for(blw = i = 0; i < nlayouts; i++) {
  79. w = textw(layout[i].symbol);
  80. if(w > blw)
  81. blw = w;
  82. }
  83. }
  84. void
  85. resizemaster(Arg *arg) {
  86. if(lt->arrange != tile)
  87. return;
  88. if(arg->i == 0)
  89. master = MASTER;
  90. else {
  91. if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
  92. || waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
  93. return;
  94. master += arg->i;
  95. }
  96. lt->arrange();
  97. }
  98. void
  99. restack(void) {
  100. Client *c;
  101. XEvent ev;
  102. drawstatus();
  103. if(!sel)
  104. return;
  105. if(sel->isversatile || lt->arrange == versatile)
  106. XRaiseWindow(dpy, sel->win);
  107. if(lt->arrange != versatile) {
  108. if(!sel->isversatile)
  109. XLowerWindow(dpy, sel->win);
  110. for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
  111. if(c == sel)
  112. continue;
  113. XLowerWindow(dpy, c->win);
  114. }
  115. }
  116. XSync(dpy, False);
  117. while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  118. }
  119. void
  120. setlayout(Arg *arg) {
  121. unsigned int i;
  122. if(arg->i == -1) {
  123. for(i = 0; i < nlayouts && lt != &layout[i]; i++);
  124. if(i == nlayouts - 1)
  125. lt = &layout[0];
  126. else
  127. lt = &layout[++i];
  128. }
  129. else {
  130. if(arg->i < 0 || arg->i >= nlayouts)
  131. return;
  132. lt = &layout[arg->i];
  133. }
  134. if(sel)
  135. lt->arrange();
  136. else
  137. drawstatus();
  138. }
  139. void
  140. toggleversatile(Arg *arg) {
  141. if(!sel || lt->arrange == versatile)
  142. return;
  143. sel->isversatile = !sel->isversatile;
  144. lt->arrange();
  145. }
  146. void
  147. versatile(void) {
  148. Client *c;
  149. for(c = clients; c; c = c->next) {
  150. if(isvisible(c)) {
  151. if(c->isbanned)
  152. XMoveWindow(dpy, c->win, c->x, c->y);
  153. c->isbanned = False;
  154. resize(c, c->x, c->y, c->w, c->h, True);
  155. }
  156. else {
  157. c->isbanned = True;
  158. XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
  159. }
  160. }
  161. if(!sel || !isvisible(sel)) {
  162. for(c = stack; c && !isvisible(c); c = c->snext);
  163. focus(c);
  164. }
  165. restack();
  166. }