dwm-meillo

view view.c @ 384:126e78129f1d

configurenotify remembers max geom now, and restores this if necessary, however it accepts to touch the max size on configurerequest, this shouldn't break fillscreen apps (tested with mplayer)
author Anselm R. Garbe <arg@10kloc.org>
date Tue, 29 Aug 2006 17:31:55 +0200
parents b00cc483d13b
children aba385c61b3b
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"
6 #include <stdio.h>
8 /* static */
10 static Client *
11 minclient()
12 {
13 Client *c, *min;
15 for(min = c = clients; c; c = c->next)
16 if(c->weight < min->weight)
17 min = c;
18 return min;
19 }
22 static void
23 reorder()
24 {
25 Client *c, *newclients, *tail;
27 newclients = tail = NULL;
28 while((c = minclient())) {
29 detach(c);
30 if(tail) {
31 c->prev = tail;
32 tail->next = c;
33 tail = c;
34 }
35 else
36 tail = newclients = c;
37 }
38 clients = newclients;
39 }
41 /* extern */
43 void (*arrange)(Arg *) = DEFMODE;
45 void
46 detach(Client *c)
47 {
48 if(c->prev)
49 c->prev->next = c->next;
50 if(c->next)
51 c->next->prev = c->prev;
52 if(c == clients)
53 clients = c->next;
54 c->next = c->prev = NULL;
55 }
57 void
58 dofloat(Arg *arg)
59 {
60 Client *c;
62 for(c = clients; c; c = c->next) {
63 c->ismax = False;
64 if(isvisible(c)) {
65 resize(c, True, TopLeft);
66 }
67 else
68 ban(c);
69 }
70 if((sel = getnext(clients)))
71 focus(sel);
72 else
73 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
74 restack();
75 }
77 void
78 dotile(Arg *arg)
79 {
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 c->ismax = False;
95 if(isvisible(c)) {
96 if(c->isfloat) {
97 resize(c, True, TopLeft);
98 continue;
99 }
100 if(n == 1) {
101 c->x = sx;
102 c->y = sy + bh;
103 c->w = sw - 2;
104 c->h = sh - 2 - bh;
105 }
106 else if(i == 0) {
107 c->x = sx;
108 c->y = sy + bh;
109 c->w = mw - 2;
110 c->h = sh - 2 - bh;
111 }
112 else if(h > bh) {
113 c->x = sx + mw;
114 c->y = sy + (i - 1) * h + bh;
115 c->w = w - 2;
116 if(i + 1 == n)
117 c->h = sh - c->y - 2;
118 else
119 c->h = h - 2;
120 }
121 else { /* fallback if h < bh */
122 c->x = sx + mw;
123 c->y = sy + bh;
124 c->w = w - 2;
125 c->h = sh - 2 - bh;
126 }
127 resize(c, False, TopLeft);
128 i++;
129 }
130 else
131 ban(c);
132 }
133 if((sel = getnext(clients)))
134 focus(sel);
135 else
136 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
137 restack();
138 }
140 void
141 focusnext(Arg *arg)
142 {
143 Client *c;
145 if(!sel)
146 return;
148 if(!(c = getnext(sel->next)))
149 c = getnext(clients);
150 if(c) {
151 focus(c);
152 restack();
153 }
154 }
156 void
157 focusprev(Arg *arg)
158 {
159 Client *c;
161 if(!sel)
162 return;
164 if(!(c = getprev(sel->prev))) {
165 for(c = clients; c && c->next; c = c->next);
166 c = getprev(c);
167 }
168 if(c) {
169 focus(c);
170 restack();
171 }
172 }
174 Bool
175 isvisible(Client *c)
176 {
177 unsigned int i;
179 for(i = 0; i < ntags; i++)
180 if(c->tags[i] && seltag[i])
181 return True;
182 return False;
183 }
185 void
186 restack()
187 {
188 static unsigned int nwins = 0;
189 static Window *wins = NULL;
190 unsigned int f, fi, m, mi, n;
191 Client *c;
192 XEvent ev;
194 for(f = 0, m = 0, c = clients; c; c = c->next)
195 if(isvisible(c)) {
196 if(c->isfloat || arrange == dofloat)
197 f++;
198 else
199 m++;
200 }
201 if(!(n = 2 * (f + m))) {
202 drawstatus();
203 return;
204 }
205 if(nwins < n) {
206 nwins = n;
207 wins = erealloc(wins, nwins * sizeof(Window));
208 }
210 fi = 0;
211 mi = 2 * f;
212 if(sel->isfloat || arrange == dofloat) {
213 wins[fi++] = sel->twin;
214 wins[fi++] = sel->win;
215 }
216 else {
217 wins[mi++] = sel->twin;
218 wins[mi++] = sel->win;
219 }
220 for(c = clients; c; c = c->next)
221 if(isvisible(c) && c != sel) {
222 if(c->isfloat || arrange == dofloat) {
223 wins[fi++] = c->twin;
224 wins[fi++] = c->win;
225 }
226 else {
227 wins[mi++] = c->twin;
228 wins[mi++] = c->win;
229 }
230 }
231 XRestackWindows(dpy, wins, n);
232 drawall();
233 XSync(dpy, False);
234 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
235 }
237 void
238 togglemode(Arg *arg)
239 {
240 arrange = (arrange == dofloat) ? dotile : dofloat;
241 if(sel)
242 arrange(NULL);
243 else
244 drawstatus();
245 }
247 void
248 toggleview(Arg *arg)
249 {
250 unsigned int i;
252 seltag[arg->i] = !seltag[arg->i];
253 for(i = 0; i < ntags && !seltag[i]; i++);
254 if(i == ntags)
255 seltag[arg->i] = True; /* cannot toggle last view */
256 reorder();
257 arrange(NULL);
258 }
260 void
261 view(Arg *arg)
262 {
263 unsigned int i;
264 Client *c;
266 for(i = 0; i < ntags; i++)
267 seltag[i] = False;
268 seltag[arg->i] = True;
269 reorder();
270 arrange(NULL);
271 }
273 void
274 zoom(Arg *arg)
275 {
276 Client *c = sel;
278 if(!c || (arrange != dotile) || c->isfloat || c->ismax)
279 return;
281 if(c == getnext(clients))
282 if(!(c = getnext(c->next)))
283 return;
284 detach(c);
285 c->next = clients;
286 clients->prev = c;
287 clients = c;
288 focus(c);
289 arrange(NULL);
290 }