+ if(sel && sel->ismax)
+ togglemax(NULL);
+ sel = c;
+ if(old && old != c)
+ drawtitle(old);
+ drawtitle(c);
+ XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
+}
+
+void
+focusnext(Arg *arg)
+{
+ Client *c;
+
+ if(!sel)
+ return;
+
+ if(!(c = getnext(sel->next)))
+ c = getnext(clients);
+ if(c) {
+ focus(c);
+ restack();
+ }
+}
+
+void
+focusprev(Arg *arg)
+{
+ Client *c;
+
+ if(!sel)
+ return;
+
+ if(!(c = getprev(sel->prev))) {
+ for(c = clients; c && c->next; c = c->next);
+ c = getprev(c);
+ }
+ if(c) {
+ focus(c);
+ restack();
+ }
+}
+
+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) {
+ default:
+ break;
+ 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;
+ }
+
+ switch (c->grav) {
+ default:
+ break;
+ 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;
+ }
+
+ if(invert) {
+ dx = -dx;
+ dy = -dy;
+ }
+ c->x += dx;
+ c->y += dy;
+}
+
+void
+killclient(Arg *arg)
+{
+ if(!sel)
+ return;
+ if(sel->proto & PROTODELWIN)
+ sendevent(sel->win, wmatom[WMProtocols], wmatom[WMDelete]);
+ else
+ XKillClient(dpy, sel->win);
+}
+
+void
+manage(Window w, XWindowAttributes *wa)
+{
+ Client *c, *tc;
+ Window trans;
+ XSetWindowAttributes twa;
+
+ c = emallocz(sizeof(Client));
+ c->tags = emallocz(ntags * sizeof(Bool));
+ c->win = w;
+ c->x = c->tx = wa->x;
+ c->y = c->ty = wa->y;
+ c->w = c->tw = wa->width;
+ c->h = wa->height;
+ c->th = bh;
+
+ c->border = 0;
+ setsize(c);
+
+ if(c->h != sh && c->y < bh)
+ c->y = c->ty = bh;
+
+ c->proto = getproto(c->win);
+ XSelectInput(dpy, c->win,
+ StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
+ XGetTransientForHint(dpy, c->win, &trans);
+ twa.override_redirect = 1;
+ twa.background_pixmap = ParentRelative;
+ twa.event_mask = ExposureMask | EnterWindowMask;
+
+ c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
+ 0, DefaultDepth(dpy, screen), CopyFromParent,
+ DefaultVisual(dpy, screen),
+ CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
+
+ if(clients)
+ clients->prev = c;
+ c->next = clients;
+ clients = c;
+
+ XGrabButton(dpy, Button1, MODKEY, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+ XGrabButton(dpy, Button1, MODKEY | LockMask, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+ XGrabButton(dpy, Button1, MODKEY | numlockmask, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+ XGrabButton(dpy, Button1, MODKEY | numlockmask | LockMask, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+
+ XGrabButton(dpy, Button2, MODKEY, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+ XGrabButton(dpy, Button2, MODKEY | LockMask, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+ XGrabButton(dpy, Button2, MODKEY | numlockmask, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+ XGrabButton(dpy, Button2, MODKEY | numlockmask | LockMask, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+
+ XGrabButton(dpy, Button3, MODKEY, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+ XGrabButton(dpy, Button3, MODKEY | LockMask, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+ XGrabButton(dpy, Button3, MODKEY | numlockmask, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+ XGrabButton(dpy, Button3, MODKEY | numlockmask | LockMask, c->win, False, BUTTONMASK,
+ GrabModeAsync, GrabModeSync, None, None);
+
+ settags(c);
+ if(!c->isfloat)
+ c->isfloat = trans
+ || (c->maxw && c->minw &&
+ c->maxw == c->minw && c->maxh == c->minh);
+ settitle(c);
+
+ if(trans && (tc = getclient(trans))) {
+ c->x = (tc->x + tc->w / 2) - (c->w / 2);
+ c->y = (tc->y + tc->h / 2) - (c->h / 2);
+ if(c->x < 0 || c->x >= sw)
+ c->x = (sw / 2) - (c->w / 2);
+ if(c->y < 0 || c->y >= sh)
+ c->y = ((sh - bh) / 2) - (c->h / 2) + bh;
+ }