aewl
changeset 50:148f25ed0ad7
several other additions/fixes, dwm is quite usable already
author | Anselm R. Garbe <garbeam@wmii.de> |
---|---|
date | Thu, 13 Jul 2006 18:21:38 +0200 |
parents | 466591c2f967 |
children | 035617ee18d1 |
files | client.c dev.c dwm.h main.c |
diffstat | 4 files changed, 164 insertions(+), 110 deletions(-) [+] |
line diff
1.1 --- a/client.c Thu Jul 13 17:09:35 2006 +0200 1.2 +++ b/client.c Thu Jul 13 18:21:38 2006 +0200 1.3 @@ -13,60 +13,105 @@ 1.4 1.5 static void (*arrange)(Arg *) = floating; 1.6 1.7 +static void 1.8 +center(Client *c) 1.9 +{ 1.10 + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); 1.11 +} 1.12 + 1.13 static Client * 1.14 next(Client *c) 1.15 { 1.16 - for(c = c->next; c && !c->tags[tsel]; c = c->next); 1.17 + for(; c && !c->tags[tsel]; c = c->next); 1.18 return c; 1.19 } 1.20 1.21 -static Client * 1.22 -prev(Client *c) 1.23 +void 1.24 +zoom(Arg *arg) 1.25 { 1.26 - for(c = c->prev; c && !c->tags[tsel]; c = c->prev); 1.27 - return c; 1.28 + Client **l; 1.29 + 1.30 + if(!sel) 1.31 + return; 1.32 + 1.33 + for(l = &clients; *l && *l != sel; l = &(*l)->next); 1.34 + *l = sel->next; 1.35 + 1.36 + sel->next = clients; /* pop */ 1.37 + clients = sel; 1.38 + arrange(NULL); 1.39 + center(sel); 1.40 + focus(sel); 1.41 } 1.42 1.43 void 1.44 max(Arg *arg) 1.45 { 1.46 - if(!csel) 1.47 + if(!sel) 1.48 return; 1.49 - csel->x = sx; 1.50 - csel->y = sy; 1.51 - csel->w = sw - 2 * csel->border; 1.52 - csel->h = sh - 2 * csel->border; 1.53 - craise(csel); 1.54 - resize(csel); 1.55 + sel->x = sx; 1.56 + sel->y = sy; 1.57 + sel->w = sw - 2 * sel->border; 1.58 + sel->h = sh - 2 * sel->border; 1.59 + craise(sel); 1.60 + resize(sel); 1.61 discard_events(EnterWindowMask); 1.62 } 1.63 1.64 void 1.65 +view(Arg *arg) 1.66 +{ 1.67 + tsel = arg->i; 1.68 + arrange(NULL); 1.69 +} 1.70 + 1.71 +void 1.72 tag(Arg *arg) 1.73 { 1.74 - if(!csel) 1.75 + int i, n; 1.76 + if(!sel) 1.77 return; 1.78 1.79 - if(arg->i == tsel) 1.80 - return; 1.81 + if(arg->i == tsel) { 1.82 + for(n = i = 0; i < TLast; i++) 1.83 + if(sel->tags[i]) 1.84 + n++; 1.85 + if(n < 2) 1.86 + return; 1.87 + } 1.88 1.89 - if(csel->tags[arg->i]) 1.90 - csel->tags[arg->i] = NULL; /* toggle tag */ 1.91 + if(sel->tags[arg->i]) 1.92 + sel->tags[arg->i] = NULL; /* toggle tag */ 1.93 else 1.94 - csel->tags[arg->i] = tags[arg->i]; 1.95 + sel->tags[arg->i] = tags[arg->i]; 1.96 arrange(NULL); 1.97 } 1.98 1.99 +static void 1.100 +ban_client(Client *c) 1.101 +{ 1.102 + XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); 1.103 + XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); 1.104 +} 1.105 + 1.106 void 1.107 floating(Arg *arg) 1.108 { 1.109 Client *c; 1.110 1.111 arrange = floating; 1.112 - if(!csel) 1.113 - return; 1.114 - for(c = csel; c; c = next(c)) 1.115 - resize(c); 1.116 + for(c = clients; c; c = c->next) { 1.117 + if(c->tags[tsel]) 1.118 + resize(c); 1.119 + else 1.120 + ban_client(c); 1.121 + } 1.122 + if(sel && !sel->tags[tsel]) { 1.123 + if((sel = next(clients))) { 1.124 + craise(sel); 1.125 + focus(sel); 1.126 + } 1.127 + } 1.128 discard_events(EnterWindowMask); 1.129 } 1.130 1.131 @@ -78,31 +123,43 @@ 1.132 float rt, fd; 1.133 1.134 arrange = tiling; 1.135 - if(!csel) 1.136 - return; 1.137 - for(n = 0, c = csel; c; c = next(c), n++); 1.138 - rt = sqrt(n); 1.139 - if(modff(rt, &fd) < 0.5) 1.140 - rows = floor(rt); 1.141 + for(n = 0, c = clients; c; c = next(c->next), n++); 1.142 + if(n) { 1.143 + rt = sqrt(n); 1.144 + if(modff(rt, &fd) < 0.5) 1.145 + rows = floor(rt); 1.146 + else 1.147 + rows = ceil(rt); 1.148 + if(rows * rows < n) 1.149 + cols = rows + 1; 1.150 + else 1.151 + cols = rows; 1.152 + 1.153 + gw = (sw - 2) / cols; 1.154 + gh = (sh - 2) / rows; 1.155 + } 1.156 else 1.157 - rows = ceil(rt); 1.158 - if(rows * rows < n) 1.159 - cols = rows + 1; 1.160 - else 1.161 - cols = rows; 1.162 + cols = rows = gw = gh = 0; 1.163 1.164 - gw = (sw - 2) / cols; 1.165 - gh = (sh - 2) / rows; 1.166 - 1.167 - for(i = j = 0, c = csel; c; c = next(c)) { 1.168 - c->x = i * gw; 1.169 - c->y = j * gh; 1.170 - c->w = gw; 1.171 - c->h = gh; 1.172 - resize(c); 1.173 - if(++i == cols) { 1.174 - j++; 1.175 - i = 0; 1.176 + for(i = j = 0, c = clients; c; c = c->next) { 1.177 + if(c->tags[tsel]) { 1.178 + c->x = i * gw; 1.179 + c->y = j * gh; 1.180 + c->w = gw; 1.181 + c->h = gh; 1.182 + resize(c); 1.183 + if(++i == cols) { 1.184 + j++; 1.185 + i = 0; 1.186 + } 1.187 + } 1.188 + else 1.189 + ban_client(c); 1.190 + } 1.191 + if(sel && !sel->tags[tsel]) { 1.192 + if((sel = next(clients))) { 1.193 + craise(sel); 1.194 + focus(sel); 1.195 } 1.196 } 1.197 discard_events(EnterWindowMask); 1.198 @@ -113,14 +170,12 @@ 1.199 { 1.200 Client *c; 1.201 1.202 - if(!csel) 1.203 + if(!sel) 1.204 return; 1.205 1.206 - if(!(c = prev(csel))) 1.207 - c = prev(cend); 1.208 - if(c) { 1.209 + if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { 1.210 craise(c); 1.211 - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); 1.212 + center(c); 1.213 focus(c); 1.214 } 1.215 } 1.216 @@ -130,15 +185,15 @@ 1.217 { 1.218 Client *c; 1.219 1.220 - if(!csel) 1.221 + if(!sel) 1.222 return; 1.223 1.224 - if(!(c = next(csel))) 1.225 - c = next(cstart); 1.226 - 1.227 + if(!(c = next(sel->next))) 1.228 + c = next(clients); 1.229 if(c) { 1.230 craise(c); 1.231 - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); 1.232 + center(c); 1.233 + c->revert = sel; 1.234 focus(c); 1.235 } 1.236 } 1.237 @@ -146,14 +201,12 @@ 1.238 void 1.239 ckill(Arg *arg) 1.240 { 1.241 - Client *c = csel; 1.242 - 1.243 - if(!c) 1.244 + if(!sel) 1.245 return; 1.246 - if(c->proto & WM_PROTOCOL_DELWIN) 1.247 - send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]); 1.248 + if(sel->proto & WM_PROTOCOL_DELWIN) 1.249 + send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); 1.250 else 1.251 - XKillClient(dpy, c->win); 1.252 + XKillClient(dpy, sel->win); 1.253 } 1.254 1.255 static void 1.256 @@ -256,12 +309,12 @@ 1.257 void 1.258 focus(Client *c) 1.259 { 1.260 - if(csel && csel != c) { 1.261 - XSetWindowBorder(dpy, csel->win, dc.bg); 1.262 - XMapWindow(dpy, csel->title); 1.263 - draw_client(csel); 1.264 + if(sel && sel != c) { 1.265 + XSetWindowBorder(dpy, sel->win, dc.bg); 1.266 + XMapWindow(dpy, sel->title); 1.267 + draw_client(sel); 1.268 } 1.269 - csel = c; 1.270 + sel = c; 1.271 XUnmapWindow(dpy, c->title); 1.272 XSetWindowBorder(dpy, c->win, dc.fg); 1.273 draw_client(c); 1.274 @@ -273,7 +326,7 @@ 1.275 void 1.276 manage(Window w, XWindowAttributes *wa) 1.277 { 1.278 - Client *c; 1.279 + Client *c, **l; 1.280 XSetWindowAttributes twa; 1.281 1.282 c = emallocz(sizeof(Client)); 1.283 @@ -284,6 +337,7 @@ 1.284 c->h = wa->height; 1.285 c->th = th; 1.286 c->border = 1; 1.287 + c->proto = win_proto(c->win); 1.288 update_size(c); 1.289 XSelectInput(dpy, c->win, 1.290 StructureNotifyMask | PropertyChangeMask | EnterWindowMask); 1.291 @@ -300,13 +354,9 @@ 1.292 1.293 update_name(c); 1.294 1.295 - if(!cstart) 1.296 - cstart = cend = c; 1.297 - else { 1.298 - cend->next = c; 1.299 - c->prev = cend; 1.300 - cend = c; 1.301 - } 1.302 + for(l = &clients; *l; l = &(*l)->next); 1.303 + c->next = *l; /* *l == nil */ 1.304 + *l = c; 1.305 1.306 XSetWindowBorderWidth(dpy, c->win, 1); 1.307 XMapRaised(dpy, c->win); 1.308 @@ -318,7 +368,7 @@ 1.309 XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, 1.310 GrabModeAsync, GrabModeSync, None, None); 1.311 arrange(NULL); 1.312 - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); 1.313 + center(c); 1.314 focus(c); 1.315 } 1.316 1.317 @@ -420,26 +470,21 @@ 1.318 void 1.319 unmanage(Client *c) 1.320 { 1.321 + Client **l; 1.322 + 1.323 XGrabServer(dpy); 1.324 XSetErrorHandler(dummy_error_handler); 1.325 1.326 XUngrabButton(dpy, AnyButton, AnyModifier, c->win); 1.327 XDestroyWindow(dpy, c->title); 1.328 1.329 - if(c->prev) { 1.330 - c->prev->next = c->next; 1.331 - if(csel == c) 1.332 - csel = c->prev; 1.333 - } 1.334 - if(c->next) { 1.335 - c->next->prev = c->prev; 1.336 - if(csel == c) 1.337 - csel = c->next; 1.338 - } 1.339 - if(cstart == c) 1.340 - cstart = c->next; 1.341 - if(cend == c) 1.342 - cend = c->prev; 1.343 + for(l = &clients; *l && *l != c; l = &(*l)->next); 1.344 + *l = c->next; 1.345 + for(l = &clients; *l; l = &(*l)->next) 1.346 + if((*l)->revert == c) 1.347 + (*l)->revert = NULL; 1.348 + if(sel == c) 1.349 + sel = sel->revert ? sel->revert : clients; 1.350 1.351 free(c); 1.352 1.353 @@ -447,15 +492,15 @@ 1.354 XSetErrorHandler(error_handler); 1.355 XUngrabServer(dpy); 1.356 arrange(NULL); 1.357 - if(csel) 1.358 - focus(csel); 1.359 + if(sel) 1.360 + focus(sel); 1.361 } 1.362 1.363 Client * 1.364 gettitle(Window w) 1.365 { 1.366 Client *c; 1.367 - for(c = cstart; c; c = c->next) 1.368 + for(c = clients; c; c = c->next) 1.369 if(c->title == w) 1.370 return c; 1.371 return NULL; 1.372 @@ -465,7 +510,7 @@ 1.373 getclient(Window w) 1.374 { 1.375 Client *c; 1.376 - for(c = cstart; c; c = c->next) 1.377 + for(c = clients; c; c = c->next) 1.378 if(c->win == w) 1.379 return c; 1.380 return NULL; 1.381 @@ -475,7 +520,7 @@ 1.382 draw_client(Client *c) 1.383 { 1.384 int i; 1.385 - if(c == csel) 1.386 + if(c == sel) 1.387 return; 1.388 1.389 dc.x = dc.y = 0;
2.1 --- a/dev.c Thu Jul 13 17:09:35 2006 +0200 2.2 +++ b/dev.c Thu Jul 13 18:21:38 2006 +0200 2.3 @@ -20,19 +20,25 @@ 2.4 const char *xlock[] = { "xlock", NULL }; 2.5 2.6 static Key key[] = { 2.7 - { Mod1Mask, XK_Return, spawn, { .argv = term } }, 2.8 + { Mod1Mask, XK_Return, zoom, { 0 } }, 2.9 + { Mod1Mask, XK_t, spawn, { .argv = term } }, 2.10 { Mod1Mask, XK_w, spawn, { .argv = browse } }, 2.11 { Mod1Mask, XK_l, spawn, { .argv = xlock } }, 2.12 { Mod1Mask, XK_k, prevc, { 0 } }, 2.13 { Mod1Mask, XK_j, nextc, { 0 } }, 2.14 - { Mod1Mask, XK_t, tiling, { 0 } }, 2.15 - { Mod1Mask, XK_f, floating, { 0 } }, 2.16 { Mod1Mask, XK_m, max, { 0 } }, 2.17 - { Mod1Mask, XK_0, tag, { .i = Tscratch } }, 2.18 - { Mod1Mask, XK_1, tag, { .i = Tdev } }, 2.19 - { Mod1Mask, XK_2, tag, { .i = Tirc } }, 2.20 - { Mod1Mask, XK_3, tag, { .i = Twww } }, 2.21 - { Mod1Mask, XK_4, tag, { .i = Twork } }, 2.22 + { Mod1Mask, XK_0, view, { .i = Tscratch } }, 2.23 + { Mod1Mask, XK_1, view, { .i = Tdev } }, 2.24 + { Mod1Mask, XK_2, view, { .i = Tirc } }, 2.25 + { Mod1Mask, XK_3, view, { .i = Twww } }, 2.26 + { Mod1Mask, XK_4, view, { .i = Twork } }, 2.27 + { Mod1Mask, XK_space, tiling, { 0 } }, 2.28 + { Mod1Mask | ShiftMask, XK_space, floating, { 0 } }, 2.29 + { Mod1Mask | ShiftMask, XK_0, tag, { .i = Tscratch } }, 2.30 + { Mod1Mask | ShiftMask, XK_1, tag, { .i = Tdev } }, 2.31 + { Mod1Mask | ShiftMask, XK_2, tag, { .i = Tirc } }, 2.32 + { Mod1Mask | ShiftMask, XK_3, tag, { .i = Twww } }, 2.33 + { Mod1Mask | ShiftMask, XK_4, tag, { .i = Twork } }, 2.34 { Mod1Mask | ShiftMask, XK_c, ckill, { 0 } }, 2.35 { Mod1Mask | ShiftMask, XK_q, quit, { 0 } }, 2.36 };
3.1 --- a/dwm.h Thu Jul 13 17:09:35 2006 +0200 3.2 +++ b/dwm.h Thu Jul 13 18:21:38 2006 +0200 3.3 @@ -68,7 +68,7 @@ 3.4 Window trans; 3.5 Window title; 3.6 Client *next; 3.7 - Client *prev; 3.8 + Client *revert; 3.9 }; 3.10 3.11 struct Key { 3.12 @@ -89,7 +89,7 @@ 3.13 extern char stext[1024], *tags[TLast]; 3.14 3.15 extern DC dc; 3.16 -extern Client *cstart, *cend, *csel; 3.17 +extern Client *clients, *sel; 3.18 3.19 /* client.c */ 3.20 extern void manage(Window w, XWindowAttributes *wa); 3.21 @@ -109,7 +109,9 @@ 3.22 extern void max(Arg *arg); 3.23 extern void floating(Arg *arg); 3.24 extern void tiling(Arg *arg); 3.25 -void tag(Arg *arg); 3.26 +extern void tag(Arg *arg); 3.27 +extern void view(Arg *arg); 3.28 +extern void zoom(Arg *arg); 3.29 extern void gravitate(Client *c, Bool invert); 3.30 3.31 /* draw.c */
4.1 --- a/main.c Thu Jul 13 17:09:35 2006 +0200 4.2 +++ b/main.c Thu Jul 13 18:21:38 2006 +0200 4.3 @@ -38,9 +38,8 @@ 4.4 int screen, sx, sy, sw, sh, th; 4.5 4.6 DC dc = {0}; 4.7 -Client *cstart = NULL; 4.8 -Client *cend = NULL; 4.9 -Client *csel = NULL; 4.10 +Client *clients = NULL; 4.11 +Client *sel = NULL; 4.12 4.13 static Bool other_wm_running; 4.14 static const char version[] = 4.15 @@ -169,8 +168,10 @@ 4.16 static void 4.17 cleanup() 4.18 { 4.19 - while(csel) 4.20 - unmanage(csel); 4.21 + while(sel) { 4.22 + resize(sel); 4.23 + unmanage(sel); 4.24 + } 4.25 XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); 4.26 } 4.27