9 #include <X11/Xatom.h> |
9 #include <X11/Xatom.h> |
10 #include <X11/Xutil.h> |
10 #include <X11/Xutil.h> |
11 |
11 |
12 #include "dwm.h" |
12 #include "dwm.h" |
13 |
13 |
14 void (*arrange)(Arg *) = tiling; |
|
15 |
|
16 static Rule rule[] = { |
14 static Rule rule[] = { |
17 /* class instance tags floating */ |
15 /* class instance tags floating */ |
18 { "Firefox-bin", "Gecko", { [Twww] = "www" }, False }, |
16 { "Firefox-bin", "Gecko", { [Twww] = "www" }, False }, |
19 }; |
17 }; |
20 |
18 |
21 static Client * |
19 Client * |
22 next(Client *c) |
20 next(Client *c) |
23 { |
21 { |
24 for(; c && !c->tags[tsel]; c = c->next); |
22 for(; c && !c->tags[tsel]; c = c->next); |
25 return c; |
23 return c; |
26 } |
24 } |
27 |
25 |
28 void |
26 void |
29 zoom(Arg *arg) |
|
30 { |
|
31 Client **l, *c; |
|
32 |
|
33 if(!sel) |
|
34 return; |
|
35 |
|
36 if(sel == next(clients) && sel->next) { |
|
37 if((c = next(sel->next))) |
|
38 sel = c; |
|
39 } |
|
40 |
|
41 for(l = &clients; *l && *l != sel; l = &(*l)->next); |
|
42 *l = sel->next; |
|
43 |
|
44 sel->next = clients; /* pop */ |
|
45 clients = sel; |
|
46 arrange(NULL); |
|
47 focus(sel); |
|
48 } |
|
49 |
|
50 void |
|
51 max(Arg *arg) |
|
52 { |
|
53 if(!sel) |
|
54 return; |
|
55 sel->x = sx; |
|
56 sel->y = sy + bh; |
|
57 sel->w = sw - 2 * sel->border; |
|
58 sel->h = sh - 2 * sel->border - bh; |
|
59 craise(sel); |
|
60 resize(sel, False); |
|
61 } |
|
62 |
|
63 void |
|
64 view(Arg *arg) |
|
65 { |
|
66 Client *c; |
|
67 |
|
68 tsel = arg->i; |
|
69 arrange(NULL); |
|
70 |
|
71 for(c = clients; c; c = next(c->next)) |
|
72 draw_client(c); |
|
73 draw_bar(); |
|
74 } |
|
75 |
|
76 void |
|
77 tappend(Arg *arg) |
|
78 { |
|
79 if(!sel) |
|
80 return; |
|
81 |
|
82 sel->tags[arg->i] = tags[arg->i]; |
|
83 arrange(NULL); |
|
84 } |
|
85 |
|
86 void |
|
87 ttrunc(Arg *arg) |
|
88 { |
|
89 int i; |
|
90 if(!sel) |
|
91 return; |
|
92 |
|
93 for(i = 0; i < TLast; i++) |
|
94 sel->tags[i] = NULL; |
|
95 tappend(arg); |
|
96 } |
|
97 |
|
98 static void |
|
99 ban_client(Client *c) |
27 ban_client(Client *c) |
100 { |
28 { |
101 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); |
29 XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); |
102 XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); |
30 XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); |
103 } |
|
104 |
|
105 void |
|
106 floating(Arg *arg) |
|
107 { |
|
108 Client *c; |
|
109 |
|
110 arrange = floating; |
|
111 for(c = clients; c; c = c->next) { |
|
112 if(c->tags[tsel]) |
|
113 resize(c, True); |
|
114 else |
|
115 ban_client(c); |
|
116 } |
|
117 if(sel && !sel->tags[tsel]) { |
|
118 if((sel = next(clients))) { |
|
119 craise(sel); |
|
120 focus(sel); |
|
121 } |
|
122 } |
|
123 draw_bar(); |
|
124 } |
|
125 |
|
126 void |
|
127 tiling(Arg *arg) |
|
128 { |
|
129 Client *c; |
|
130 int n, i, w, h; |
|
131 |
|
132 w = sw - mw; |
|
133 arrange = tiling; |
|
134 for(n = 0, c = clients; c; c = c->next) |
|
135 if(c->tags[tsel] && !c->floating) |
|
136 n++; |
|
137 |
|
138 if(n > 1) |
|
139 h = (sh - bh) / (n - 1); |
|
140 else |
|
141 h = sh - bh; |
|
142 |
|
143 for(i = 0, c = clients; c; c = c->next) { |
|
144 if(c->tags[tsel]) { |
|
145 if(c->floating) { |
|
146 craise(c); |
|
147 resize(c, True); |
|
148 continue; |
|
149 } |
|
150 if(n == 1) { |
|
151 c->x = sx; |
|
152 c->y = sy + bh; |
|
153 c->w = sw - 2 * c->border; |
|
154 c->h = sh - 2 * c->border - bh; |
|
155 } |
|
156 else if(i == 0) { |
|
157 c->x = sx; |
|
158 c->y = sy + bh; |
|
159 c->w = mw - 2 * c->border; |
|
160 c->h = sh - 2 * c->border - bh; |
|
161 } |
|
162 else { |
|
163 c->x = sx + mw; |
|
164 c->y = sy + (i - 1) * h + bh; |
|
165 c->w = w - 2 * c->border; |
|
166 c->h = h - 2 * c->border; |
|
167 } |
|
168 resize(c, False); |
|
169 i++; |
|
170 } |
|
171 else |
|
172 ban_client(c); |
|
173 } |
|
174 if(!sel || (sel && !sel->tags[tsel])) { |
|
175 if((sel = next(clients))) { |
|
176 craise(sel); |
|
177 focus(sel); |
|
178 } |
|
179 } |
|
180 draw_bar(); |
|
181 } |
|
182 |
|
183 void |
|
184 prevc(Arg *arg) |
|
185 { |
|
186 Client *c; |
|
187 |
|
188 if(!sel) |
|
189 return; |
|
190 |
|
191 if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { |
|
192 craise(c); |
|
193 focus(c); |
|
194 } |
|
195 } |
|
196 |
|
197 void |
|
198 nextc(Arg *arg) |
|
199 { |
|
200 Client *c; |
|
201 |
|
202 if(!sel) |
|
203 return; |
|
204 |
|
205 if(!(c = next(sel->next))) |
|
206 c = next(clients); |
|
207 if(c) { |
|
208 craise(c); |
|
209 c->revert = sel; |
|
210 focus(c); |
|
211 } |
|
212 } |
|
213 |
|
214 void |
|
215 ckill(Arg *arg) |
|
216 { |
|
217 if(!sel) |
|
218 return; |
|
219 if(sel->proto & WM_PROTOCOL_DELWIN) |
|
220 send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); |
|
221 else |
|
222 XKillClient(dpy, sel->win); |
|
223 } |
31 } |
224 |
32 |
225 static void |
33 static void |
226 resize_title(Client *c) |
34 resize_title(Client *c) |
227 { |
35 { |
228 int i; |
36 int i; |
229 |
37 |
230 c->tw = 0; |
38 c->tw = 0; |
231 for(i = 0; i < TLast; i++) |
39 for(i = 0; i < TLast; i++) |
232 if(c->tags[i]) |
40 if(c->tags[i]) |
233 c->tw += textw(c->tags[i]) + dc.font.height; |
41 c->tw += textw(c->tags[i]); |
234 c->tw += textw(c->name) + dc.font.height; |
42 c->tw += textw(c->name); |
235 if(c->tw > c->w) |
43 if(c->tw > c->w) |
236 c->tw = c->w + 2; |
44 c->tw = c->w + 2; |
237 c->tx = c->x + c->w - c->tw + 2; |
45 c->tx = c->x + c->w - c->tw + 2; |
238 c->ty = c->y; |
46 c->ty = c->y; |
239 XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th); |
47 XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th); |
582 for(c = clients; c; c = c->next) |
390 for(c = clients; c; c = c->next) |
583 if(c->win == w) |
391 if(c->win == w) |
584 return c; |
392 return c; |
585 return NULL; |
393 return NULL; |
586 } |
394 } |
587 |
|
588 void |
|
589 draw_client(Client *c) |
|
590 { |
|
591 int i; |
|
592 if(c == sel) { |
|
593 draw_bar(); |
|
594 XUnmapWindow(dpy, c->title); |
|
595 XSetWindowBorder(dpy, c->win, dc.fg); |
|
596 return; |
|
597 } |
|
598 |
|
599 XSetWindowBorder(dpy, c->win, dc.bg); |
|
600 XMapWindow(dpy, c->title); |
|
601 |
|
602 dc.x = dc.y = 0; |
|
603 |
|
604 dc.w = 0; |
|
605 for(i = 0; i < TLast; i++) { |
|
606 if(c->tags[i]) { |
|
607 dc.x += dc.w; |
|
608 dc.w = textw(c->tags[i]) + dc.font.height; |
|
609 drawtext(c->tags[i], False, True); |
|
610 } |
|
611 } |
|
612 dc.x += dc.w; |
|
613 dc.w = textw(c->name) + dc.font.height; |
|
614 drawtext(c->name, False, True); |
|
615 XCopyArea(dpy, dc.drawable, c->title, dc.gc, |
|
616 0, 0, c->tw, c->th, 0, 0); |
|
617 XFlush(dpy); |
|
618 } |
|