aewl

view view.c @ 479:de69a7b0c8fa

fixed issue pointed out by Jukka
author arg@mmvi
date Fri, 22 Sep 2006 11:49:24 +0200
parents 2d8af0d7920d
children 680aca428830
line source
1 /*
2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
3 * See LICENSE file for license details.
4 */
5 #include "dwm.h"
7 /* static */
9 static Client *
10 minclient() {
11 Client *c, *min;
13 if((clients && clients->isfloat) || arrange == dofloat)
14 return clients; /* don't touch floating order */
15 for(min = c = clients; c; c = c->next)
16 if(c->weight < min->weight)
17 min = c;
18 return min;
19 }
21 static void
22 reorder() {
23 Client *c, *newclients, *tail;
25 newclients = tail = NULL;
26 while((c = minclient())) {
27 detach(c);
28 if(tail) {
29 c->prev = tail;
30 tail->next = c;
31 tail = c;
32 }
33 else
34 tail = newclients = c;
35 }
36 clients = newclients;
37 }
39 static Client *
40 nexttiled(Client *c) {
41 for(c = getnext(c); c && c->isfloat; c = getnext(c->next));
42 return c;
43 }
45 /* extern */
47 void (*arrange)(Arg *) = DEFMODE;
49 void
50 detach(Client *c) {
51 if(c->prev)
52 c->prev->next = c->next;
53 if(c->next)
54 c->next->prev = c->prev;
55 if(c == clients)
56 clients = c->next;
57 c->next = c->prev = NULL;
58 }
60 void
61 dofloat(Arg *arg) {
62 Client *c;
64 for(c = clients; c; c = c->next) {
65 if(isvisible(c)) {
66 resize(c, True, TopLeft);
67 }
68 else
69 ban(c);
70 }
71 if(!sel || !isvisible(sel)) {
72 for(c = stack; c && !isvisible(c); c = c->snext);
73 focus(c);
74 }
75 restack();
76 }
78 void
79 dotile(Arg *arg) {
80 int h, i, n, w;
81 Client *c;
83 w = sw - mw;
84 for(n = 0, c = clients; c; c = c->next)
85 if(isvisible(c) && !c->isfloat)
86 n++;
88 if(n > 1)
89 h = (sh - bh) / (n - 1);
90 else
91 h = sh - bh;
93 for(i = 0, c = clients; c; c = c->next) {
94 if(isvisible(c)) {
95 if(c->isfloat) {
96 resize(c, True, TopLeft);
97 continue;
98 }
99 if(n == 1) {
100 c->x = sx;
101 c->y = sy + bh;
102 c->w = sw - 2;
103 c->h = sh - 2 - bh;
104 }
105 else if(i == 0) {
106 c->x = sx;
107 c->y = sy + bh;
108 c->w = mw - 2;
109 c->h = sh - 2 - bh;
110 }
111 else if(h > bh) {
112 c->x = sx + mw;
113 c->y = sy + (i - 1) * h + bh;
114 c->w = w - 2;
115 if(i + 1 == n)
116 c->h = sh - c->y - 2;
117 else
118 c->h = h - 2;
119 }
120 else { /* fallback if h < bh */
121 c->x = sx + mw;
122 c->y = sy + bh;
123 c->w = w - 2;
124 c->h = sh - 2 - bh;
125 }
126 resize(c, False, TopLeft);
127 i++;
128 }
129 else
130 ban(c);
131 }
132 if(!sel || !isvisible(sel)) {
133 for(c = stack; c && !isvisible(c); c = c->snext);
134 focus(c);
135 }
136 restack();
137 }
139 void
140 focusnext(Arg *arg) {
141 Client *c;
143 if(!sel)
144 return;
146 if(!(c = getnext(sel->next)))
147 c = getnext(clients);
148 if(c) {
149 focus(c);
150 restack();
151 }
152 }
154 void
155 focusprev(Arg *arg) {
156 Client *c;
158 if(!sel)
159 return;
161 if(!(c = getprev(sel->prev))) {
162 for(c = clients; c && c->next; c = c->next);
163 c = getprev(c);
164 }
165 if(c) {
166 focus(c);
167 restack();
168 }
169 }
171 Bool
172 isvisible(Client *c) {
173 unsigned int i;
175 for(i = 0; i < ntags; i++)
176 if(c->tags[i] && seltag[i])
177 return True;
178 return False;
179 }
181 void
182 resizecol(Arg *arg) {
183 unsigned int n;
184 Client *c;
186 for(n = 0, c = clients; c; c = c->next)
187 if(isvisible(c) && !c->isfloat)
188 n++;
189 if(!sel || sel->isfloat || n < 2 || (arrange != dotile))
190 return;
192 if(sel == getnext(clients)) {
193 if(mw + arg->i > sw - 100 || mw + arg->i < 100)
194 return;
195 mw += arg->i;
196 }
197 else {
198 if(mw - arg->i > sw - 100 || mw - arg->i < 100)
199 return;
200 mw -= arg->i;
201 }
202 arrange(NULL);
203 }
205 void
206 restack() {
207 Client *c;
208 XEvent ev;
210 if(!sel) {
211 drawstatus();
212 return;
213 }
214 if(sel->isfloat || arrange == dofloat) {
215 XRaiseWindow(dpy, sel->win);
216 XRaiseWindow(dpy, sel->twin);
217 }
218 if(arrange != dofloat)
219 for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
220 XLowerWindow(dpy, c->twin);
221 XLowerWindow(dpy, c->win);
222 }
223 drawall();
224 XSync(dpy, False);
225 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
226 }
228 void
229 togglemode(Arg *arg) {
230 arrange = (arrange == dofloat) ? dotile : dofloat;
231 if(sel)
232 arrange(NULL);
233 else
234 drawstatus();
235 }
237 void
238 toggleview(Arg *arg) {
239 unsigned int i;
241 seltag[arg->i] = !seltag[arg->i];
242 for(i = 0; i < ntags && !seltag[i]; i++);
243 if(i == ntags)
244 seltag[arg->i] = True; /* cannot toggle last view */
245 reorder();
246 arrange(NULL);
247 }
249 void
250 view(Arg *arg) {
251 unsigned int i;
253 for(i = 0; i < ntags; i++)
254 seltag[i] = False;
255 seltag[arg->i] = True;
256 reorder();
257 arrange(NULL);
258 }
260 void
261 viewall(Arg *arg) {
262 unsigned int i;
264 for(i = 0; i < ntags; i++)
265 seltag[i] = True;
266 reorder();
267 arrange(NULL);
268 }
270 void
271 zoom(Arg *arg) {
272 int tmp;
273 unsigned int n;
274 Client *c;
275 XEvent ev;
277 if(!sel)
278 return;
280 if(sel->isfloat || (arrange == dofloat)) {
281 sel->x = sx;
282 sel->y = bh;
283 sel->w = sw;
284 sel->h = sh - bh;
285 resize(sel, True, TopLeft);
286 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
287 return;
288 }
290 for(n = 0, c = clients; c; c = c->next)
291 if(isvisible(c) && !c->isfloat)
292 n++;
293 if(n < 2 || (arrange != dotile))
294 return;
296 if((c = sel) == nexttiled(clients))
297 if(!(c = nexttiled(c->next)))
298 return;
299 detach(c);
300 if(clients)
301 clients->prev = c;
302 c->next = clients;
303 clients = c;
304 focus(c);
305 arrange(NULL);
306 }