view layout.c @ 8:e749c30135e9

add tag_n_view()
author paulo@thepaulopc
date Tue, 14 Jun 2011 00:33:07 -0700
parents e060ab82b136
children
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 bstack(void) {
147 unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
148 Client *c;
150 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
151 n++;
152 /* window geoms */
153 mh = (n > nmaster) ? (wah * master) / 1000 : wah;
154 mw = (n > nmaster) ? waw / nmaster : waw / (n > 0 ? n : 1);
155 th = wah - mh;
156 tw = (n > nmaster) ? waw / (n - nmaster) : 0;
158 for(i = 0, c = clients; c; c = c->next)
159 if(isvisible(c)) {
160 if(c->isbanned)
161 XMoveWindow(dpy, c->win, c->x, c->y);
162 c->isbanned = False;
163 if(c->isversatile)
164 continue;
165 c->ismax = False;
166 nx = wax;
167 ny = way;
168 if(i < nmaster) {
169 nx += i * mw;
170 nw = mw - 2 * BORDERPX;
171 nh = mh - 2 * BORDERPX;
172 }
173 else { /* tile window */
174 ny += mh;
175 nh = th - 2 * BORDERPX;
176 if(tw > 2 * BORDERPX) {
177 nx += (i - nmaster) * tw;
178 nw = tw - 2 * BORDERPX;
179 }
180 else /* fallback if th <= 2 * BORDERPX */
181 nw = waw - 2 * BORDERPX;
182 }
183 resize(c, nx, ny, nw, nh, False);
184 i++;
185 }
186 else {
187 c->isbanned = True;
188 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
189 }
190 if(!sel || !isvisible(sel)) {
191 for(c = stack; c && !isvisible(c); c = c->snext);
192 focus(c);
193 }
194 restack();
195 }
197 static void
198 grid(void) {
199 unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch;
200 Client *c;
202 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
203 n++;
204 if(n == 0)
205 return;
207 /* grid dimensions */
208 for(cols = 0; cols <= n/2; cols++)
209 if(cols*cols >= n)
210 break;
211 if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
212 cols = 2;
213 rows = n/cols;
215 /* window geometries */
216 cw = cols ? waw / cols : waw;
217 cn = 0; /* current column number */
218 rn = 0; /* current row number */
219 for(i = 0, c = clients; c; c = c->next)
220 if(isvisible(c)) {
221 if(i/rows + 1 > cols - n%cols)
222 rows = n/cols + 1;
223 ch = rows ? wah / rows : wah;
224 cx = cn*cw;
225 cy = (TOPBAR ? dc.h : 0) + rn*ch;
226 resize(c, cx, cy, cw - 2 * BORDERPX, ch - 2 * BORDERPX, False);
227 rn++;
228 if(rn >= rows) {
229 rn = 0;
230 cn++;
231 }
232 i++;
233 }
234 else {
235 c->isbanned = True;
236 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
237 }
239 if(!sel || !isvisible(sel)) {
240 for(c = stack; c && !isvisible(c); c = c->snext);
241 focus(c);
242 }
243 restack();
244 }
246 static void
247 tile(void) {
248 unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
249 Client *c;
251 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
252 n++;
253 /* window geoms */
254 mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
255 mw = (n > nmaster) ? (waw * master) / 1000 : waw;
256 th = (n > nmaster) ? wah / (n - nmaster) : 0;
257 tw = waw - mw;
259 for(i = 0, c = clients; c; c = c->next)
260 if(isvisible(c)) {
261 if(c->isbanned)
262 XMoveWindow(dpy, c->win, c->x, c->y);
263 c->isbanned = False;
264 if(c->isversatile)
265 continue;
266 c->ismax = False;
267 nx = wax;
268 ny = way;
269 if(i < nmaster) {
270 ny += i * mh;
271 nw = mw - 2 * BORDERPX;
272 nh = mh - 2 * BORDERPX;
273 }
274 else { /* tile window */
275 nx += mw;
276 nw = tw - 2 * BORDERPX;
277 if(th > 2 * BORDERPX) {
278 ny += (i - nmaster) * th;
279 nh = th - 2 * BORDERPX;
280 }
281 else /* fallback if th <= 2 * BORDERPX */
282 nh = wah - 2 * BORDERPX;
283 }
284 resize(c, nx, ny, nw, nh, False);
285 i++;
286 }
287 else {
288 c->isbanned = True;
289 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
290 }
291 if(!sel || !isvisible(sel)) {
292 for(c = stack; c && !isvisible(c); c = c->snext);
293 focus(c);
294 }
295 restack();
296 }
298 LAYOUTS
300 /* extern */
302 void
303 focusnext(Arg *arg) {
304 Client *c;
306 if(!sel)
307 return;
308 for(c = sel->next; c && !isvisible(c); c = c->next);
309 if(!c)
310 for(c = clients; c && !isvisible(c); c = c->next);
311 if(c) {
312 focus(c);
313 restack();
314 }
315 }
317 void
318 focusprev(Arg *arg) {
319 Client *c;
321 if(!sel)
322 return;
323 for(c = sel->prev; c && !isvisible(c); c = c->prev);
324 if(!c) {
325 for(c = clients; c && c->next; c = c->next);
326 for(; c && !isvisible(c); c = c->prev);
327 }
328 if(c) {
329 focus(c);
330 restack();
331 }
332 }
334 void
335 incnmaster(Arg *arg) {
336 //if((lt->arrange != tile) || (nmaster + arg->i < 1)
337 //|| (wah / (nmaster + arg->i) <= 2 * BORDERPX))
338 // return;
339 if(nmaster + arg->i < 1 && nmaster + arg->i <= MAX_TASKS)
340 return;
341 nmaster += arg->i;
342 if(sel)
343 lt->arrange();
344 else
345 drawstatus();
346 }
348 void
349 initlayouts(void) {
350 unsigned int i, w;
352 lt = &layout[0];
353 nlayouts = sizeof layout / sizeof layout[0];
354 for(blw = i = 0; i < nlayouts; i++) {
355 w = textw(layout[i].symbol);
356 if(w > blw)
357 blw = w;
358 }
359 }
361 Client *
362 nexttiled(Client *c) {
363 for(; c && (c->isversatile || !isvisible(c)); c = c->next);
364 return c;
365 }
367 void
368 resizemaster(Arg *arg) {
369 //if(lt->arrange != tile)
370 // return;
371 if(arg->i == 0)
372 master = MASTER;
373 else {
374 //if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
375 //|| waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
376 // return;
377 master += arg->i;
378 }
379 lt->arrange();
380 }
382 void
383 restack(void) {
384 Client *c;
385 XEvent ev;
387 drawstatus();
388 if(!sel)
389 return;
390 if(sel->isversatile || lt->arrange == versatile)
391 XRaiseWindow(dpy, sel->win);
392 if(lt->arrange != versatile) {
393 if(!sel->isversatile)
394 XLowerWindow(dpy, sel->win);
395 for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
396 if(c == sel)
397 continue;
398 XLowerWindow(dpy, c->win);
399 }
400 }
401 XSync(dpy, False);
402 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
403 }
405 void
406 setlayout(Arg *arg) {
407 int i;
409 if(arg->i < 0) {
410 for(i = 0; i < nlayouts && lt != &layout[i]; i++);
411 if(arg->i == -1)
412 lt = &layout[(i + 1) % nlayouts];
413 else if(arg->i == -2)
414 lt = &layout[(i - 1) >= 0 ? i - 1 : nlayouts - 1];
415 }
416 else {
417 if(arg->i < 0 || arg->i >= nlayouts)
418 return;
419 lt = &layout[arg->i];
420 }
421 if(sel)
422 lt->arrange();
423 else
424 drawstatus();
425 }
427 void
428 versatile(void) {
429 Client *c;
431 for(c = clients; c; c = c->next) {
432 if(isvisible(c)) {
433 if(c->isbanned)
434 XMoveWindow(dpy, c->win, c->x, c->y);
435 c->isbanned = False;
436 resize(c, c->x, c->y, c->w, c->h, True);
437 }
438 else {
439 c->isbanned = True;
440 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
441 }
442 }
443 if(!sel || !isvisible(sel)) {
444 for(c = stack; c && !isvisible(c); c = c->snext);
445 focus(c);
446 }
447 restack();
448 }