aewl

view view.c @ 533:a5567a0d3011

do* has no Arg arument anymore (never called directly)
author Anselm R. Garbe <arg@10kloc.org>
date Fri, 06 Oct 2006 13:06:37 +0200
parents 651f2c868b31
children 13ef0d218c67
line source
1 /* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
2 * See LICENSE file for license details.
3 */
4 #include "dwm.h"
6 /* static */
8 static Client *
9 minclient(void) {
10 Client *c, *min;
12 if((clients && clients->isfloat) || arrange == dofloat)
13 return clients; /* don't touch floating order */
14 for(min = c = clients; c; c = c->next)
15 if(c->weight < min->weight)
16 min = c;
17 return min;
18 }
20 static Client *
21 nexttiled(Client *c) {
22 for(c = getnext(c); c && c->isfloat; c = getnext(c->next));
23 return c;
24 }
26 static void
27 reorder(void) {
28 Client *c, *newclients, *tail;
30 newclients = tail = NULL;
31 while((c = minclient())) {
32 detach(c);
33 if(tail) {
34 c->prev = tail;
35 tail->next = c;
36 tail = c;
37 }
38 else
39 tail = newclients = c;
40 }
41 clients = newclients;
42 }
44 static void
45 togglemax(Client *c) {
46 XEvent ev;
48 if((c->ismax = !c->ismax)) {
49 c->rx = c->x; c->x = sx;
50 c->ry = c->y; c->y = bh;
51 c->rw = c->w; c->w = sw - 2 * BORDERPX;
52 c->rh = c->h; c->h = sh - bh - 2 * BORDERPX;
53 }
54 else {
55 c->x = c->rx;
56 c->y = c->ry;
57 c->w = c->rw;
58 c->h = c->rh;
59 }
60 resize(c, True, TopLeft);
61 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
62 }
64 /* extern */
66 void (*arrange)(void) = DEFMODE;
68 void
69 detach(Client *c) {
70 if(c->prev)
71 c->prev->next = c->next;
72 if(c->next)
73 c->next->prev = c->prev;
74 if(c == clients)
75 clients = c->next;
76 c->next = c->prev = NULL;
77 }
79 void
80 dofloat(void) {
81 Client *c;
83 for(c = clients; c; c = c->next) {
84 if(isvisible(c)) {
85 resize(c, True, TopLeft);
86 }
87 else
88 ban(c);
89 }
90 if(!sel || !isvisible(sel)) {
91 for(c = stack; c && !isvisible(c); c = c->snext);
92 focus(c);
93 }
94 restack();
95 }
97 void
98 dotile(void) {
99 unsigned int i, n, mpx, stackw, stackh, th;
100 Client *c;
102 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
103 n++;
104 mpx = (sw * master) / 1000;
105 stackw = sw - mpx;
106 stackh = sh - bh;
107 th = stackh;
108 if(n > 1)
109 th /= (n - 1);
111 for(i = 0, c = clients; c; c = c->next, i++)
112 if(isvisible(c)) {
113 if(c->isfloat) {
114 resize(c, True, TopLeft);
115 continue;
116 }
117 c->ismax = False;
118 c->x = sx;
119 c->y = sy + bh;
120 if(n == 1) { /* only 1 window */
121 c->w = sw - 2 * BORDERPX;
122 c->h = sh - 2 * BORDERPX - bh;
123 }
124 else if(i == 0) { /* master window */
125 c->w = mpx - 2 * BORDERPX;
126 c->h = sh - bh - 2 * BORDERPX;
127 }
128 else { /* tile window */
129 c->x += mpx;
130 c->w = stackw - 2 * BORDERPX;
131 if(th > bh) {
132 c->y = sy + (i - 1) * th + bh;
133 if(i + 1 == n)
134 c->h = sh - c->y - 2 * BORDERPX;
135 else
136 c->h = th - 2 * BORDERPX;
137 }
138 else /* fallback if th < bh */
139 c->h = stackh - 2 * BORDERPX;
140 }
141 resize(c, False, TopLeft);
142 }
143 else
144 ban(c);
146 if(!sel || !isvisible(sel)) {
147 for(c = stack; c && !isvisible(c); c = c->snext);
148 focus(c);
149 }
150 restack();
151 }
153 void
154 focusnext(Arg *arg) {
155 Client *c;
157 if(!sel)
158 return;
159 if(!(c = getnext(sel->next)))
160 c = getnext(clients);
161 if(c) {
162 focus(c);
163 restack();
164 }
165 }
167 void
168 focusprev(Arg *arg) {
169 Client *c;
171 if(!sel)
172 return;
173 if(!(c = getprev(sel->prev))) {
174 for(c = clients; c && c->next; c = c->next);
175 c = getprev(c);
176 }
177 if(c) {
178 focus(c);
179 restack();
180 }
181 }
183 Bool
184 isvisible(Client *c) {
185 unsigned int i;
187 for(i = 0; i < ntags; i++)
188 if(c->tags[i] && seltag[i])
189 return True;
190 return False;
191 }
193 void
194 resizecol(Arg *arg) {
195 unsigned int n;
196 Client *c;
198 for(n = 0, c = clients; c; c = c->next)
199 if(isvisible(c) && !c->isfloat)
200 n++;
201 if(!sel || sel->isfloat || n < 2 || (arrange == dofloat))
202 return;
203 if(sel == getnext(clients)) {
204 if(master + arg->i > 950 || master + arg->i < 50)
205 return;
206 master += arg->i;
207 }
208 else {
209 if(master - arg->i > 950 || master - arg->i < 50)
210 return;
211 master -= arg->i;
212 }
213 arrange();
214 }
216 void
217 restack(void) {
218 Client *c;
219 XEvent ev;
221 if(!sel) {
222 drawstatus();
223 return;
224 }
225 if(sel->isfloat || arrange == dofloat) {
226 XRaiseWindow(dpy, sel->win);
227 XRaiseWindow(dpy, sel->twin);
228 }
229 if(arrange != dofloat) {
230 if(!sel->isfloat) {
231 XLowerWindow(dpy, sel->twin);
232 XLowerWindow(dpy, sel->win);
233 }
234 for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
235 if(c == sel)
236 continue;
237 XLowerWindow(dpy, c->twin);
238 XLowerWindow(dpy, c->win);
239 }
240 }
241 drawall();
242 XSync(dpy, False);
243 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
244 }
246 void
247 togglemode(Arg *arg) {
248 arrange = (arrange == dofloat) ? dotile : dofloat;
249 if(sel)
250 arrange();
251 else
252 drawstatus();
253 }
255 void
256 toggleview(Arg *arg) {
257 unsigned int i;
259 seltag[arg->i] = !seltag[arg->i];
260 for(i = 0; i < ntags && !seltag[i]; i++);
261 if(i == ntags)
262 seltag[arg->i] = True; /* cannot toggle last view */
263 reorder();
264 arrange();
265 }
267 void
268 view(Arg *arg) {
269 unsigned int i;
271 for(i = 0; i < ntags; i++)
272 seltag[i] = False;
273 seltag[arg->i] = True;
274 reorder();
275 arrange();
276 }
278 void
279 viewall(Arg *arg) {
280 unsigned int i;
282 for(i = 0; i < ntags; i++)
283 seltag[i] = True;
284 reorder();
285 arrange();
286 }
288 void
289 zoom(Arg *arg) {
290 unsigned int n;
291 Client *c;
293 if(!sel)
294 return;
295 if(sel->isfloat || (arrange == dofloat)) {
296 togglemax(sel);
297 return;
298 }
299 for(n = 0, c = clients; c; c = c->next)
300 if(isvisible(c) && !c->isfloat)
301 n++;
302 if(n < 2 || (arrange == dofloat))
303 return;
304 if((c = sel) == nexttiled(clients))
305 if(!(c = nexttiled(c->next)))
306 return;
307 detach(c);
308 if(clients)
309 clients->prev = c;
310 c->next = clients;
311 clients = c;
312 focus(c);
313 arrange();
314 }