X-Git-Url: https://jasonwoof.com/gitweb/?p=dwm.git;a=blobdiff_plain;f=client.c;h=2403d749652f866cd942448910b0a9ece7352d1a;hp=46e6e83a27f62453debe601254dedc61bd9c91ac;hb=c47da143bdf5b4e3924a411f42648d4b3e86ff00;hpb=8b59083eb13c0712e04d9a5b6d7bf4af5913c442 diff --git a/client.c b/client.c index 46e6e83..2403d74 100644 --- a/client.c +++ b/client.c @@ -9,45 +9,78 @@ #include #include -#include "wm.h" +#include "dwm.h" -void (*arrange)(void *aux); +static void (*arrange)(Arg *) = floating; + +static Client * +next(Client *c) +{ + for(c = c->next; c && !c->tags[tsel]; c = c->next); + return c; +} + +static Client * +prev(Client *c) +{ + for(c = c->prev; c && !c->tags[tsel]; c = c->prev); + return c; +} void -max(void *aux) +max(Arg *arg) { - if(!stack) + if(!csel) return; - stack->x = sx; - stack->y = sy; - stack->w = sw - 2 * stack->border; - stack->h = sh - 2 * stack->border; - resize(stack); + csel->x = sx; + csel->y = sy; + csel->w = sw - 2 * csel->border; + csel->h = sh - 2 * csel->border; + craise(csel); + resize(csel); discard_events(EnterWindowMask); } void -floating(void *aux) +tag(Arg *arg) +{ + if(!csel) + return; + + if(arg->i == tsel) + return; + + if(csel->tags[arg->i]) + csel->tags[arg->i] = NULL; /* toggle tag */ + else + csel->tags[arg->i] = tags[arg->i]; + arrange(NULL); +} + +void +floating(Arg *arg) { Client *c; arrange = floating; - for(c = stack; c; c = c->snext) + if(!csel) + return; + for(c = csel; c; c = next(c)) resize(c); discard_events(EnterWindowMask); } void -grid(void *aux) +tiling(Arg *arg) { Client *c; int n, cols, rows, gw, gh, i, j; float rt, fd; - arrange = grid; - if(!clients) + arrange = tiling; + if(!csel) return; - for(n = 0, c = clients; c; c = c->next, n++); + for(n = 0, c = csel; c; c = next(c), n++); rt = sqrt(n); if(modff(rt, &fd) < 0.5) rows = floor(rt); @@ -61,7 +94,7 @@ grid(void *aux) gw = (sw - 2) / cols; gh = (sh - 2) / rows; - for(i = j = 0, c = clients; c; c = c->next) { + for(i = j = 0, c = csel; c; c = next(c)) { c->x = i * gw; c->y = j * gh; c->w = gw; @@ -76,27 +109,44 @@ grid(void *aux) } void -sel(void *aux) +prevc(Arg *arg) { - const char *arg = aux; - Client *c = NULL; + Client *c; - if(!arg || !stack) + if(!csel) return; - if(!strncmp(arg, "next", 5)) - c = stack->snext ? stack->snext : stack; - else if(!strncmp(arg, "prev", 5)) - for(c = stack; c && c->snext; c = c->snext); - if(!c) - c = stack; - craise(c); - focus(c); + + if(!(c = prev(csel))) + c = prev(cend); + if(c) { + craise(c); + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); + focus(c); + } } void -ckill(void *aux) +nextc(Arg *arg) { - Client *c = stack; + Client *c; + + if(!csel) + return; + + if(!(c = next(csel))) + c = next(cstart); + + if(c) { + craise(c); + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); + focus(c); + } +} + +void +ckill(Arg *arg) +{ + Client *c = csel; if(!c) return; @@ -114,8 +164,8 @@ resize_title(Client *c) c->tw = 0; for(i = 0; i < TLast; i++) if(c->tags[i]) - c->tw += textw(&brush.font, c->tags[i]) + brush.font.height; - c->tw += textw(&brush.font, c->name) + brush.font.height; + c->tw += textw(c->tags[i]) + dc.font.height; + c->tw += textw(c->name) + dc.font.height; if(c->tw > c->w) c->tw = c->w + 2; c->tx = c->x + c->w - c->tw + 2; @@ -206,28 +256,24 @@ lower(Client *c) void focus(Client *c) { - Client **l, *old; - - old = stack; - for(l = &stack; *l && *l != c; l = &(*l)->snext); - if(*l) - *l = c->snext; - c->snext = stack; - stack = c; - if(old && old != c) { - XMapWindow(dpy, old->title); - draw_client(old); + if(csel && csel != c) { + XSetWindowBorder(dpy, csel->win, dc.bg); + XMapWindow(dpy, csel->title); + draw_client(csel); } + csel = c; XUnmapWindow(dpy, c->title); + XSetWindowBorder(dpy, c->win, dc.fg); draw_client(c); XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); XFlush(dpy); + discard_events(EnterWindowMask); } void manage(Window w, XWindowAttributes *wa) { - Client *c, **l; + Client *c; XSetWindowAttributes twa; c = emallocz(sizeof(Client)); @@ -239,8 +285,6 @@ manage(Window w, XWindowAttributes *wa) c->th = th; c->border = 1; update_size(c); - XSetWindowBorderWidth(dpy, c->win, 1); - XSetWindowBorder(dpy, c->win, brush.border); XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | EnterWindowMask); XGetTransientForHint(dpy, c->win, &c->trans); @@ -255,9 +299,16 @@ manage(Window w, XWindowAttributes *wa) CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); update_name(c); - for(l=&clients; *l; l=&(*l)->next); - c->next = *l; /* *l == nil */ - *l = c; + + if(!cstart) + cstart = cend = c; + else { + cend->next = c; + c->prev = cend; + cend = c; + } + + XSetWindowBorderWidth(dpy, c->win, 1); XMapRaised(dpy, c->win); XMapRaised(dpy, c->title); XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask, @@ -267,6 +318,7 @@ manage(Window w, XWindowAttributes *wa) XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, GrabModeAsync, GrabModeSync, None, None); arrange(NULL); + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); focus(c); } @@ -360,7 +412,7 @@ resize(Client *c) } static int -dummy_error_handler(Display *dpy, XErrorEvent *error) +dummy_error_handler(Display *dsply, XErrorEvent *err) { return 0; } @@ -368,33 +420,42 @@ dummy_error_handler(Display *dpy, XErrorEvent *error) void unmanage(Client *c) { - Client **l; - XGrabServer(dpy); XSetErrorHandler(dummy_error_handler); XUngrabButton(dpy, AnyButton, AnyModifier, c->win); XDestroyWindow(dpy, c->title); - for(l=&clients; *l && *l != c; l=&(*l)->next); - *l = c->next; - for(l=&stack; *l && *l != c; l=&(*l)->snext); - *l = c->snext; + if(c->prev) { + c->prev->next = c->next; + if(csel == c) + csel = c->prev; + } + if(c->next) { + c->next->prev = c->prev; + if(csel == c) + csel = c->next; + } + if(cstart == c) + cstart = c->next; + if(cend == c) + cend = c->prev; + free(c); XFlush(dpy); XSetErrorHandler(error_handler); XUngrabServer(dpy); arrange(NULL); - if(stack) - focus(stack); + if(csel) + focus(csel); } Client * gettitle(Window w) { Client *c; - for(c = clients; c; c = c->next) + for(c = cstart; c; c = c->next) if(c->title == w) return c; return NULL; @@ -404,7 +465,7 @@ Client * getclient(Window w) { Client *c; - for(c = clients; c; c = c->next) + for(c = cstart; c; c = c->next) if(c->win == w) return c; return NULL; @@ -414,24 +475,24 @@ void draw_client(Client *c) { int i; - if(c == stack) + if(c == csel) return; - brush.x = brush.y = 0; - brush.h = c->th; + dc.x = dc.y = 0; + dc.h = c->th; - brush.w = 0; + dc.w = 0; for(i = 0; i < TLast; i++) { if(c->tags[i]) { - brush.x += brush.w; - brush.w = textw(&brush.font, c->tags[i]) + brush.font.height; - draw(dpy, &brush, True, c->tags[i]); + dc.x += dc.w; + dc.w = textw(c->tags[i]) + dc.font.height; + draw(True, c->tags[i]); } } - brush.x += brush.w; - brush.w = textw(&brush.font, c->name) + brush.font.height; - draw(dpy, &brush, True, c->name); - XCopyArea(dpy, brush.drawable, c->title, brush.gc, + dc.x += dc.w; + dc.w = textw(c->name) + dc.font.height; + draw(True, c->name); + XCopyArea(dpy, dc.drawable, c->title, dc.gc, 0, 0, c->tw, c->th, 0, 0); XFlush(dpy); }