garbeam@5: /* garbeam@5: * (C)opyright MMVI Anselm R. Garbe garbeam@5: * See LICENSE file for license details. garbeam@5: */ garbeam@5: garbeam@10: #include garbeam@5: #include garbeam@5: #include garbeam@5: garbeam@5: #include "util.h" garbeam@5: #include "wm.h" garbeam@5: garbeam@13: void garbeam@13: update_name(Client *c) garbeam@5: { garbeam@5: XTextProperty name; garbeam@5: int n; garbeam@7: char **list = NULL; garbeam@5: garbeam@5: name.nitems = 0; garbeam@5: c->name[0] = 0; garbeam@5: XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]); garbeam@5: if(!name.nitems) garbeam@5: XGetWMName(dpy, c->win, &name); garbeam@5: if(!name.nitems) garbeam@5: return; garbeam@5: if(name.encoding == XA_STRING) garbeam@5: strncpy(c->name, (char *)name.value, sizeof(c->name)); garbeam@5: else { garbeam@5: if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success garbeam@5: && n > 0 && *list) garbeam@5: { garbeam@5: strncpy(c->name, *list, sizeof(c->name)); garbeam@5: XFreeStringList(list); garbeam@5: } garbeam@5: } garbeam@5: XFree(name.value); garbeam@5: } garbeam@5: garbeam@10: void garbeam@13: focus(Client *c) garbeam@13: { garbeam@13: Client **l; garbeam@13: for(l=&stack; *l && *l != c; l=&(*l)->snext); garbeam@13: eassert(*l == c); garbeam@13: *l = c->snext; garbeam@13: c->snext = stack; garbeam@13: stack = c; garbeam@13: XRaiseWindow(dpy, c->win); garbeam@13: XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); garbeam@13: XFlush(dpy); garbeam@13: } garbeam@13: garbeam@13: void garbeam@10: manage(Window w, XWindowAttributes *wa) garbeam@5: { garbeam@10: Client *c, **l; garbeam@5: XSetWindowAttributes twa; garbeam@5: long msize; garbeam@5: garbeam@5: c = emallocz(sizeof(Client)); garbeam@5: c->win = w; garbeam@5: c->r[RFloat].x = wa->x; garbeam@5: c->r[RFloat].y = wa->y; garbeam@5: c->r[RFloat].width = wa->width; garbeam@5: c->r[RFloat].height = wa->height; garbeam@5: c->border = wa->border_width; garbeam@5: XSetWindowBorderWidth(dpy, c->win, 0); garbeam@5: XGetTransientForHint(dpy, c->win, &c->trans); garbeam@5: if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags) garbeam@5: c->size.flags = PSize; garbeam@5: c->fixedsize = garbeam@5: (c->size.flags & PMinSize && c->size.flags & PMaxSize garbeam@5: && c->size.min_width == c->size.max_width garbeam@5: && c->size.min_height == c->size.max_height); garbeam@13: update_name(c); garbeam@5: twa.override_redirect = 1; garbeam@5: twa.background_pixmap = ParentRelative; garbeam@5: twa.event_mask = ExposureMask; garbeam@5: garbeam@5: c->title = XCreateWindow(dpy, root, c->r[RFloat].x, c->r[RFloat].y, garbeam@5: c->r[RFloat].width, barrect.height, 0, garbeam@5: DefaultDepth(dpy, screen), CopyFromParent, garbeam@5: DefaultVisual(dpy, screen), garbeam@5: CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); garbeam@5: garbeam@10: for(l=&clients; *l; l=&(*l)->next); garbeam@10: c->next = *l; /* *l == nil */ garbeam@10: *l = c; garbeam@13: c->snext = stack; garbeam@13: stack = c; garbeam@13: XMapWindow(dpy, c->win); garbeam@13: focus(c); garbeam@5: } garbeam@9: garbeam@10: static int garbeam@10: dummy_error_handler(Display *dpy, XErrorEvent *error) garbeam@10: { garbeam@10: return 0; garbeam@10: } garbeam@10: garbeam@10: void garbeam@10: unmanage(Client *c) garbeam@10: { garbeam@10: Client **l; garbeam@10: garbeam@10: XGrabServer(dpy); garbeam@10: XSetErrorHandler(dummy_error_handler); garbeam@10: garbeam@10: XUnmapWindow(dpy, c->win); garbeam@10: XDestroyWindow(dpy, c->title); garbeam@10: garbeam@10: for(l=&clients; *l && *l != c; l=&(*l)->next); garbeam@10: eassert(*l == c); garbeam@10: *l = c->next; garbeam@13: for(l=&stack; *l && *l != c; l=&(*l)->snext); garbeam@13: eassert(*l == c); garbeam@13: *l = c->snext; garbeam@10: free(c); garbeam@10: garbeam@10: XFlush(dpy); garbeam@10: XSetErrorHandler(error_handler); garbeam@10: XUngrabServer(dpy); garbeam@13: flush_events(EnterWindowMask); garbeam@10: } garbeam@10: garbeam@10: garbeam@9: Client * garbeam@9: getclient(Window w) garbeam@9: { garbeam@9: Client *c; garbeam@9: for(c = clients; c; c = c->next) garbeam@9: if(c->win == w) garbeam@9: return c; garbeam@9: return NULL; garbeam@9: } garbeam@13: