- ev.xclient.data.l[1] = CurrentTime;
- XSendEvent(dpy, sel->win, False, NoEventMask, &ev);
- }
- else
- XKillClient(dpy, sel->win);
-}
-
-static void
-manage(Window w, XWindowAttributes *wa) {
- unsigned int i;
- Client *c, *t = NULL;
- Window trans;
- Status rettrans;
- XWindowChanges wc;
-
- c = emallocz(sizeof(Client));
- c->tags = emallocz(ntags * sizeof(Bool));
- c->win = w;
- c->x = wa->x;
- c->y = wa->y;
- c->w = wa->width;
- c->h = wa->height;
- c->oldborder = wa->border_width;
- if(c->w == sw && c->h == sh) {
- c->x = sx;
- c->y = sy;
- c->border = wa->border_width;
- }
- else {
- if(c->x + c->w + 2 * c->border > wax + waw)
- c->x = wax + waw - c->w - 2 * c->border;
- if(c->y + c->h + 2 * c->border > way + wah)
- c->y = way + wah - c->h - 2 * c->border;
- if(c->x < wax)
- c->x = wax;
- if(c->y < way)
- c->y = way;
- c->border = BORDERPX;
- }
- wc.border_width = c->border;
- XConfigureWindow(dpy, w, CWBorderWidth, &wc);
- XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
- configure(c); /* propagates border_width, if size doesn't change */
- updatesizehints(c);
- XSelectInput(dpy, w,
- StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
- grabbuttons(c, False);
- updatetitle(c);
- if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
- for(t = clients; t && t->win != trans; t = t->next);
- if(t)
- for(i = 0; i < ntags; i++)
- c->tags[i] = t->tags[i];
- applyrules(c);
- if(!c->isfloating)
- c->isfloating = (rettrans == Success) || c->isfixed;
- attach(c);
- attachstack(c);
- XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */
- ban(c);
- XMapWindow(dpy, c->win);
- setclientstate(c, NormalState);
- arrange();
-}
-
-static void
-resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
- double dx, dy, max, min, ratio;
- XWindowChanges wc;
-
- if(sizehints) {
- if(c->minay > 0 && c->maxay > 0 && (h - c->baseh) > 0 && (w - c->basew) > 0) {
- dx = (double)(w - c->basew);
- dy = (double)(h - c->baseh);
- min = (double)(c->minax) / (double)(c->minay);
- max = (double)(c->maxax) / (double)(c->maxay);
- ratio = dx / dy;
- if(max > 0 && min > 0 && ratio > 0) {
- if(ratio < min) {
- dy = (dx * min + dy) / (min * min + 1);
- dx = dy * min;
- w = (int)dx + c->basew;
- h = (int)dy + c->baseh;
- }
- else if(ratio > max) {
- dy = (dx * min + dy) / (max * max + 1);
- dx = dy * min;
- w = (int)dx + c->basew;
- h = (int)dy + c->baseh;
- }
- }
- }
- if(c->minw && w < c->minw)
- w = c->minw;
- if(c->minh && h < c->minh)
- h = c->minh;
- if(c->maxw && w > c->maxw)
- w = c->maxw;
- if(c->maxh && h > c->maxh)
- h = c->maxh;
- if(c->incw)
- w -= (w - c->basew) % c->incw;
- if(c->inch)
- h -= (h - c->baseh) % c->inch;
- }
- if(w <= 0 || h <= 0)
- return;
- /* offscreen appearance fixes */
- if(x > sw)
- x = sw - w - 2 * c->border;
- if(y > sh)
- y = sh - h - 2 * c->border;
- if(x + w + 2 * c->border < sx)
- x = sx;
- if(y + h + 2 * c->border < sy)
- y = sy;
- if(c->x != x || c->y != y || c->w != w || c->h != h) {
- c->x = wc.x = x;
- c->y = wc.y = y;
- c->w = wc.width = w;
- c->h = wc.height = h;
- wc.border_width = c->border;
- XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc);
- configure(c);
- XSync(dpy, False);
- }
-}
-
-static void
-unban(Client *c) {
- if(!c->isbanned)
- return;
- XMoveWindow(dpy, c->win, c->x, c->y);
- c->isbanned = False;
-}
-
-static void
-unmanage(Client *c) {
- XWindowChanges wc;
-
- wc.border_width = c->oldborder;
- /* The server grab construct avoids race conditions. */
- XGrabServer(dpy);
- XSetErrorHandler(xerrordummy);
- XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
- detach(c);
- detachstack(c);
- if(sel == c)
- focus(NULL);
- XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
- setclientstate(c, WithdrawnState);
- free(c->tags);
- free(c);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XUngrabServer(dpy);
- arrange();
-}
-
-static void
-updatesizehints(Client *c) {
- long msize;
- XSizeHints size;
-
- 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 if(c->flags & PMinSize) {
- c->basew = size.min_width;
- c->baseh = size.min_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 if(c->flags & PBaseSize) {
- c->minw = size.base_width;
- c->minh = size.base_height;