aewl
view view.c @ 378:83576f5f0a90
added attach/detach functions which don't attach at the begin of list, but at the slot of a first match of the tags of a client
author | Anselm R. Garbe <arg@10kloc.org> |
---|---|
date | Tue, 29 Aug 2006 09:23:44 +0200 |
parents | a1901753deef |
children | 4bf79305d675 |
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 /* extern */
9 void (*arrange)(Arg *) = DEFMODE;
11 void
12 attach(Client *c)
13 {
14 Client *first = getnext(clients);
16 if(!first) {
17 if(clients) {
18 for(first = clients; first->next; first = first->next);
19 first->next = c;
20 c->prev = first;
21 }
22 else
23 clients = c;
24 }
25 else if(first == clients) {
26 c->next = clients;
27 clients->prev = c;
28 clients = c;
29 }
30 else {
31 first->prev->next = c;
32 c->prev = first->prev;
33 first->prev = c;
34 c->next = first;
35 }
36 }
38 void
39 detach(Client *c)
40 {
41 if(c->prev)
42 c->prev->next = c->next;
43 if(c->next)
44 c->next->prev = c->prev;
45 if(c == clients)
46 clients = c->next;
47 c->next = c->prev = NULL;
48 }
50 void
51 dofloat(Arg *arg)
52 {
53 Client *c;
55 for(c = clients; c; c = c->next) {
56 c->ismax = False;
57 if(isvisible(c)) {
58 resize(c, True, TopLeft);
59 }
60 else
61 ban(c);
62 }
63 if(!sel || !isvisible(sel))
64 sel = getnext(clients);
65 if(sel)
66 focus(sel);
67 else
68 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
69 restack();
70 }
72 void
73 dotile(Arg *arg)
74 {
75 int h, i, n, w;
76 Client *c;
78 w = sw - mw;
79 for(n = 0, c = clients; c; c = c->next)
80 if(isvisible(c) && !c->isfloat)
81 n++;
83 if(n > 1)
84 h = (sh - bh) / (n - 1);
85 else
86 h = sh - bh;
88 for(i = 0, c = clients; c; c = c->next) {
89 c->ismax = False;
90 if(isvisible(c)) {
91 if(c->isfloat) {
92 resize(c, True, TopLeft);
93 continue;
94 }
95 if(n == 1) {
96 c->x = sx;
97 c->y = sy + bh;
98 c->w = sw - 2;
99 c->h = sh - 2 - bh;
100 }
101 else if(i == 0) {
102 c->x = sx;
103 c->y = sy + bh;
104 c->w = mw - 2;
105 c->h = sh - 2 - bh;
106 }
107 else if(h > bh) {
108 c->x = sx + mw;
109 c->y = sy + (i - 1) * h + bh;
110 c->w = w - 2;
111 if(i + 1 == n)
112 c->h = sh - c->y - 2;
113 else
114 c->h = h - 2;
115 }
116 else { /* fallback if h < bh */
117 c->x = sx + mw;
118 c->y = sy + bh;
119 c->w = w - 2;
120 c->h = sh - 2 - bh;
121 }
122 resize(c, False, TopLeft);
123 i++;
124 }
125 else
126 ban(c);
127 }
128 if(!sel || !isvisible(sel))
129 sel = getnext(clients);
130 if(sel)
131 focus(sel);
132 else
133 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
134 restack();
135 }
137 void
138 focusnext(Arg *arg)
139 {
140 Client *c;
142 if(!sel)
143 return;
145 if(!(c = getnext(sel->next)))
146 c = getnext(clients);
147 if(c) {
148 focus(c);
149 restack();
150 }
151 }
153 void
154 focusprev(Arg *arg)
155 {
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 {
174 unsigned int i;
176 for(i = 0; i < ntags; i++)
177 if(c->tags[i] && seltag[i])
178 return True;
179 return False;
180 }
182 void
183 restack()
184 {
185 static unsigned int nwins = 0;
186 static Window *wins = NULL;
187 unsigned int f, fi, m, mi, n;
188 Client *c;
189 XEvent ev;
191 for(f = 0, m = 0, c = clients; c; c = c->next)
192 if(isvisible(c)) {
193 if(c->isfloat || arrange == dofloat)
194 f++;
195 else
196 m++;
197 }
198 if(!(n = 2 * (f + m))) {
199 drawstatus();
200 return;
201 }
202 if(nwins < n) {
203 nwins = n;
204 wins = erealloc(wins, nwins * sizeof(Window));
205 }
207 fi = 0;
208 mi = 2 * f;
209 if(sel->isfloat || arrange == dofloat) {
210 wins[fi++] = sel->twin;
211 wins[fi++] = sel->win;
212 }
213 else {
214 wins[mi++] = sel->twin;
215 wins[mi++] = sel->win;
216 }
217 for(c = clients; c; c = c->next)
218 if(isvisible(c) && c != sel) {
219 if(c->isfloat || arrange == dofloat) {
220 wins[fi++] = c->twin;
221 wins[fi++] = c->win;
222 }
223 else {
224 wins[mi++] = c->twin;
225 wins[mi++] = c->win;
226 }
227 }
228 XRestackWindows(dpy, wins, n);
229 drawall();
230 XSync(dpy, False);
231 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
232 }
234 void
235 togglemode(Arg *arg)
236 {
237 arrange = (arrange == dofloat) ? dotile : dofloat;
238 if(sel)
239 arrange(NULL);
240 else
241 drawstatus();
242 }
244 void
245 toggleview(Arg *arg)
246 {
247 unsigned int i;
249 seltag[arg->i] = !seltag[arg->i];
250 for(i = 0; i < ntags && !seltag[i]; i++);
251 if(i == ntags)
252 seltag[arg->i] = True; /* cannot toggle last view */
253 arrange(NULL);
254 }
256 void
257 view(Arg *arg)
258 {
259 unsigned int i;
261 for(i = 0; i < ntags; i++)
262 seltag[i] = False;
263 seltag[arg->i] = True;
264 arrange(NULL);
265 }
267 void
268 zoom(Arg *arg)
269 {
270 Client *c = sel;
272 if(!c || (arrange != dotile) || c->isfloat || c->ismax)
273 return;
275 if(c == getnext(clients))
276 if(!(c = getnext(c->next)))
277 return;
278 detach(c);
279 attach(c);
280 focus(c);
281 arrange(NULL);
282 }