Xinqi Bao's Git

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