aewl
changeset 49:466591c2f967
implemented tagging a client
author | Anselm R. Garbe <garbeam@wmii.de> |
---|---|
date | Thu, 13 Jul 2006 17:09:35 +0200 |
parents | ceff29af8c7b |
children | 148f25ed0ad7 |
files | client.c dev.c dwm.h main.c util.c |
diffstat | 5 files changed, 156 insertions(+), 85 deletions(-) [+] |
line diff
1.1 --- a/client.c Thu Jul 13 14:33:22 2006 +0200 1.2 +++ b/client.c Thu Jul 13 17:09:35 2006 +0200 1.3 @@ -11,44 +11,76 @@ 1.4 1.5 #include "dwm.h" 1.6 1.7 -static void (*arrange)(void *) = floating; 1.8 +static void (*arrange)(Arg *) = floating; 1.9 + 1.10 +static Client * 1.11 +next(Client *c) 1.12 +{ 1.13 + for(c = c->next; c && !c->tags[tsel]; c = c->next); 1.14 + return c; 1.15 +} 1.16 + 1.17 +static Client * 1.18 +prev(Client *c) 1.19 +{ 1.20 + for(c = c->prev; c && !c->tags[tsel]; c = c->prev); 1.21 + return c; 1.22 +} 1.23 1.24 void 1.25 -max(void *aux) 1.26 +max(Arg *arg) 1.27 { 1.28 - if(!stack) 1.29 + if(!csel) 1.30 return; 1.31 - stack->x = sx; 1.32 - stack->y = sy; 1.33 - stack->w = sw - 2 * stack->border; 1.34 - stack->h = sh - 2 * stack->border; 1.35 - craise(stack); 1.36 - resize(stack); 1.37 + csel->x = sx; 1.38 + csel->y = sy; 1.39 + csel->w = sw - 2 * csel->border; 1.40 + csel->h = sh - 2 * csel->border; 1.41 + craise(csel); 1.42 + resize(csel); 1.43 discard_events(EnterWindowMask); 1.44 } 1.45 1.46 void 1.47 -floating(void *aux) 1.48 +tag(Arg *arg) 1.49 +{ 1.50 + if(!csel) 1.51 + return; 1.52 + 1.53 + if(arg->i == tsel) 1.54 + return; 1.55 + 1.56 + if(csel->tags[arg->i]) 1.57 + csel->tags[arg->i] = NULL; /* toggle tag */ 1.58 + else 1.59 + csel->tags[arg->i] = tags[arg->i]; 1.60 + arrange(NULL); 1.61 +} 1.62 + 1.63 +void 1.64 +floating(Arg *arg) 1.65 { 1.66 Client *c; 1.67 1.68 arrange = floating; 1.69 - for(c = stack; c; c = c->snext) 1.70 + if(!csel) 1.71 + return; 1.72 + for(c = csel; c; c = next(c)) 1.73 resize(c); 1.74 discard_events(EnterWindowMask); 1.75 } 1.76 1.77 void 1.78 -tiling(void *aux) 1.79 +tiling(Arg *arg) 1.80 { 1.81 Client *c; 1.82 int n, cols, rows, gw, gh, i, j; 1.83 float rt, fd; 1.84 1.85 arrange = tiling; 1.86 - if(!clients) 1.87 + if(!csel) 1.88 return; 1.89 - for(n = 0, c = clients; c; c = c->next, n++); 1.90 + for(n = 0, c = csel; c; c = next(c), n++); 1.91 rt = sqrt(n); 1.92 if(modff(rt, &fd) < 0.5) 1.93 rows = floor(rt); 1.94 @@ -62,7 +94,7 @@ 1.95 gw = (sw - 2) / cols; 1.96 gh = (sh - 2) / rows; 1.97 1.98 - for(i = j = 0, c = clients; c; c = c->next) { 1.99 + for(i = j = 0, c = csel; c; c = next(c)) { 1.100 c->x = i * gw; 1.101 c->y = j * gh; 1.102 c->w = gw; 1.103 @@ -77,28 +109,44 @@ 1.104 } 1.105 1.106 void 1.107 -sel(void *aux) 1.108 +prevc(Arg *arg) 1.109 { 1.110 - const char *arg = aux; 1.111 - Client *c = NULL; 1.112 + Client *c; 1.113 1.114 - if(!arg || !stack) 1.115 + if(!csel) 1.116 return; 1.117 - if(!strncmp(arg, "next", 5)) 1.118 - c = stack->snext ? stack->snext : stack; 1.119 - else if(!strncmp(arg, "prev", 5)) 1.120 - for(c = stack; c && c->snext; c = c->snext); 1.121 - if(!c) 1.122 - c = stack; 1.123 - craise(c); 1.124 - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); 1.125 - focus(c); 1.126 + 1.127 + if(!(c = prev(csel))) 1.128 + c = prev(cend); 1.129 + if(c) { 1.130 + craise(c); 1.131 + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); 1.132 + focus(c); 1.133 + } 1.134 } 1.135 1.136 void 1.137 -ckill(void *aux) 1.138 +nextc(Arg *arg) 1.139 { 1.140 - Client *c = stack; 1.141 + Client *c; 1.142 + 1.143 + if(!csel) 1.144 + return; 1.145 + 1.146 + if(!(c = next(csel))) 1.147 + c = next(cstart); 1.148 + 1.149 + if(c) { 1.150 + craise(c); 1.151 + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); 1.152 + focus(c); 1.153 + } 1.154 +} 1.155 + 1.156 +void 1.157 +ckill(Arg *arg) 1.158 +{ 1.159 + Client *c = csel; 1.160 1.161 if(!c) 1.162 return; 1.163 @@ -208,19 +256,12 @@ 1.164 void 1.165 focus(Client *c) 1.166 { 1.167 - Client **l, *old; 1.168 - 1.169 - old = stack; 1.170 - for(l = &stack; *l && *l != c; l = &(*l)->snext); 1.171 - if(*l) 1.172 - *l = c->snext; 1.173 - c->snext = stack; 1.174 - stack = c; 1.175 - if(old && old != c) { 1.176 - XSetWindowBorder(dpy, old->win, dc.bg); 1.177 - XMapWindow(dpy, old->title); 1.178 - draw_client(old); 1.179 + if(csel && csel != c) { 1.180 + XSetWindowBorder(dpy, csel->win, dc.bg); 1.181 + XMapWindow(dpy, csel->title); 1.182 + draw_client(csel); 1.183 } 1.184 + csel = c; 1.185 XUnmapWindow(dpy, c->title); 1.186 XSetWindowBorder(dpy, c->win, dc.fg); 1.187 draw_client(c); 1.188 @@ -232,7 +273,7 @@ 1.189 void 1.190 manage(Window w, XWindowAttributes *wa) 1.191 { 1.192 - Client *c, **l; 1.193 + Client *c; 1.194 XSetWindowAttributes twa; 1.195 1.196 c = emallocz(sizeof(Client)); 1.197 @@ -258,9 +299,15 @@ 1.198 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); 1.199 1.200 update_name(c); 1.201 - for(l=&clients; *l; l=&(*l)->next); 1.202 - c->next = *l; /* *l == nil */ 1.203 - *l = c; 1.204 + 1.205 + if(!cstart) 1.206 + cstart = cend = c; 1.207 + else { 1.208 + cend->next = c; 1.209 + c->prev = cend; 1.210 + cend = c; 1.211 + } 1.212 + 1.213 XSetWindowBorderWidth(dpy, c->win, 1); 1.214 XMapRaised(dpy, c->win); 1.215 XMapRaised(dpy, c->title); 1.216 @@ -373,33 +420,42 @@ 1.217 void 1.218 unmanage(Client *c) 1.219 { 1.220 - Client **l; 1.221 - 1.222 XGrabServer(dpy); 1.223 XSetErrorHandler(dummy_error_handler); 1.224 1.225 XUngrabButton(dpy, AnyButton, AnyModifier, c->win); 1.226 XDestroyWindow(dpy, c->title); 1.227 1.228 - for(l=&clients; *l && *l != c; l=&(*l)->next); 1.229 - *l = c->next; 1.230 - for(l=&stack; *l && *l != c; l=&(*l)->snext); 1.231 - *l = c->snext; 1.232 + if(c->prev) { 1.233 + c->prev->next = c->next; 1.234 + if(csel == c) 1.235 + csel = c->prev; 1.236 + } 1.237 + if(c->next) { 1.238 + c->next->prev = c->prev; 1.239 + if(csel == c) 1.240 + csel = c->next; 1.241 + } 1.242 + if(cstart == c) 1.243 + cstart = c->next; 1.244 + if(cend == c) 1.245 + cend = c->prev; 1.246 + 1.247 free(c); 1.248 1.249 XFlush(dpy); 1.250 XSetErrorHandler(error_handler); 1.251 XUngrabServer(dpy); 1.252 arrange(NULL); 1.253 - if(stack) 1.254 - focus(stack); 1.255 + if(csel) 1.256 + focus(csel); 1.257 } 1.258 1.259 Client * 1.260 gettitle(Window w) 1.261 { 1.262 Client *c; 1.263 - for(c = clients; c; c = c->next) 1.264 + for(c = cstart; c; c = c->next) 1.265 if(c->title == w) 1.266 return c; 1.267 return NULL; 1.268 @@ -409,7 +465,7 @@ 1.269 getclient(Window w) 1.270 { 1.271 Client *c; 1.272 - for(c = clients; c; c = c->next) 1.273 + for(c = cstart; c; c = c->next) 1.274 if(c->win == w) 1.275 return c; 1.276 return NULL; 1.277 @@ -419,7 +475,7 @@ 1.278 draw_client(Client *c) 1.279 { 1.280 int i; 1.281 - if(c == stack) 1.282 + if(c == csel) 1.283 return; 1.284 1.285 dc.x = dc.y = 0;
2.1 --- a/dev.c Thu Jul 13 14:33:22 2006 +0200 2.2 +++ b/dev.c Thu Jul 13 17:09:35 2006 +0200 2.3 @@ -20,16 +20,21 @@ 2.4 const char *xlock[] = { "xlock", NULL }; 2.5 2.6 static Key key[] = { 2.7 - { Mod1Mask, XK_Return, (void (*)(void *))spawn, term }, 2.8 - { Mod1Mask, XK_w, (void (*)(void *))spawn, browse }, 2.9 - { Mod1Mask, XK_l, (void (*)(void *))spawn, xlock }, 2.10 - { Mod1Mask, XK_k, sel, "prev" }, 2.11 - { Mod1Mask, XK_j, sel, "next" }, 2.12 - { Mod1Mask, XK_t, tiling, NULL }, 2.13 - { Mod1Mask, XK_f, floating, NULL }, 2.14 - { Mod1Mask, XK_m, max, NULL }, 2.15 - { Mod1Mask | ShiftMask, XK_c, ckill, NULL }, 2.16 - { Mod1Mask | ShiftMask, XK_q, quit, NULL }, 2.17 + { Mod1Mask, XK_Return, spawn, { .argv = term } }, 2.18 + { Mod1Mask, XK_w, spawn, { .argv = browse } }, 2.19 + { Mod1Mask, XK_l, spawn, { .argv = xlock } }, 2.20 + { Mod1Mask, XK_k, prevc, { 0 } }, 2.21 + { Mod1Mask, XK_j, nextc, { 0 } }, 2.22 + { Mod1Mask, XK_t, tiling, { 0 } }, 2.23 + { Mod1Mask, XK_f, floating, { 0 } }, 2.24 + { Mod1Mask, XK_m, max, { 0 } }, 2.25 + { Mod1Mask, XK_0, tag, { .i = Tscratch } }, 2.26 + { Mod1Mask, XK_1, tag, { .i = Tdev } }, 2.27 + { Mod1Mask, XK_2, tag, { .i = Tirc } }, 2.28 + { Mod1Mask, XK_3, tag, { .i = Twww } }, 2.29 + { Mod1Mask, XK_4, tag, { .i = Twork } }, 2.30 + { Mod1Mask | ShiftMask, XK_c, ckill, { 0 } }, 2.31 + { Mod1Mask | ShiftMask, XK_q, quit, { 0 } }, 2.32 }; 2.33 2.34 /********** CUSTOMIZE **********/ 2.35 @@ -60,7 +65,7 @@ 2.36 for(i = 0; i < len; i++) 2.37 if((keysym == key[i].keysym) && (key[i].mod == ev->state)) { 2.38 if(key[i].func) 2.39 - key[i].func(key[i].aux); 2.40 + key[i].func(&key[i].arg); 2.41 return; 2.42 } 2.43 }
3.1 --- a/dwm.h Thu Jul 13 14:33:22 2006 +0200 3.2 +++ b/dwm.h Thu Jul 13 17:09:35 2006 +0200 3.3 @@ -22,6 +22,12 @@ 3.4 typedef struct Client Client; 3.5 typedef struct Fnt Fnt; 3.6 typedef struct Key Key; 3.7 +typedef union Arg Arg; 3.8 + 3.9 +union Arg { 3.10 + const char **argv; 3.11 + int i; 3.12 +}; 3.13 3.14 /* atoms */ 3.15 enum { WMProtocols, WMDelete, WMLast }; 3.16 @@ -62,14 +68,14 @@ 3.17 Window trans; 3.18 Window title; 3.19 Client *next; 3.20 - Client *snext; 3.21 + Client *prev; 3.22 }; 3.23 3.24 struct Key { 3.25 unsigned long mod; 3.26 KeySym keysym; 3.27 - void (*func)(void *aux); 3.28 - void *aux; 3.29 + void (*func)(Arg *arg); 3.30 + Arg arg; 3.31 }; 3.32 3.33 extern Display *dpy; 3.34 @@ -83,7 +89,7 @@ 3.35 extern char stext[1024], *tags[TLast]; 3.36 3.37 extern DC dc; 3.38 -extern Client *clients, *stack; 3.39 +extern Client *cstart, *cend, *csel; 3.40 3.41 /* client.c */ 3.42 extern void manage(Window w, XWindowAttributes *wa); 3.43 @@ -97,11 +103,13 @@ 3.44 extern Client *gettitle(Window w); 3.45 extern void craise(Client *c); 3.46 extern void lower(Client *c); 3.47 -extern void ckill(void *aux); 3.48 -extern void sel(void *aux); 3.49 -extern void max(void *aux); 3.50 -extern void floating(void *aux); 3.51 -extern void tiling(void *aux); 3.52 +extern void ckill(Arg *arg); 3.53 +extern void nextc(Arg *arg); 3.54 +extern void prevc(Arg *arg); 3.55 +extern void max(Arg *arg); 3.56 +extern void floating(Arg *arg); 3.57 +extern void tiling(Arg *arg); 3.58 +void tag(Arg *arg); 3.59 extern void gravitate(Client *c, Bool invert); 3.60 3.61 /* draw.c */ 3.62 @@ -125,7 +133,7 @@ 3.63 extern int error_handler(Display *dsply, XErrorEvent *e); 3.64 extern void send_message(Window w, Atom a, long value); 3.65 extern int win_proto(Window w); 3.66 -extern void quit(void *aux); 3.67 +extern void quit(Arg *arg); 3.68 3.69 /* util.c */ 3.70 extern void error(const char *errstr, ...); 3.71 @@ -133,5 +141,5 @@ 3.72 extern void *emalloc(unsigned int size); 3.73 extern void *erealloc(void *ptr, unsigned int size); 3.74 extern char *estrdup(const char *str); 3.75 -extern void spawn(char *argv[]); 3.76 +extern void spawn(Arg *arg); 3.77 extern void swap(void **p1, void **p2);
4.1 --- a/main.c Thu Jul 13 14:33:22 2006 +0200 4.2 +++ b/main.c Thu Jul 13 17:09:35 2006 +0200 4.3 @@ -38,8 +38,9 @@ 4.4 int screen, sx, sy, sw, sh, th; 4.5 4.6 DC dc = {0}; 4.7 -Client *clients = NULL; 4.8 -Client *stack = NULL; 4.9 +Client *cstart = NULL; 4.10 +Client *cend = NULL; 4.11 +Client *csel = NULL; 4.12 4.13 static Bool other_wm_running; 4.14 static const char version[] = 4.15 @@ -168,13 +169,13 @@ 4.16 static void 4.17 cleanup() 4.18 { 4.19 - while(clients) 4.20 - unmanage(clients); 4.21 + while(csel) 4.22 + unmanage(csel); 4.23 XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); 4.24 } 4.25 4.26 void 4.27 -quit(void *aux) 4.28 +quit(Arg *arg) 4.29 { 4.30 running = False; 4.31 }