Mercurial > hg > index.fcgi > dwm > dwm-3.6.1-12pba
view layout.c @ 4:a54de16f8277
fix taskbar behavior when exceeding MAX_TASKS; bound moveresize() to windowarea
author | paulo@localhost |
---|---|
date | Fri, 24 Apr 2009 01:34:17 -0700 |
parents | ba504f41828f |
children | e060ab82b136 |
line source
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"
6 unsigned int master = MASTER;
7 unsigned int nmaster = NMASTER;
8 unsigned int blw = 0;
9 Layout *lt = NULL;
11 /* static */
13 static unsigned int nlayouts = 0;
15 static void
16 spiral(void) {
17 unsigned int i, n, nx, ny, nw, nh;
18 Client *c;
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 }
70 static void
71 spiral_h(void) {
72 unsigned int i, n, nx, ny, nw, nh;
73 Client *c;
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 }
125 static void
126 monocle(void) {
127 Client *c;
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 }
139 for(c = nexttiled(clients); c; c = nexttiled(c->next))
140 resize(c, wax, way, waw - 2*c->border, wah - 2*c->border, False);
142 restack();
143 }
145 static void
146 cascade(void) {
147 unsigned int i, n, px = 20;
148 Client *c;
150 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), n++);
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 }
168 restack();
169 }
171 static void
172 bstack(void) {
173 unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
174 Client *c;
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;
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 }
223 static void
224 grid(void) {
225 unsigned int i, n, nx, ny, nw, nh, aw, ah, tw, th, cols, rows;
226 Client *c;
228 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
229 n++;
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;
236 th = wah / (rows ? rows : 1);
237 tw = waw / (cols ? cols : 1);
238 nw = tw - 2 * BORDERPX;
239 nh = th - 2 * BORDERPX;
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) ? wah - th * rows : 0;
253 aw = (i >= rows * (cols - 1)) ? waw - 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 }
262 if(!sel || !isvisible(sel)) {
263 for(c = stack; c && !isvisible(c); c = c->snext);
264 focus(c);
265 }
266 restack();
267 }
269 static void
270 tile(void) {
271 unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
272 Client *c;
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;
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 }
321 LAYOUTS
323 /* extern */
325 void
326 focusnext(Arg *arg) {
327 Client *c;
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 }
340 void
341 focusprev(Arg *arg) {
342 Client *c;
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 }
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 }
371 void
372 initlayouts(void) {
373 unsigned int i, w;
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 }
384 Client *
385 nexttiled(Client *c) {
386 for(; c && (c->isversatile || !isvisible(c)); c = c->next);
387 return c;
388 }
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 }
405 void
406 restack(void) {
407 Client *c;
408 XEvent ev;
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 }
428 void
429 setlayout(Arg *arg) {
430 int i;
432 if(arg->i < 0) {
433 for(i = 0; i < nlayouts && lt != &layout[i]; i++);
434 if(arg->i == -1)
435 lt = &layout[(i + 1) % nlayouts];
436 else if(arg->i == -2)
437 lt = &layout[(i - 1) >= 0 ? i - 1 : nlayouts - 1];
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 }
450 void
451 versatile(void) {
452 Client *c;
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 }