/* aewm - a minimalistic X11 window manager. ------- vim:sw=4:et * Copyright (c) 1998-2001 Decklin Foster <decklin@red-bean.com> * Free software! Please see README for details and license. */ #include "aewm.h" #include <X11/Xmd.h> Client *head_client = NULL; Client *find_client(Window w) { Client *c; for (c = head_client; c; c = c->next) if (c->window == w) return c; return NULL; } void set_focus_on(Window w) { char *name; XFetchName(dpy, w, &name); if (name && strcmp(name, "skip")) { XSetInputFocus(dpy, w, RevertToPointerRoot, CurrentTime); #ifdef DEBUG printf("aewm-drakx: adding %lx %s\n", w, name); #endif } } /* Attempt to follow the ICCCM by explicity specifying 32 bits for * this property. Does this goof up on 64 bit systems? */ void set_wm_state(Client *c, int state) { CARD32 data[2]; data[0] = state; data[1] = None; /* Icon? We don't need no steenking icon. */ XChangeProperty(dpy, c->window, wm_state, wm_state, 32, PropModeReplace, (unsigned char *)data, 2); } /* If we can't find a WM_STATE we're going to have to assume * Withdrawn. This is not exactly optimal, since we can't really * distinguish between the case where no WM has run yet and when the * state was explicitly removed (Clients are allowed to either set the * atom to Withdrawn or just remove it... yuck.) */ long get_wm_state(Client *c) { Atom real_type; int real_format; unsigned long items_read, items_left; long *data, state = WithdrawnState; if (XGetWindowProperty(dpy, c->window, wm_state, 0L, 2L, False, wm_state, &real_type, &real_format, &items_read, &items_left, (unsigned char **) &data) == Success && items_read) { state = *data; XFree(data); } return state; } void remove_client(Client *c) { int ignore_xerror(Display *dpy, XErrorEvent *e) { return 0; } Client *p; XGrabServer(dpy); XSetErrorHandler(ignore_xerror); set_wm_state(c, WithdrawnState); if (head_client == c) head_client = c->next; else for (p = head_client; p && p->next; p = p->next) if (p->next == c) p->next = c->next; free(c); if (head_client) set_focus_on(head_client->window); XSync(dpy, False); XSetErrorHandler(handle_xerror); XUngrabServer(dpy); } void make_new_client(Window w) { Client *c; XWindowAttributes attr; c = malloc(sizeof *c); c->next = head_client; c->window = w; head_client = c; XGrabServer(dpy); XGetWindowAttributes(dpy, w, &attr); if (attr.map_state != IsViewable) { XWMHints *hints; set_wm_state(c, NormalState); if ((hints = XGetWMHints(dpy, w))) { if (hints->flags & StateHint) set_wm_state(c, hints->initial_state); XFree(hints); } } if (attr.map_state == IsViewable) { XMapWindow(dpy, c->window); set_wm_state(c, NormalState); } else if (get_wm_state(c) == NormalState) { XMapWindow(dpy, c->window); } set_focus_on(w); XSync(dpy, False); XUngrabServer(dpy); }