Mercurial > dwm-meillo
comparison client.c @ 51:035617ee18d1
new stuff
author | Anselm R. Garbe <garbeam@wmii.de> |
---|---|
date | Thu, 13 Jul 2006 19:55:07 +0200 |
parents | 148f25ed0ad7 |
children | d18f6dd0cf23 |
comparison
equal
deleted
inserted
replaced
50:148f25ed0ad7 | 51:035617ee18d1 |
---|---|
1 /* | 1 /* |
2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | 2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> |
3 * See LICENSE file for license details. | 3 * See LICENSE file for license details. |
4 */ | 4 */ |
5 | 5 |
6 #include <math.h> | |
7 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <stdio.h> | |
8 #include <string.h> | 8 #include <string.h> |
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 static void (*arrange)(Arg *) = floating; | 14 static void (*arrange)(Arg *) = tiling; |
15 | 15 |
16 static void | 16 static Rule rule[] = { |
17 center(Client *c) | 17 { "Firefox-bin", "Gecko", { [Twww] = "www" } }, |
18 { | 18 }; |
19 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); | |
20 } | |
21 | 19 |
22 static Client * | 20 static Client * |
23 next(Client *c) | 21 next(Client *c) |
24 { | 22 { |
25 for(; c && !c->tags[tsel]; c = c->next); | 23 for(; c && !c->tags[tsel]; c = c->next); |
27 } | 25 } |
28 | 26 |
29 void | 27 void |
30 zoom(Arg *arg) | 28 zoom(Arg *arg) |
31 { | 29 { |
32 Client **l; | 30 Client **l, *old; |
33 | 31 |
34 if(!sel) | 32 if(!(old = sel)) |
35 return; | 33 return; |
36 | 34 |
37 for(l = &clients; *l && *l != sel; l = &(*l)->next); | 35 for(l = &clients; *l && *l != sel; l = &(*l)->next); |
38 *l = sel->next; | 36 *l = sel->next; |
39 | 37 |
40 sel->next = clients; /* pop */ | 38 old->next = clients; /* pop */ |
41 clients = sel; | 39 clients = old; |
40 sel = old; | |
42 arrange(NULL); | 41 arrange(NULL); |
43 center(sel); | |
44 focus(sel); | 42 focus(sel); |
45 } | 43 } |
46 | 44 |
47 void | 45 void |
48 max(Arg *arg) | 46 max(Arg *arg) |
117 | 115 |
118 void | 116 void |
119 tiling(Arg *arg) | 117 tiling(Arg *arg) |
120 { | 118 { |
121 Client *c; | 119 Client *c; |
122 int n, cols, rows, gw, gh, i, j; | 120 int n, i, w, h; |
123 float rt, fd; | 121 |
124 | 122 w = sw - mw; |
125 arrange = tiling; | 123 arrange = tiling; |
126 for(n = 0, c = clients; c; c = next(c->next), n++); | 124 for(n = 0, c = clients; c; c = c->next) |
127 if(n) { | 125 if(c->tags[tsel]) |
128 rt = sqrt(n); | 126 n++; |
129 if(modff(rt, &fd) < 0.5) | 127 |
130 rows = floor(rt); | 128 h = (n > 2) ? sh / (n - 2) : sh; |
131 else | 129 |
132 rows = ceil(rt); | 130 for(i = 0, c = clients; c; c = c->next) { |
133 if(rows * rows < n) | |
134 cols = rows + 1; | |
135 else | |
136 cols = rows; | |
137 | |
138 gw = (sw - 2) / cols; | |
139 gh = (sh - 2) / rows; | |
140 } | |
141 else | |
142 cols = rows = gw = gh = 0; | |
143 | |
144 for(i = j = 0, c = clients; c; c = c->next) { | |
145 if(c->tags[tsel]) { | 131 if(c->tags[tsel]) { |
146 c->x = i * gw; | 132 if(n == 1) { |
147 c->y = j * gh; | 133 c->x = sx; |
148 c->w = gw; | 134 c->y = sy; |
149 c->h = gh; | 135 c->w = sw; |
136 c->h = sh; | |
137 } | |
138 else if(i == 1) { | |
139 c->x = sx; | |
140 c->y = sy; | |
141 c->w = mw; | |
142 c->h = sh; | |
143 } | |
144 else { | |
145 c->x = sx + mw; | |
146 c->y = sy + (i - 2) * h; | |
147 c->w = w; | |
148 c->h = h; | |
149 } | |
150 resize(c); | 150 resize(c); |
151 if(++i == cols) { | 151 i++; |
152 j++; | |
153 i = 0; | |
154 } | |
155 } | 152 } |
156 else | 153 else |
157 ban_client(c); | 154 ban_client(c); |
158 } | 155 } |
159 if(sel && !sel->tags[tsel]) { | 156 if(sel && !sel->tags[tsel]) { |
173 if(!sel) | 170 if(!sel) |
174 return; | 171 return; |
175 | 172 |
176 if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { | 173 if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { |
177 craise(c); | 174 craise(c); |
178 center(c); | |
179 focus(c); | 175 focus(c); |
180 } | 176 } |
181 } | 177 } |
182 | 178 |
183 void | 179 void |
190 | 186 |
191 if(!(c = next(sel->next))) | 187 if(!(c = next(sel->next))) |
192 c = next(clients); | 188 c = next(clients); |
193 if(c) { | 189 if(c) { |
194 craise(c); | 190 craise(c); |
195 center(c); | |
196 c->revert = sel; | 191 c->revert = sel; |
197 focus(c); | 192 focus(c); |
198 } | 193 } |
199 } | 194 } |
200 | 195 |
319 XSetWindowBorder(dpy, c->win, dc.fg); | 314 XSetWindowBorder(dpy, c->win, dc.fg); |
320 draw_client(c); | 315 draw_client(c); |
321 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); | 316 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
322 XFlush(dpy); | 317 XFlush(dpy); |
323 discard_events(EnterWindowMask); | 318 discard_events(EnterWindowMask); |
319 } | |
320 | |
321 static void | |
322 init_tags(Client *c) | |
323 { | |
324 XClassHint ch; | |
325 static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; | |
326 unsigned int i, j; | |
327 Bool matched = False; | |
328 | |
329 if(!len) { | |
330 c->tags[tsel] = tags[tsel]; | |
331 return; | |
332 } | |
333 | |
334 if(XGetClassHint(dpy, c->win, &ch)) { | |
335 if(ch.res_class && ch.res_name) { | |
336 fprintf(stderr, "%s:%s\n", ch.res_class, ch.res_name); | |
337 for(i = 0; i < len; i++) | |
338 if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class)) | |
339 && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) | |
340 { | |
341 fprintf(stderr, "->>>%s:%s\n", ch.res_class, ch.res_name); | |
342 for(j = 0; j < TLast; j++) | |
343 c->tags[j] = rule[i].tags[j]; | |
344 matched = True; | |
345 break; | |
346 } | |
347 } | |
348 if(ch.res_class) | |
349 XFree(ch.res_class); | |
350 if(ch.res_name) | |
351 XFree(ch.res_name); | |
352 } | |
353 | |
354 if(!matched) | |
355 c->tags[tsel] = tags[tsel]; | |
324 } | 356 } |
325 | 357 |
326 void | 358 void |
327 manage(Window w, XWindowAttributes *wa) | 359 manage(Window w, XWindowAttributes *wa) |
328 { | 360 { |
344 XGetTransientForHint(dpy, c->win, &c->trans); | 376 XGetTransientForHint(dpy, c->win, &c->trans); |
345 twa.override_redirect = 1; | 377 twa.override_redirect = 1; |
346 twa.background_pixmap = ParentRelative; | 378 twa.background_pixmap = ParentRelative; |
347 twa.event_mask = ExposureMask; | 379 twa.event_mask = ExposureMask; |
348 | 380 |
349 c->tags[tsel] = tags[tsel]; | |
350 c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th, | 381 c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th, |
351 0, DefaultDepth(dpy, screen), CopyFromParent, | 382 0, DefaultDepth(dpy, screen), CopyFromParent, |
352 DefaultVisual(dpy, screen), | 383 DefaultVisual(dpy, screen), |
353 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); | 384 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); |
354 | 385 |
355 update_name(c); | 386 update_name(c); |
387 init_tags(c); | |
356 | 388 |
357 for(l = &clients; *l; l = &(*l)->next); | 389 for(l = &clients; *l; l = &(*l)->next); |
358 c->next = *l; /* *l == nil */ | 390 c->next = *l; /* *l == nil */ |
359 *l = c; | 391 *l = c; |
360 | 392 |
366 XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask, | 398 XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask, |
367 GrabModeAsync, GrabModeSync, None, None); | 399 GrabModeAsync, GrabModeSync, None, None); |
368 XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, | 400 XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, |
369 GrabModeAsync, GrabModeSync, None, None); | 401 GrabModeAsync, GrabModeSync, None, None); |
370 arrange(NULL); | 402 arrange(NULL); |
371 center(c); | 403 if(c->tags[tsel]) |
372 focus(c); | 404 focus(c); |
405 else | |
406 ban_client(c); | |
373 } | 407 } |
374 | 408 |
375 void | 409 void |
376 gravitate(Client *c, Bool invert) | 410 gravitate(Client *c, Bool invert) |
377 { | 411 { |