X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=client.c;h=3505e76619eb698cd33d439d6310d98725e56113;hb=3ce8c9f33844a995e79329978db9d2cd3981e032;hp=badb8754750ed8a89e3f8b6ff9286e3d365e742c;hpb=a5cb80b86cdedb8cd1f3a02de47f204bd174f649;p=dwm.git diff --git a/client.c b/client.c index badb875..3505e76 100644 --- a/client.c +++ b/client.c @@ -7,7 +7,7 @@ #include #include -/* static functions */ +/* static */ static void detachstack(Client *c) { @@ -65,23 +65,32 @@ xerrordummy(Display *dsply, XErrorEvent *ee) { return 0; } -/* extern functions */ +/* extern */ + +void +ban(Client *c) { + if(!c || c->isbanned) + return; + c->isbanned = True; + XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); +} void configure(Client *c) { - XEvent synev; + XConfigureEvent ce; - synev.type = ConfigureNotify; - synev.xconfigure.display = dpy; - synev.xconfigure.event = c->win; - synev.xconfigure.window = c->win; - synev.xconfigure.x = c->x; - synev.xconfigure.y = c->y; - synev.xconfigure.width = c->w; - synev.xconfigure.height = c->h; - synev.xconfigure.border_width = c->border; - synev.xconfigure.above = None; - XSendEvent(dpy, c->win, True, NoEventMask, &synev); + ce.type = ConfigureNotify; + ce.display = dpy; + ce.event = c->win; + ce.window = c->win; + ce.x = c->x; + ce.y = c->y; + ce.width = c->w; + ce.height = c->h; + ce.border_width = c->border; + ce.above = None; + ce.override_redirect = False; + XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce); } void @@ -120,11 +129,26 @@ getclient(Window w) { return NULL; } +Bool +isprotodel(Client *c) { + int i, n; + Atom *protocols; + Bool ret = False; + + if(XGetWMProtocols(dpy, c->win, &protocols, &n)) { + for(i = 0; !ret && i < n; i++) + if(protocols[i] == wmatom[WMDelete]) + ret = True; + XFree(protocols); + } + return ret; +} + void killclient(Arg *arg) { if(!sel) return; - if(sel->proto & PROTODELWIN) + if(isprotodel(sel)) sendevent(sel->win, wmatom[WMProtocols], wmatom[WMDelete]); else XKillClient(dpy, sel->win); @@ -132,7 +156,7 @@ killclient(Arg *arg) { void manage(Window w, XWindowAttributes *wa) { - Client *c; + Client *c, *t; Window trans; c = emallocz(sizeof(Client)); @@ -159,22 +183,22 @@ manage(Window w, XWindowAttributes *wa) { c->y = way; } updatesizehints(c); - c->proto = getproto(c->win); XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | EnterWindowMask); XGetTransientForHint(dpy, c->win, &trans); grabbuttons(c, False); XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); updatetitle(c); - settags(c, getclient(trans)); + t = getclient(trans); + settags(c, t); if(!c->isfloat) - c->isfloat = trans || c->isfixed; + c->isfloat = (t != 0) || c->isfixed; if(clients) clients->prev = c; c->next = clients; c->snext = stack; stack = clients = c; - XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); + ban(c); XMapWindow(dpy, c->win); setclientstate(c, NormalState); if(isvisible(c)) @@ -184,15 +208,12 @@ manage(Window w, XWindowAttributes *wa) { void resize(Client *c, Bool sizehints) { + float actual, dx, dy, max, min; XWindowChanges wc; if(c->w <= 0 || c->h <= 0) return; if(sizehints) { - if(c->incw) - c->w -= (c->w - c->basew) % c->incw; - if(c->inch) - c->h -= (c->h - c->baseh) % c->inch; if(c->minw && c->w < c->minw) c->w = c->minw; if(c->minh && c->h < c->minh) @@ -201,6 +222,32 @@ resize(Client *c, Bool sizehints) { c->w = c->maxw; if(c->maxh && c->h > c->maxh) c->h = c->maxh; + /* inspired by algorithm from fluxbox */ + if(c->minay > 0 && c->maxay && (c->h - c->baseh) > 0) { + dx = (float)(c->w - c->basew); + dy = (float)(c->h - c->baseh); + min = (float)(c->minax) / (float)(c->minay); + max = (float)(c->maxax) / (float)(c->maxay); + actual = dx / dy; + if(max > 0 && min > 0 && actual > 0) { + if(actual < min) { + dy = (dx * min + dy) / (min * min + 1); + dx = dy * min; + c->w = (int)dx + c->basew; + c->h = (int)dy + c->baseh; + } + else if(actual > max) { + dy = (dx * min + dy) / (max * max + 1); + dx = dy * min; + c->w = (int)dx + c->basew; + c->h = (int)dy + c->baseh; + } + } + } + if(c->incw) + c->w -= (c->w - c->basew) % c->incw; + if(c->inch) + c->h -= (c->h - c->baseh) % c->inch; } if(c->w == sw && c->h == sh) c->border = 0; @@ -257,8 +304,16 @@ updatesizehints(Client *c) { } else c->minw = c->minh = 0; - c->isfixed = (c->maxw && c->minw && c->maxh && c->minh && - c->maxw == c->minw && c->maxh == c->minh); + if(c->flags & PAspect) { + c->minax = size.min_aspect.x; + c->minay = size.min_aspect.y; + c->maxax = size.max_aspect.x; + c->maxay = size.max_aspect.y; + } + else + c->minax = c->minay = c->maxax = c->maxay = 0; + c->isfixed = (c->maxw && c->minw && c->maxh && c->minh + && c->maxw == c->minw && c->maxh == c->minh); } void @@ -278,7 +333,7 @@ updatetitle(Client *c) { strncpy(c->name, (char *)name.value, sizeof c->name); else { if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success - && n > 0 && *list) + && n > 0 && *list) { strncpy(c->name, *list, sizeof c->name); XFreeStringList(list);