aewl

view view.c @ 541:08d3d329270a

using MASTER 600 again, it is definately better, and using urxvtc for the moment (it doesn't flickers on refreshes, but this is not because of Marc Lehmann, it is because of the original rxvt code)
author arg@mig29
date Thu, 26 Oct 2006 12:13:41 +0200
parents a5567a0d3011
children 3d23384eb5ab
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)
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 i++;
143 }
144 else
145 ban(c);
147 if(!sel || !isvisible(sel)) {
148 for(c = stack; c && !isvisible(c); c = c->snext);
149 focus(c);
150 }
151 restack();
152 }
154 void
155 focusnext(Arg *arg) {
156 Client *c;
158 if(!sel)
159 return;
160 if(!(c = getnext(sel->next)))
161 c = getnext(clients);
162 if(c) {
163 focus(c);
164 restack();
165 }
166 }
168 void
169 focusprev(Arg *arg) {
170 Client *c;
172 if(!sel)
173 return;
174 if(!(c = getprev(sel->prev))) {
175 for(c = clients; c && c->next; c = c->next);
176 c = getprev(c);
177 }
178 if(c) {
179 focus(c);
180 restack();
181 }
182 }
184 Bool
185 isvisible(Client *c) {
186 unsigned int i;
188 for(i = 0; i < ntags; i++)
189 if(c->tags[i] && seltag[i])
190 return True;
191 return False;
192 }
194 void
195 resizecol(Arg *arg) {
196 unsigned int n;
197 Client *c;
199 for(n = 0, c = clients; c; c = c->next)
200 if(isvisible(c) && !c->isfloat)
201 n++;
202 if(!sel || sel->isfloat || n < 2 || (arrange == dofloat))
203 return;
204 if(sel == getnext(clients)) {
205 if(master + arg->i > 950 || master + arg->i < 50)
206 return;
207 master += arg->i;
208 }
209 else {
210 if(master - arg->i > 950 || master - arg->i < 50)
211 return;
212 master -= arg->i;
213 }
214 arrange();
215 }
217 void
218 restack(void) {
219 Client *c;
220 XEvent ev;
222 if(!sel) {
223 drawstatus();
224 return;
225 }
226 if(sel->isfloat || arrange == dofloat) {
227 XRaiseWindow(dpy, sel->win);
228 XRaiseWindow(dpy, sel->twin);
229 }
230 if(arrange != dofloat) {
231 if(!sel->isfloat) {
232 XLowerWindow(dpy, sel->twin);
233 XLowerWindow(dpy, sel->win);
234 }
235 for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
236 if(c == sel)
237 continue;
238 XLowerWindow(dpy, c->twin);
239 XLowerWindow(dpy, c->win);
240 }
241 }
242 drawall();
243 XSync(dpy, False);
244 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
245 }
247 void
248 togglemode(Arg *arg) {
249 arrange = (arrange == dofloat) ? dotile : dofloat;
250 if(sel)
251 arrange();
252 else
253 drawstatus();
254 }
256 void
257 toggleview(Arg *arg) {
258 unsigned int i;
260 seltag[arg->i] = !seltag[arg->i];
261 for(i = 0; i < ntags && !seltag[i]; i++);
262 if(i == ntags)
263 seltag[arg->i] = True; /* cannot toggle last view */
264 reorder();
265 arrange();
266 }
268 void
269 view(Arg *arg) {
270 unsigned int i;
272 for(i = 0; i < ntags; i++)
273 seltag[i] = False;
274 seltag[arg->i] = True;
275 reorder();
276 arrange();
277 }
279 void
280 viewall(Arg *arg) {
281 unsigned int i;
283 for(i = 0; i < ntags; i++)
284 seltag[i] = True;
285 reorder();
286 arrange();
287 }
289 void
290 zoom(Arg *arg) {
291 unsigned int n;
292 Client *c;
294 if(!sel)
295 return;
296 if(sel->isfloat || (arrange == dofloat)) {
297 togglemax(sel);
298 return;
299 }
300 for(n = 0, c = clients; c; c = c->next)
301 if(isvisible(c) && !c->isfloat)
302 n++;
303 if(n < 2 || (arrange == dofloat))
304 return;
305 if((c = sel) == nexttiled(clients))
306 if(!(c = nexttiled(c->next)))
307 return;
308 detach(c);
309 if(clients)
310 clients->prev = c;
311 c->next = clients;
312 clients = c;
313 focus(c);
314 arrange();
315 }