Mercurial > dwm-meillo
comparison client.c @ 49:466591c2f967
implemented tagging a client
author | Anselm R. Garbe <garbeam@wmii.de> |
---|---|
date | Thu, 13 Jul 2006 17:09:35 +0200 |
parents | 58307ad56ec1 |
children | 148f25ed0ad7 |
comparison
equal
deleted
inserted
replaced
48:ceff29af8c7b | 49:466591c2f967 |
---|---|
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)(void *) = floating; | 14 static void (*arrange)(Arg *) = floating; |
15 | 15 |
16 void | 16 static Client * |
17 max(void *aux) | 17 next(Client *c) |
18 { | 18 { |
19 if(!stack) | 19 for(c = c->next; c && !c->tags[tsel]; c = c->next); |
20 return; | 20 return c; |
21 stack->x = sx; | 21 } |
22 stack->y = sy; | 22 |
23 stack->w = sw - 2 * stack->border; | 23 static Client * |
24 stack->h = sh - 2 * stack->border; | 24 prev(Client *c) |
25 craise(stack); | 25 { |
26 resize(stack); | 26 for(c = c->prev; c && !c->tags[tsel]; c = c->prev); |
27 return c; | |
28 } | |
29 | |
30 void | |
31 max(Arg *arg) | |
32 { | |
33 if(!csel) | |
34 return; | |
35 csel->x = sx; | |
36 csel->y = sy; | |
37 csel->w = sw - 2 * csel->border; | |
38 csel->h = sh - 2 * csel->border; | |
39 craise(csel); | |
40 resize(csel); | |
27 discard_events(EnterWindowMask); | 41 discard_events(EnterWindowMask); |
28 } | 42 } |
29 | 43 |
30 void | 44 void |
31 floating(void *aux) | 45 tag(Arg *arg) |
46 { | |
47 if(!csel) | |
48 return; | |
49 | |
50 if(arg->i == tsel) | |
51 return; | |
52 | |
53 if(csel->tags[arg->i]) | |
54 csel->tags[arg->i] = NULL; /* toggle tag */ | |
55 else | |
56 csel->tags[arg->i] = tags[arg->i]; | |
57 arrange(NULL); | |
58 } | |
59 | |
60 void | |
61 floating(Arg *arg) | |
32 { | 62 { |
33 Client *c; | 63 Client *c; |
34 | 64 |
35 arrange = floating; | 65 arrange = floating; |
36 for(c = stack; c; c = c->snext) | 66 if(!csel) |
67 return; | |
68 for(c = csel; c; c = next(c)) | |
37 resize(c); | 69 resize(c); |
38 discard_events(EnterWindowMask); | 70 discard_events(EnterWindowMask); |
39 } | 71 } |
40 | 72 |
41 void | 73 void |
42 tiling(void *aux) | 74 tiling(Arg *arg) |
43 { | 75 { |
44 Client *c; | 76 Client *c; |
45 int n, cols, rows, gw, gh, i, j; | 77 int n, cols, rows, gw, gh, i, j; |
46 float rt, fd; | 78 float rt, fd; |
47 | 79 |
48 arrange = tiling; | 80 arrange = tiling; |
49 if(!clients) | 81 if(!csel) |
50 return; | 82 return; |
51 for(n = 0, c = clients; c; c = c->next, n++); | 83 for(n = 0, c = csel; c; c = next(c), n++); |
52 rt = sqrt(n); | 84 rt = sqrt(n); |
53 if(modff(rt, &fd) < 0.5) | 85 if(modff(rt, &fd) < 0.5) |
54 rows = floor(rt); | 86 rows = floor(rt); |
55 else | 87 else |
56 rows = ceil(rt); | 88 rows = ceil(rt); |
60 cols = rows; | 92 cols = rows; |
61 | 93 |
62 gw = (sw - 2) / cols; | 94 gw = (sw - 2) / cols; |
63 gh = (sh - 2) / rows; | 95 gh = (sh - 2) / rows; |
64 | 96 |
65 for(i = j = 0, c = clients; c; c = c->next) { | 97 for(i = j = 0, c = csel; c; c = next(c)) { |
66 c->x = i * gw; | 98 c->x = i * gw; |
67 c->y = j * gh; | 99 c->y = j * gh; |
68 c->w = gw; | 100 c->w = gw; |
69 c->h = gh; | 101 c->h = gh; |
70 resize(c); | 102 resize(c); |
75 } | 107 } |
76 discard_events(EnterWindowMask); | 108 discard_events(EnterWindowMask); |
77 } | 109 } |
78 | 110 |
79 void | 111 void |
80 sel(void *aux) | 112 prevc(Arg *arg) |
81 { | 113 { |
82 const char *arg = aux; | 114 Client *c; |
83 Client *c = NULL; | 115 |
84 | 116 if(!csel) |
85 if(!arg || !stack) | 117 return; |
86 return; | 118 |
87 if(!strncmp(arg, "next", 5)) | 119 if(!(c = prev(csel))) |
88 c = stack->snext ? stack->snext : stack; | 120 c = prev(cend); |
89 else if(!strncmp(arg, "prev", 5)) | 121 if(c) { |
90 for(c = stack; c && c->snext; c = c->snext); | 122 craise(c); |
91 if(!c) | 123 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); |
92 c = stack; | 124 focus(c); |
93 craise(c); | 125 } |
94 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); | 126 } |
95 focus(c); | 127 |
96 } | 128 void |
97 | 129 nextc(Arg *arg) |
98 void | 130 { |
99 ckill(void *aux) | 131 Client *c; |
100 { | 132 |
101 Client *c = stack; | 133 if(!csel) |
134 return; | |
135 | |
136 if(!(c = next(csel))) | |
137 c = next(cstart); | |
138 | |
139 if(c) { | |
140 craise(c); | |
141 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); | |
142 focus(c); | |
143 } | |
144 } | |
145 | |
146 void | |
147 ckill(Arg *arg) | |
148 { | |
149 Client *c = csel; | |
102 | 150 |
103 if(!c) | 151 if(!c) |
104 return; | 152 return; |
105 if(c->proto & WM_PROTOCOL_DELWIN) | 153 if(c->proto & WM_PROTOCOL_DELWIN) |
106 send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]); | 154 send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]); |
206 } | 254 } |
207 | 255 |
208 void | 256 void |
209 focus(Client *c) | 257 focus(Client *c) |
210 { | 258 { |
211 Client **l, *old; | 259 if(csel && csel != c) { |
212 | 260 XSetWindowBorder(dpy, csel->win, dc.bg); |
213 old = stack; | 261 XMapWindow(dpy, csel->title); |
214 for(l = &stack; *l && *l != c; l = &(*l)->snext); | 262 draw_client(csel); |
215 if(*l) | 263 } |
216 *l = c->snext; | 264 csel = c; |
217 c->snext = stack; | |
218 stack = c; | |
219 if(old && old != c) { | |
220 XSetWindowBorder(dpy, old->win, dc.bg); | |
221 XMapWindow(dpy, old->title); | |
222 draw_client(old); | |
223 } | |
224 XUnmapWindow(dpy, c->title); | 265 XUnmapWindow(dpy, c->title); |
225 XSetWindowBorder(dpy, c->win, dc.fg); | 266 XSetWindowBorder(dpy, c->win, dc.fg); |
226 draw_client(c); | 267 draw_client(c); |
227 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); | 268 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
228 XFlush(dpy); | 269 XFlush(dpy); |
230 } | 271 } |
231 | 272 |
232 void | 273 void |
233 manage(Window w, XWindowAttributes *wa) | 274 manage(Window w, XWindowAttributes *wa) |
234 { | 275 { |
235 Client *c, **l; | 276 Client *c; |
236 XSetWindowAttributes twa; | 277 XSetWindowAttributes twa; |
237 | 278 |
238 c = emallocz(sizeof(Client)); | 279 c = emallocz(sizeof(Client)); |
239 c->win = w; | 280 c->win = w; |
240 c->tx = c->x = wa->x; | 281 c->tx = c->x = wa->x; |
256 0, DefaultDepth(dpy, screen), CopyFromParent, | 297 0, DefaultDepth(dpy, screen), CopyFromParent, |
257 DefaultVisual(dpy, screen), | 298 DefaultVisual(dpy, screen), |
258 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); | 299 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); |
259 | 300 |
260 update_name(c); | 301 update_name(c); |
261 for(l=&clients; *l; l=&(*l)->next); | 302 |
262 c->next = *l; /* *l == nil */ | 303 if(!cstart) |
263 *l = c; | 304 cstart = cend = c; |
305 else { | |
306 cend->next = c; | |
307 c->prev = cend; | |
308 cend = c; | |
309 } | |
310 | |
264 XSetWindowBorderWidth(dpy, c->win, 1); | 311 XSetWindowBorderWidth(dpy, c->win, 1); |
265 XMapRaised(dpy, c->win); | 312 XMapRaised(dpy, c->win); |
266 XMapRaised(dpy, c->title); | 313 XMapRaised(dpy, c->title); |
267 XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask, | 314 XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask, |
268 GrabModeAsync, GrabModeSync, None, None); | 315 GrabModeAsync, GrabModeSync, None, None); |
371 } | 418 } |
372 | 419 |
373 void | 420 void |
374 unmanage(Client *c) | 421 unmanage(Client *c) |
375 { | 422 { |
376 Client **l; | |
377 | |
378 XGrabServer(dpy); | 423 XGrabServer(dpy); |
379 XSetErrorHandler(dummy_error_handler); | 424 XSetErrorHandler(dummy_error_handler); |
380 | 425 |
381 XUngrabButton(dpy, AnyButton, AnyModifier, c->win); | 426 XUngrabButton(dpy, AnyButton, AnyModifier, c->win); |
382 XDestroyWindow(dpy, c->title); | 427 XDestroyWindow(dpy, c->title); |
383 | 428 |
384 for(l=&clients; *l && *l != c; l=&(*l)->next); | 429 if(c->prev) { |
385 *l = c->next; | 430 c->prev->next = c->next; |
386 for(l=&stack; *l && *l != c; l=&(*l)->snext); | 431 if(csel == c) |
387 *l = c->snext; | 432 csel = c->prev; |
433 } | |
434 if(c->next) { | |
435 c->next->prev = c->prev; | |
436 if(csel == c) | |
437 csel = c->next; | |
438 } | |
439 if(cstart == c) | |
440 cstart = c->next; | |
441 if(cend == c) | |
442 cend = c->prev; | |
443 | |
388 free(c); | 444 free(c); |
389 | 445 |
390 XFlush(dpy); | 446 XFlush(dpy); |
391 XSetErrorHandler(error_handler); | 447 XSetErrorHandler(error_handler); |
392 XUngrabServer(dpy); | 448 XUngrabServer(dpy); |
393 arrange(NULL); | 449 arrange(NULL); |
394 if(stack) | 450 if(csel) |
395 focus(stack); | 451 focus(csel); |
396 } | 452 } |
397 | 453 |
398 Client * | 454 Client * |
399 gettitle(Window w) | 455 gettitle(Window w) |
400 { | 456 { |
401 Client *c; | 457 Client *c; |
402 for(c = clients; c; c = c->next) | 458 for(c = cstart; c; c = c->next) |
403 if(c->title == w) | 459 if(c->title == w) |
404 return c; | 460 return c; |
405 return NULL; | 461 return NULL; |
406 } | 462 } |
407 | 463 |
408 Client * | 464 Client * |
409 getclient(Window w) | 465 getclient(Window w) |
410 { | 466 { |
411 Client *c; | 467 Client *c; |
412 for(c = clients; c; c = c->next) | 468 for(c = cstart; c; c = c->next) |
413 if(c->win == w) | 469 if(c->win == w) |
414 return c; | 470 return c; |
415 return NULL; | 471 return NULL; |
416 } | 472 } |
417 | 473 |
418 void | 474 void |
419 draw_client(Client *c) | 475 draw_client(Client *c) |
420 { | 476 { |
421 int i; | 477 int i; |
422 if(c == stack) | 478 if(c == csel) |
423 return; | 479 return; |
424 | 480 |
425 dc.x = dc.y = 0; | 481 dc.x = dc.y = 0; |
426 dc.h = c->th; | 482 dc.h = c->th; |
427 | 483 |