X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=client.c;h=158b92833158df13de27ef9d287976fd919ed3a5;hb=e6cbe9c11e88537d74eb094ba5844f71ee57f268;hp=7bb8459042a1447a385793cdff289b404765b89b;hpb=c0705eeb65733e8c5091e47d5bdc701a0779a949;p=dwm.git diff --git a/client.c b/client.c index 7bb8459..158b928 100644 --- a/client.c +++ b/client.c @@ -2,36 +2,17 @@ * (C)opyright MMVI Anselm R. Garbe * See LICENSE file for license details. */ +#include "dwm.h" #include -#include #include #include #include -#include "dwm.h" - -static Rule rule[] = { - /* class instance tags floating */ - { "Firefox-bin", "Gecko", { [Twww] = "www" }, False }, -}; - -Client * -getnext(Client *c) -{ - for(; c && !c->tags[tsel]; c = c->next); - return c; -} - -void -ban(Client *c) -{ - XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); - XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); -} +/* static functions */ static void -resize_title(Client *c) +resizetitle(Client *c) { int i; @@ -47,84 +28,19 @@ resize_title(Client *c) XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th); } -void -settitle(Client *c) -{ - XTextProperty name; - int n; - char **list = NULL; - - name.nitems = 0; - c->name[0] = 0; - XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]); - if(!name.nitems) - XGetWMName(dpy, c->win, &name); - if(!name.nitems) - return; - if(name.encoding == XA_STRING) - strncpy(c->name, (char *)name.value, sizeof(c->name)); - else { - if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success - && n > 0 && *list) - { - strncpy(c->name, *list, sizeof(c->name)); - XFreeStringList(list); - } - } - XFree(name.value); - resize_title(c); -} - -void -setsize(Client *c) +static int +xerrordummy(Display *dsply, XErrorEvent *ee) { - XSizeHints size; - long msize; - if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags) - size.flags = PSize; - c->flags = size.flags; - if(c->flags & PBaseSize) { - c->basew = size.base_width; - c->baseh = size.base_height; - } - else - c->basew = c->baseh = 0; - if(c->flags & PResizeInc) { - c->incw = size.width_inc; - c->inch = size.height_inc; - } - else - c->incw = c->inch = 0; - if(c->flags & PMaxSize) { - c->maxw = size.max_width; - c->maxh = size.max_height; - } - else - c->maxw = c->maxh = 0; - if(c->flags & PMinSize) { - c->minw = size.min_width; - c->minh = size.min_height; - } - else - c->minw = c->minh = 0; - if(c->flags & PWinGravity) - c->grav = size.win_gravity; - else - c->grav = NorthWestGravity; + return 0; } -void -higher(Client *c) -{ - XRaiseWindow(dpy, c->win); - XRaiseWindow(dpy, c->title); -} +/* extern functions */ void -lower(Client *c) +ban(Client *c) { - XLowerWindow(dpy, c->title); - XLowerWindow(dpy, c->win); + XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); + XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); } void @@ -133,50 +49,144 @@ focus(Client *c) Client *old = sel; XEvent ev; - XFlush(dpy); sel = c; if(old && old != c) drawtitle(old); drawtitle(c); XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); - XFlush(dpy); + XSync(dpy, False); while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); } -static void -init_tags(Client *c) +void +focusnext(Arg *arg) { - XClassHint ch; - static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; - unsigned int i, j; - Bool matched = False; + Client *c; + + if(!sel) + return; - if(!len) { - c->tags[tsel] = tags[tsel]; + if(!(c = getnext(sel->next))) + c = getnext(clients); + if(c) { + higher(c); + c->revert = sel; + focus(c); + } +} + +void +focusprev(Arg *arg) +{ + Client *c; + + if(!sel) return; + + if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { + higher(c); + focus(c); } +} - if(XGetClassHint(dpy, c->win, &ch)) { - if(ch.res_class && ch.res_name) { - for(i = 0; i < len; i++) - if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class)) - && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) - { - for(j = 0; j < TLast; j++) - c->tags[j] = rule[i].tags[j]; - c->floating = rule[i].floating; - matched = True; - break; - } - } - if(ch.res_class) - XFree(ch.res_class); - if(ch.res_name) - XFree(ch.res_name); +Client * +getclient(Window w) +{ + Client *c; + for(c = clients; c; c = c->next) + if(c->win == w) + return c; + return NULL; +} + +Client * +getctitle(Window w) +{ + Client *c; + for(c = clients; c; c = c->next) + if(c->title == w) + return c; + return NULL; +} + +void +gravitate(Client *c, Bool invert) +{ + int dx = 0, dy = 0; + + switch(c->grav) { + case StaticGravity: + case NorthWestGravity: + case NorthGravity: + case NorthEastGravity: + dy = c->border; + break; + case EastGravity: + case CenterGravity: + case WestGravity: + dy = -(c->h / 2) + c->border; + break; + case SouthEastGravity: + case SouthGravity: + case SouthWestGravity: + dy = -c->h; + break; + default: + break; } - if(!matched) - c->tags[tsel] = tags[tsel]; + switch (c->grav) { + case StaticGravity: + case NorthWestGravity: + case WestGravity: + case SouthWestGravity: + dx = c->border; + break; + case NorthGravity: + case CenterGravity: + case SouthGravity: + dx = -(c->w / 2) + c->border; + break; + case NorthEastGravity: + case EastGravity: + case SouthEastGravity: + dx = -(c->w + c->border); + break; + default: + break; + } + + if(invert) { + dx = -dx; + dy = -dy; + } + c->x += dx; + c->y += dy; +} + +void +higher(Client *c) +{ + XRaiseWindow(dpy, c->win); + XRaiseWindow(dpy, c->title); +} + +void +killclient(Arg *arg) +{ + if(!sel) + return; + if(sel->proto & WM_PROTOCOL_DELWIN) + sendevent(sel->win, wmatom[WMProtocols], wmatom[WMDelete]); + else + XKillClient(dpy, sel->win); +} + +void +lower(Client *c) +{ + XLowerWindow(dpy, c->title); + XLowerWindow(dpy, c->win); } void @@ -196,7 +206,7 @@ manage(Window w, XWindowAttributes *wa) c->h = wa->height; c->th = bh; c->border = 1; - c->proto = proto(c->win); + c->proto = getproto(c->win); setsize(c); XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | EnterWindowMask); @@ -211,7 +221,7 @@ manage(Window w, XWindowAttributes *wa) CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); settitle(c); - init_tags(c); + settags(c); for(l = &clients; *l; l = &(*l)->next); c->next = *l; /* *l == nil */ @@ -224,8 +234,8 @@ manage(Window w, XWindowAttributes *wa) XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, GrabModeAsync, GrabModeSync, None, None); - if(!c->floating) - c->floating = trans + if(!c->dofloat) + c->dofloat = trans || ((c->maxw == c->minw) && (c->maxh == c->minh)); arrange(NULL); @@ -243,61 +253,18 @@ manage(Window w, XWindowAttributes *wa) } void -gravitate(Client *c, Bool invert) +maximize(Arg *arg) { - int dx = 0, dy = 0; - - switch(c->grav) { - case StaticGravity: - case NorthWestGravity: - case NorthGravity: - case NorthEastGravity: - dy = c->border; - break; - case EastGravity: - case CenterGravity: - case WestGravity: - dy = -(c->h / 2) + c->border; - break; - case SouthEastGravity: - case SouthGravity: - case SouthWestGravity: - dy = -c->h; - break; - default: - break; - } - - switch (c->grav) { - case StaticGravity: - case NorthWestGravity: - case WestGravity: - case SouthWestGravity: - dx = c->border; - break; - case NorthGravity: - case CenterGravity: - case SouthGravity: - dx = -(c->w / 2) + c->border; - break; - case NorthEastGravity: - case EastGravity: - case SouthEastGravity: - dx = -(c->w + c->border); - break; - default: - break; - } - - if(invert) { - dx = -dx; - dy = -dy; - } - c->x += dx; - c->y += dy; + if(!sel) + return; + sel->x = sx; + sel->y = sy + bh; + sel->w = sw - 2 * sel->border; + sel->h = sh - 2 * sel->border - bh; + higher(sel); + resize(sel, False); } - void resize(Client *c, Bool inc) { @@ -321,7 +288,7 @@ resize(Client *c, Bool inc) c->w = c->maxw; if(c->maxh && c->h > c->maxh) c->h = c->maxh; - resize_title(c); + resizetitle(c); XSetWindowBorderWidth(dpy, c->win, 1); XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); e.type = ConfigureNotify; @@ -335,13 +302,73 @@ resize(Client *c, Bool inc) e.above = None; e.override_redirect = False; XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e); - XFlush(dpy); + XSync(dpy, False); } -static int -dummy_xerror(Display *dsply, XErrorEvent *err) +void +setsize(Client *c) { - return 0; + XSizeHints size; + long msize; + if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags) + size.flags = PSize; + c->flags = size.flags; + if(c->flags & PBaseSize) { + c->basew = size.base_width; + c->baseh = size.base_height; + } + else + c->basew = c->baseh = 0; + if(c->flags & PResizeInc) { + c->incw = size.width_inc; + c->inch = size.height_inc; + } + else + c->incw = c->inch = 0; + if(c->flags & PMaxSize) { + c->maxw = size.max_width; + c->maxh = size.max_height; + } + else + c->maxw = c->maxh = 0; + if(c->flags & PMinSize) { + c->minw = size.min_width; + c->minh = size.min_height; + } + else + c->minw = c->minh = 0; + if(c->flags & PWinGravity) + c->grav = size.win_gravity; + else + c->grav = NorthWestGravity; +} + +void +settitle(Client *c) +{ + XTextProperty name; + int n; + char **list = NULL; + + name.nitems = 0; + c->name[0] = 0; + XGetTextProperty(dpy, c->win, &name, netatom[NetWMName]); + if(!name.nitems) + XGetWMName(dpy, c->win, &name); + if(!name.nitems) + return; + if(name.encoding == XA_STRING) + strncpy(c->name, (char *)name.value, sizeof(c->name)); + else { + if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success + && n > 0 && *list) + { + strncpy(c->name, *list, sizeof(c->name)); + XFreeStringList(list); + } + } + XFree(name.value); + resizetitle(c); } void @@ -350,7 +377,7 @@ unmanage(Client *c) Client **l; XGrabServer(dpy); - XSetErrorHandler(dummy_xerror); + XSetErrorHandler(xerrordummy); XUngrabButton(dpy, AnyButton, AnyModifier, c->win); XDestroyWindow(dpy, c->title); @@ -365,7 +392,7 @@ unmanage(Client *c) free(c); - XFlush(dpy); + XSync(dpy, False); XSetErrorHandler(xerror); XUngrabServer(dpy); arrange(NULL); @@ -373,22 +400,24 @@ unmanage(Client *c) focus(sel); } -Client * -gettitle(Window w) +void +zoom(Arg *arg) { - Client *c; - for(c = clients; c; c = c->next) - if(c->title == w) - return c; - return NULL; -} + Client **l, *c; -Client * -getclient(Window w) -{ - Client *c; - for(c = clients; c; c = c->next) - if(c->win == w) - return c; - return NULL; + if(!sel) + return; + + if(sel == getnext(clients) && sel->next) { + if((c = getnext(sel->next))) + sel = c; + } + + for(l = &clients; *l && *l != sel; l = &(*l)->next); + *l = sel->next; + + sel->next = clients; /* pop */ + clients = sel; + arrange(NULL); + focus(sel); }