Mercurial > hg > index.fcgi > dwm > dwm-3.6.1-10pba
comparison layout.c @ 0:7024076fa948
initial add
author | paulo@localhost |
---|---|
date | Sun, 22 Mar 2009 23:26:35 -0700 |
parents | |
children | ba504f41828f |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1bcc3572197d |
---|---|
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 unsigned int blw = 0; | |
9 Layout *lt = NULL; | |
10 | |
11 /* static */ | |
12 | |
13 static unsigned int nlayouts = 0; | |
14 | |
15 static void | |
16 spiral(void) { | |
17 unsigned int i, n, nx, ny, nw, nh; | |
18 Client *c; | |
19 | |
20 nx = wax; | |
21 ny = way + wah; | |
22 nw = waw; | |
23 nh = wah; | |
24 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) | |
25 n++; | |
26 for(i = 0, c = clients; c; c = c->next) | |
27 if(isvisible(c)) { | |
28 if(c->isbanned) | |
29 XMoveWindow(dpy, c->win, c->x, c->y); | |
30 c->isbanned = False; | |
31 if(c->isversatile) | |
32 continue; | |
33 c->ismax = False; | |
34 if((i % 2 && nh / 2 > 2 * c->border) | |
35 || (!(i % 2) && nw / 2 > 2 * c->border)) | |
36 { | |
37 if(i < n - 1) { | |
38 if(i % 2) | |
39 nh /= 2; | |
40 else | |
41 nw /= 2; | |
42 if((i % 4) == 2) | |
43 nx += nw; | |
44 else if((i % 4) == 3) | |
45 ny += nh; | |
46 } | |
47 if((i % 4) == 0) | |
48 ny -= nh; | |
49 else if((i % 4) == 1) | |
50 nx += nw; | |
51 else if((i % 4) == 2) | |
52 ny += nh; | |
53 else | |
54 nx -= nw; | |
55 i++; | |
56 } | |
57 resize(c, nx, ny, nw - 2 * c->border, nh - 2 * c->border, False); | |
58 } | |
59 else { | |
60 c->isbanned = True; | |
61 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); | |
62 } | |
63 if(!sel || !isvisible(sel)) { | |
64 for(c = stack; c && !isvisible(c); c = c->snext); | |
65 focus(c); | |
66 } | |
67 restack(); | |
68 } | |
69 | |
70 static void | |
71 spiral_h(void) { | |
72 unsigned int i, n, nx, ny, nw, nh; | |
73 Client *c; | |
74 | |
75 nx = wax + waw; | |
76 ny = way; | |
77 nw = waw; | |
78 nh = wah; | |
79 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) | |
80 n++; | |
81 for(i = 0, c = clients; c; c = c->next) | |
82 if(isvisible(c)) { | |
83 if(c->isbanned) | |
84 XMoveWindow(dpy, c->win, c->x, c->y); | |
85 c->isbanned = False; | |
86 if(c->isversatile) | |
87 continue; | |
88 c->ismax = False; | |
89 if((i % 2 && nw / 2 > 2 * c->border) | |
90 || (!(i % 2) && nh / 2 > 2 * c->border)) | |
91 { | |
92 if(i < n - 1) { | |
93 if(i % 2) | |
94 nw /= 2; | |
95 else | |
96 nh /= 2; | |
97 if((i % 4) == 2) | |
98 ny += nh; | |
99 else if((i % 4) == 3) | |
100 nx += nw; | |
101 } | |
102 if((i % 4) == 0) | |
103 nx -= nw; | |
104 else if((i % 4) == 1) | |
105 ny += nh; | |
106 else if((i % 4) == 2) | |
107 nx += nw; | |
108 else | |
109 ny -= nh; | |
110 i++; | |
111 } | |
112 resize(c, nx, ny, nw - 2 * c->border, nh - 2 * c->border, False); | |
113 } | |
114 else { | |
115 c->isbanned = True; | |
116 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); | |
117 } | |
118 if(!sel || !isvisible(sel)) { | |
119 for(c = stack; c && !isvisible(c); c = c->snext); | |
120 focus(c); | |
121 } | |
122 restack(); | |
123 } | |
124 | |
125 static void | |
126 monocle(void) { | |
127 Client *c; | |
128 | |
129 for(c = clients; c; c = c->next) | |
130 if(isvisible(c) && c->isbanned) { | |
131 XMoveWindow(dpy, c->win, c->x, c->y); | |
132 c->isbanned = False; | |
133 } | |
134 else if(!isvisible(c)) { | |
135 c->isbanned = True; | |
136 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); | |
137 } | |
138 | |
139 for(c = nexttiled(clients); c; c = nexttiled(c->next)) | |
140 resize(c, wax, way, waw - 2*c->border, wah - 2*c->border, False); | |
141 | |
142 restack(); | |
143 } | |
144 | |
145 static void | |
146 cascade(void) { | |
147 unsigned int i, n, px = 20; | |
148 Client *c; | |
149 | |
150 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), n++); | |
151 | |
152 for(i = 0, c = clients; c; c = c->next) | |
153 if(isvisible(c)) { | |
154 if(c->isbanned) { | |
155 XMoveWindow(dpy, c->win, c->x, c->y); | |
156 c->isbanned = False; | |
157 } | |
158 if(!c->isversatile) { | |
159 resize(c, wax+(px*i), way+(px*i), waw-(px*(n-1))-2*c->border, wah-(px*(n-1))-2*c->border, True); | |
160 i++; | |
161 } | |
162 } | |
163 else if(!isvisible(c)) { | |
164 c->isbanned = True; | |
165 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); | |
166 } | |
167 | |
168 restack(); | |
169 } | |
170 | |
171 static void | |
172 bstack(void) { | |
173 unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th; | |
174 Client *c; | |
175 | |
176 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) | |
177 n++; | |
178 /* window geoms */ | |
179 mh = (n > nmaster) ? (wah * master) / 1000 : wah; | |
180 mw = (n > nmaster) ? waw / nmaster : waw / (n > 0 ? n : 1); | |
181 th = wah - mh; | |
182 tw = (n > nmaster) ? waw / (n - nmaster) : 0; | |
183 | |
184 for(i = 0, c = clients; c; c = c->next) | |
185 if(isvisible(c)) { | |
186 if(c->isbanned) | |
187 XMoveWindow(dpy, c->win, c->x, c->y); | |
188 c->isbanned = False; | |
189 if(c->isversatile) | |
190 continue; | |
191 c->ismax = False; | |
192 nx = wax; | |
193 ny = way; | |
194 if(i < nmaster) { | |
195 nx += i * mw; | |
196 nw = mw - 2 * BORDERPX; | |
197 nh = mh - 2 * BORDERPX; | |
198 } | |
199 else { /* tile window */ | |
200 ny += mh; | |
201 nh = th - 2 * BORDERPX; | |
202 if(tw > 2 * BORDERPX) { | |
203 nx += (i - nmaster) * tw; | |
204 nw = tw - 2 * BORDERPX; | |
205 } | |
206 else /* fallback if th <= 2 * BORDERPX */ | |
207 nw = waw - 2 * BORDERPX; | |
208 } | |
209 resize(c, nx, ny, nw, nh, False); | |
210 i++; | |
211 } | |
212 else { | |
213 c->isbanned = True; | |
214 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); | |
215 } | |
216 if(!sel || !isvisible(sel)) { | |
217 for(c = stack; c && !isvisible(c); c = c->snext); | |
218 focus(c); | |
219 } | |
220 restack(); | |
221 } | |
222 | |
223 static void | |
224 grid(void) { | |
225 unsigned int i, n, nx, ny, nw, nh, aw, ah, tw, th, cols, rows; | |
226 Client *c; | |
227 | |
228 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) | |
229 n++; | |
230 | |
231 for(rows = 0; rows <= n/2; rows++) | |
232 if(rows*rows >= n) | |
233 break; | |
234 cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows; | |
235 | |
236 th = (sh - dc.h) / (rows ? rows : 1); | |
237 tw = sw / (cols ? cols : 1); | |
238 nw = tw - 2 * BORDERPX; | |
239 nh = th - 2 * BORDERPX; | |
240 | |
241 for(i = 0, c = clients; c; c = c->next) | |
242 if(isvisible(c)) { | |
243 if(c->isbanned) | |
244 XMoveWindow(dpy, c->win, c->x, c->y); | |
245 c->isbanned = False; | |
246 if(c->isversatile) | |
247 continue; | |
248 c->ismax = False; | |
249 nx = (i / rows) * tw; | |
250 ny = (i % rows) * th + (TOPBAR ? dc.h : 0); | |
251 /* adjust height and width of last row's and last column's windows */ | |
252 ah = ((i + 1) % rows == 0) ? sh - th * rows - dc.h : 0; | |
253 aw = (i >= rows * (cols - 1)) ? sw - tw * cols : 0; | |
254 resize(c, nx, ny, nw + aw, nh + ah, False); | |
255 i++; | |
256 } | |
257 else { | |
258 c->isbanned = True; | |
259 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); | |
260 } | |
261 | |
262 if(!sel || !isvisible(sel)) { | |
263 for(c = stack; c && !isvisible(c); c = c->snext); | |
264 focus(c); | |
265 } | |
266 restack(); | |
267 } | |
268 | |
269 static void | |
270 tile(void) { | |
271 unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th; | |
272 Client *c; | |
273 | |
274 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) | |
275 n++; | |
276 /* window geoms */ | |
277 mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1); | |
278 mw = (n > nmaster) ? (waw * master) / 1000 : waw; | |
279 th = (n > nmaster) ? wah / (n - nmaster) : 0; | |
280 tw = waw - mw; | |
281 | |
282 for(i = 0, c = clients; c; c = c->next) | |
283 if(isvisible(c)) { | |
284 if(c->isbanned) | |
285 XMoveWindow(dpy, c->win, c->x, c->y); | |
286 c->isbanned = False; | |
287 if(c->isversatile) | |
288 continue; | |
289 c->ismax = False; | |
290 nx = wax; | |
291 ny = way; | |
292 if(i < nmaster) { | |
293 ny += i * mh; | |
294 nw = mw - 2 * BORDERPX; | |
295 nh = mh - 2 * BORDERPX; | |
296 } | |
297 else { /* tile window */ | |
298 nx += mw; | |
299 nw = tw - 2 * BORDERPX; | |
300 if(th > 2 * BORDERPX) { | |
301 ny += (i - nmaster) * th; | |
302 nh = th - 2 * BORDERPX; | |
303 } | |
304 else /* fallback if th <= 2 * BORDERPX */ | |
305 nh = wah - 2 * BORDERPX; | |
306 } | |
307 resize(c, nx, ny, nw, nh, False); | |
308 i++; | |
309 } | |
310 else { | |
311 c->isbanned = True; | |
312 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); | |
313 } | |
314 if(!sel || !isvisible(sel)) { | |
315 for(c = stack; c && !isvisible(c); c = c->snext); | |
316 focus(c); | |
317 } | |
318 restack(); | |
319 } | |
320 | |
321 LAYOUTS | |
322 | |
323 /* extern */ | |
324 | |
325 void | |
326 focusnext(Arg *arg) { | |
327 Client *c; | |
328 | |
329 if(!sel) | |
330 return; | |
331 for(c = sel->next; c && !isvisible(c); c = c->next); | |
332 if(!c) | |
333 for(c = clients; c && !isvisible(c); c = c->next); | |
334 if(c) { | |
335 focus(c); | |
336 restack(); | |
337 } | |
338 } | |
339 | |
340 void | |
341 focusprev(Arg *arg) { | |
342 Client *c; | |
343 | |
344 if(!sel) | |
345 return; | |
346 for(c = sel->prev; c && !isvisible(c); c = c->prev); | |
347 if(!c) { | |
348 for(c = clients; c && c->next; c = c->next); | |
349 for(; c && !isvisible(c); c = c->prev); | |
350 } | |
351 if(c) { | |
352 focus(c); | |
353 restack(); | |
354 } | |
355 } | |
356 | |
357 void | |
358 incnmaster(Arg *arg) { | |
359 //if((lt->arrange != tile) || (nmaster + arg->i < 1) | |
360 //|| (wah / (nmaster + arg->i) <= 2 * BORDERPX)) | |
361 // return; | |
362 if(nmaster + arg->i < 1 && nmaster + arg->i <= MAX_TASKS) | |
363 return; | |
364 nmaster += arg->i; | |
365 if(sel) | |
366 lt->arrange(); | |
367 else | |
368 drawstatus(); | |
369 } | |
370 | |
371 void | |
372 initlayouts(void) { | |
373 unsigned int i, w; | |
374 | |
375 lt = &layout[0]; | |
376 nlayouts = sizeof layout / sizeof layout[0]; | |
377 for(blw = i = 0; i < nlayouts; i++) { | |
378 w = textw(layout[i].symbol); | |
379 if(w > blw) | |
380 blw = w; | |
381 } | |
382 } | |
383 | |
384 Client * | |
385 nexttiled(Client *c) { | |
386 for(; c && (c->isversatile || !isvisible(c)); c = c->next); | |
387 return c; | |
388 } | |
389 | |
390 void | |
391 resizemaster(Arg *arg) { | |
392 //if(lt->arrange != tile) | |
393 // return; | |
394 if(arg->i == 0) | |
395 master = MASTER; | |
396 else { | |
397 //if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX | |
398 //|| waw * (master + arg->i) / 1000 <= 2 * BORDERPX) | |
399 // return; | |
400 master += arg->i; | |
401 } | |
402 lt->arrange(); | |
403 } | |
404 | |
405 void | |
406 restack(void) { | |
407 Client *c; | |
408 XEvent ev; | |
409 | |
410 drawstatus(); | |
411 if(!sel) | |
412 return; | |
413 if(sel->isversatile || lt->arrange == versatile) | |
414 XRaiseWindow(dpy, sel->win); | |
415 if(lt->arrange != versatile) { | |
416 if(!sel->isversatile) | |
417 XLowerWindow(dpy, sel->win); | |
418 for(c = nexttiled(clients); c; c = nexttiled(c->next)) { | |
419 if(c == sel) | |
420 continue; | |
421 XLowerWindow(dpy, c->win); | |
422 } | |
423 } | |
424 XSync(dpy, False); | |
425 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); | |
426 } | |
427 | |
428 void | |
429 setlayout(Arg *arg) { | |
430 unsigned int i; | |
431 | |
432 if(arg->i == -1) { | |
433 for(i = 0; i < nlayouts && lt != &layout[i]; i++); | |
434 if(i == nlayouts - 1) | |
435 lt = &layout[0]; | |
436 else | |
437 lt = &layout[++i]; | |
438 } | |
439 else { | |
440 if(arg->i < 0 || arg->i >= nlayouts) | |
441 return; | |
442 lt = &layout[arg->i]; | |
443 } | |
444 if(sel) | |
445 lt->arrange(); | |
446 else | |
447 drawstatus(); | |
448 } | |
449 | |
450 void | |
451 versatile(void) { | |
452 Client *c; | |
453 | |
454 for(c = clients; c; c = c->next) { | |
455 if(isvisible(c)) { | |
456 if(c->isbanned) | |
457 XMoveWindow(dpy, c->win, c->x, c->y); | |
458 c->isbanned = False; | |
459 resize(c, c->x, c->y, c->w, c->h, True); | |
460 } | |
461 else { | |
462 c->isbanned = True; | |
463 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); | |
464 } | |
465 } | |
466 if(!sel || !isvisible(sel)) { | |
467 for(c = stack; c && !isvisible(c); c = c->snext); | |
468 focus(c); | |
469 } | |
470 restack(); | |
471 } |