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