JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
removed useless inclusion
[dwm.git] / view.c
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"
6
7 /* static */
8
9 static Client *
10 minclient() {
11         Client *c, *min;
12
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 }
20
21 static void
22 reorder() {
23         Client *c, *newclients, *tail;
24
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 }
38
39 static Client *
40 nexttiled(Client *c) {
41         for(c = getnext(c); c && c->isfloat; c = getnext(c->next));
42         return c;
43 }
44
45 /* extern */
46
47 void (*arrange)(Arg *) = DEFMODE;
48
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 }
59
60 void
61 dofloat(Arg *arg) {
62         Client *c;
63
64         maximized = False;
65
66         for(c = clients; c; c = c->next) {
67                 if(isvisible(c)) {
68                         resize(c, True, TopLeft);
69                 }
70                 else
71                         ban(c);
72         }
73         if(!sel || !isvisible(sel)) {
74                 for(c = stack; c && !isvisible(c); c = c->snext);
75                 focus(c);
76         }
77         restack();
78 }
79
80 void
81 dotile(Arg *arg) {
82         int h, i, n, w;
83         Client *c;
84
85         maximized = False;
86
87         w = sw - mw;
88         for(n = 0, c = clients; c; c = c->next)
89                 if(isvisible(c) && !c->isfloat)
90                         n++;
91
92         if(n > 1)
93                 h = (sh - bh) / (n - 1);
94         else
95                 h = sh - bh;
96
97         for(i = 0, c = clients; c; c = c->next) {
98                 if(isvisible(c)) {
99                         if(c->isfloat) {
100                                 resize(c, True, TopLeft);
101                                 continue;
102                         }
103                         if(n == 1) {
104                                 c->x = sx;
105                                 c->y = sy + bh;
106                                 c->w = sw - 2;
107                                 c->h = sh - 2 - bh;
108                         }
109                         else if(i == 0) {
110                                 c->x = sx;
111                                 c->y = sy + bh;
112                                 c->w = mw - 2;
113                                 c->h = sh - 2 - bh;
114                         }
115                         else if(h > bh) {
116                                 c->x = sx + mw;
117                                 c->y = sy + (i - 1) * h + bh;
118                                 c->w = w - 2;
119                                 if(i + 1 == n)
120                                         c->h = sh - c->y - 2;
121                                 else
122                                         c->h = h - 2;
123                         }
124                         else { /* fallback if h < bh */
125                                 c->x = sx + mw;
126                                 c->y = sy + bh;
127                                 c->w = w - 2;
128                                 c->h = sh - 2 - bh;
129                         }
130                         resize(c, False, TopLeft);
131                         i++;
132                 }
133                 else
134                         ban(c);
135         }
136         if(!sel || !isvisible(sel)) {
137                 for(c = stack; c && !isvisible(c); c = c->snext);
138                 focus(c);
139         }
140         restack();
141 }
142
143 void
144 focusnext(Arg *arg) {
145         Client *c;
146    
147         if(!sel)
148                 return;
149
150         if(!(c = getnext(sel->next)))
151                 c = getnext(clients);
152         if(c) {
153                 focus(c);
154                 restack();
155         }
156 }
157
158 void
159 focusprev(Arg *arg) {
160         Client *c;
161
162         if(!sel)
163                 return;
164
165         if(!(c = getprev(sel->prev))) {
166                 for(c = clients; c && c->next; c = c->next);
167                 c = getprev(c);
168         }
169         if(c) {
170                 focus(c);
171                 restack();
172         }
173 }
174
175 Bool
176 isvisible(Client *c) {
177         unsigned int i;
178
179         for(i = 0; i < ntags; i++)
180                 if(c->tags[i] && seltag[i])
181                         return True;
182         return False;
183 }
184
185 void
186 resizecol(Arg *arg) {
187         unsigned int n;
188         Client *c;
189
190         for(n = 0, c = clients; c; c = c->next)
191                 if(isvisible(c) && !c->isfloat)
192                         n++;
193         if(!sel || sel->isfloat || n < 2 || (arrange != dotile) || maximized)
194                 return;
195
196         if(sel == getnext(clients)) {
197                 if(mw + arg->i > sw - 100 || mw + arg->i < 100)
198                         return;
199                 mw += arg->i;
200         }
201         else {
202                 if(mw - arg->i > sw - 100 || mw - arg->i < 100)
203                         return;
204                 mw -= arg->i;
205         }
206         arrange(NULL);
207 }
208
209 void
210 restack() {
211         Client *c;
212         XEvent ev;
213         
214         if(!sel) {
215                 drawstatus();
216                 return;
217         }
218         if(sel->isfloat || arrange == dofloat) {
219                 XRaiseWindow(dpy, sel->win);
220                 XRaiseWindow(dpy, sel->twin);
221         }
222         if(arrange != dofloat)
223                 for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
224                         XLowerWindow(dpy, c->twin);
225                         XLowerWindow(dpy, c->win);
226                 }
227         drawall();
228         XSync(dpy, False);
229         while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
230 }
231
232 void
233 togglemode(Arg *arg) {
234         arrange = (arrange == dofloat) ? dotile : dofloat;
235         if(sel)
236                 arrange(NULL);
237         else
238                 drawstatus();
239 }
240
241 void
242 toggleview(Arg *arg) {
243         unsigned int i;
244
245         seltag[arg->i] = !seltag[arg->i];
246         for(i = 0; i < ntags && !seltag[i]; i++);
247         if(i == ntags)
248                 seltag[arg->i] = True; /* cannot toggle last view */
249         reorder();
250         arrange(NULL);
251 }
252
253 void
254 view(Arg *arg) {
255         unsigned int i;
256
257         for(i = 0; i < ntags; i++)
258                 seltag[i] = False;
259         seltag[arg->i] = True;
260         reorder();
261         arrange(NULL);
262 }
263
264 void
265 viewall(Arg *arg) {
266         unsigned int i;
267
268         for(i = 0; i < ntags; i++)
269                 seltag[i] = True;
270         reorder();
271         arrange(NULL);
272 }
273
274 void
275 zoom(Arg *arg) {
276         unsigned int n;
277         Client *c;
278
279         for(n = 0, c = clients; c; c = c->next)
280                 if(isvisible(c) && !c->isfloat)
281                         n++;
282         if(!sel || sel->isfloat || n < 2 || (arrange != dotile) || maximized)
283                 return;
284
285         if((c = sel) == nexttiled(clients))
286                 if(!(c = nexttiled(c->next)))
287                         return;
288         detach(c);
289         if(clients)
290                 clients->prev = c;
291         c->next = clients;
292         clients = c;
293         focus(c);
294         arrange(NULL);
295 }