X-Git-Url: https://jasonwoof.com/gitweb/?p=dwm.git;a=blobdiff_plain;f=client.c;h=2403d749652f866cd942448910b0a9ece7352d1a;hp=679e2be46b1a4783284aed7b5df7358745f47326;hb=c47da143bdf5b4e3924a411f42648d4b3e86ff00;hpb=650a1fb4e1a798aca48a53739f5bb2649191bc1c diff --git a/client.c b/client.c index 679e2be..2403d74 100644 --- a/client.c +++ b/client.c @@ -9,45 +9,78 @@ #include #include -#include "wm.h" +#include "dwm.h" -static void floating(void); -static void tiling(void); -static void (*arrange)(void) = tiling; +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); } -static void -floating(void) +void +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; - for(c = stack; c; c = c->snext) + arrange = floating; + if(!csel) + return; + for(c = csel; c; c = next(c)) resize(c); discard_events(EnterWindowMask); } -static void -tiling(void) +void +tiling(Arg *arg) { Client *c; int n, cols, rows, gw, gh, i, j; float rt, fd; - 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 @@ tiling(void) 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,38 +109,44 @@ tiling(void) } void -toggle(void *aux) +prevc(Arg *arg) { - if(arrange == floating) - arrange = tiling; - else - arrange = floating; - arrange(); -} + Client *c; + if(!csel) + return; + + 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 -sel(void *aux) +nextc(Arg *arg) { - const char *arg = aux; - Client *c = NULL; - - if(!arg || !stack) + Client *c; + + 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 = 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(void *aux) +ckill(Arg *arg) { - Client *c = stack; + Client *c = csel; if(!c) return; @@ -125,8 +164,8 @@ resize_title(Client *c) c->tw = 0; for(i = 0; i < TLast; i++) if(c->tags[i]) - c->tw += textw(&dc.font, c->tags[i]) + dc.font.height; - c->tw += textw(&dc.font, c->name) + dc.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; @@ -217,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)); @@ -250,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, dc.border); XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | EnterWindowMask); XGetTransientForHint(dpy, c->win, &c->trans); @@ -266,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, @@ -277,7 +317,8 @@ manage(Window w, XWindowAttributes *wa) GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, GrabModeAsync, GrabModeSync, None, None); - arrange(); + arrange(NULL); + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); focus(c); } @@ -379,33 +420,42 @@ dummy_error_handler(Display *dsply, XErrorEvent *err) 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(); - if(stack) - focus(stack); + arrange(NULL); + 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; @@ -415,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; @@ -425,7 +475,7 @@ void draw_client(Client *c) { int i; - if(c == stack) + if(c == csel) return; dc.x = dc.y = 0; @@ -435,12 +485,12 @@ draw_client(Client *c) for(i = 0; i < TLast; i++) { if(c->tags[i]) { dc.x += dc.w; - dc.w = textw(&dc.font, c->tags[i]) + dc.font.height; + dc.w = textw(c->tags[i]) + dc.font.height; draw(True, c->tags[i]); } } dc.x += dc.w; - dc.w = textw(&dc.font, c->name) + dc.font.height; + 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);