JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
added some new convenience functions
[dwm.git] / tile.c
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
6 unsigned int master = MASTER;
7 unsigned int nmaster = NMASTER;
8
9 /* static */
10
11 static void
12 togglemax(Client *c) {
13         XEvent ev;
14
15         if(c->isfixed)
16                 return;
17         if((c->ismax = !c->ismax)) {
18                 c->rx = c->x;
19                 c->ry = c->y;
20                 c->rw = c->w;
21                 c->rh = c->h;
22                 resize(c, wax, way, waw - 2 * BORDERPX, wah - 2 * BORDERPX, True);
23         }
24         else
25                 resize(c, c->rx, c->ry, c->rw, c->rh, True);
26         while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
27 }
28
29 /* extern */
30
31 void
32 dotile(void) {
33         unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
34         Client *c;
35
36         for(n = 0, c = nextmanaged(clients); c; c = nextmanaged(c->next))
37                 n++;
38         /* window geoms */
39         mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
40         mw = (n > nmaster) ? (waw * master) / 1000 : waw;
41         th = (n > nmaster) ? wah / (n - nmaster) : 0;
42         tw = waw - mw;
43
44         for(i = 0, c = clients; c; c = c->next)
45                 if(isvisible(c)) {
46                         if(c->isbanned)
47                                 XMoveWindow(dpy, c->win, c->x, c->y);
48                         c->isbanned = False;
49                         if(c->isfloat)
50                                 continue;
51                         c->ismax = False;
52                         nx = wax;
53                         ny = way;
54                         if(i < nmaster) {
55                                 ny += i * mh;
56                                 nw = mw - 2 * BORDERPX;
57                                 nh = mh - 2 * BORDERPX;
58                         }
59                         else {  /* tile window */
60                                 nx += mw;
61                                 nw = tw - 2 * BORDERPX;
62                                 if(th > 2 * BORDERPX) {
63                                         ny += (i - nmaster) * th;
64                                         nh = th - 2 * BORDERPX;
65                                 }
66                                 else /* fallback if th <= 2 * BORDERPX */
67                                         nh = wah - 2 * BORDERPX;
68                         }
69                         resize(c, nx, ny, nw, nh, False);
70                         i++;
71                 }
72                 else {
73                         c->isbanned = True;
74                         XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
75                 }
76         if(!sel || !isvisible(sel)) {
77                 for(c = stack; c && !isvisible(c); c = c->snext);
78                 focus(c);
79         }
80         restack();
81 }
82
83 void
84 incnmaster(Arg *arg) {
85         if((arrange == dofloat) || (nmaster + arg->i < 1)
86         || (wah / (nmaster + arg->i) <= 2 * BORDERPX))
87                 return;
88         nmaster += arg->i;
89         if(sel)
90                 arrange();
91         else
92                 drawstatus();
93 }
94
95 void
96 resizemaster(Arg *arg) {
97         if(arrange != dotile)
98                 return;
99         if(arg->i == 0)
100                 master = MASTER;
101         else {
102                 if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
103                 || waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
104                         return;
105                 master += arg->i;
106         }
107         arrange();
108 }
109
110 void
111 zoom(Arg *arg) {
112         unsigned int n;
113         Client *c;
114
115         if(!sel)
116                 return;
117         if(sel->isfloat || (arrange == dofloat)) {
118                 togglemax(sel);
119                 return;
120         }
121         for(n = 0, c = nextmanaged(clients); c; c = nextmanaged(c->next))
122                 n++;
123
124         if((c = sel) == nextmanaged(clients))
125                 if(!(c = nextmanaged(c->next)))
126                         return;
127         detach(c);
128         attach(c);
129         focus(c);
130         arrange();
131 }