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