/* Copyright (c) 1999 Decklin Foster Copyright (c) 2000 Linus Nilsson */ #include "yawm.h" #include #include #include void make_new_client(Window w) { Client *c; int i; XGrabServer(dpy); c = (Client *) malloc(sizeof(Client)); c->window = (int) NULL; c->next = head_client; c->prev = NULL; if (head_client) { head_client->prev = c; } c->name = "Untitled"; c->barname = "Untitled"; c->minimized = 0; c->maximized = 0; c->shaded = 0; head_client = c; initialize(c, w); c->y += theight(c); reparent(c); if (wm_state(c) == IconicState) { c->ignore_unmap++; XUnmapWindow(dpy, c->parent); XUnmapWindow(dpy, c->window); c->minimized = 1; } else { XMapWindow(dpy, c->window); XMapRaised(dpy, c->parent); set_wm_state(c, NormalState); } #ifdef DEBUG err("%s (%d, %d): %#x (%#x) @ %dx%d+%d+%d", c->name, wm_state(c), c->ignore_unmap, c->window, c->parent, c->width, c->height, c->x, c->y); #endif XSync(dpy, False); XUngrabServer(dpy); } void initialize(Client *c, Window w) { XWindowAttributes attr; long dummy; XWMHints *hints = XGetWMHints(dpy, w); c->window = w; c->ignore_unmap = 0; XGetTransientForHint(dpy, c->window, &c->trans); XFetchName(dpy, c->window, &c->name); XGetWindowAttributes(dpy, c->window, &attr); c->x = attr.x; c->y = attr.y; c->width = attr.width; c->height = attr.height; c->cmap = attr.colormap; c->size = XAllocSizeHints(); XGetWMNormalHints(dpy, c->window, c->size, &dummy); if (attr.map_state == IsViewable) { c->ignore_unmap++; } else { init_position(c); if (hints && hints->flags & StateHint) set_wm_state(c, hints->initial_state); } if (hints) { XFree(hints); } } void init_position(Client *c) { int x, y; int xmax = DisplayWidth(dpy, screen); int ymax = DisplayHeight(dpy, screen); if (c->size->flags & (/*PSize | */USSize)) { c->width = c->size->width; c->height = c->size->height; } if (c->width < MINSIZE) c->width = MINSIZE; if (c->height < MINSIZE) c->height = MINSIZE; if (c->width > xmax) c->width = xmax; if (c->height > ymax) c->height = ymax; if (c->size->flags & (/*PPosition | */USPosition)) { c->x = c->size->x; c->y = c->size->y; if (c->x < 0 || c->y < 0 || c->x > xmax || c->y > ymax) c->x = c->y = 1; } else { get_mouse_position(&x, &y); c->x = (x / (float)xmax) * (xmax - c->width); c->y = (y / (float)ymax) * (ymax - theight(c) - c->height); } } void reparent(Client *c) { XSetWindowAttributes p_attr; XSelectInput(dpy, c->window, ColormapChangeMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask | KeyPressMask | ExposureMask); p_attr.override_redirect = True; p_attr.background_pixel = bg.pixel; p_attr.border_pixel = bd.pixel; p_attr.event_mask = ChildMask | ButtonPressMask | ExposureMask | CWBackingPixel | CWBackPixel | EnterWindowMask | KeyPressMask; c->parent = XCreateWindow(dpy, root, c->x, c->y - theight(c), c->width, c->height + theight(c), opt_bw, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixel | CWBackingPixel | CWBorderPixel | CWBackingStore | CWEventMask, &p_attr); #ifdef SHAPE if (shape) { XShapeSelectInput(dpy, c->window, ShapeNotifyMask); set_shape(c); } #endif XAddToSaveSet(dpy, c->window); XSetWindowBorderWidth(dpy, c->window, 0); XResizeWindow(dpy, c->window, c->width, c->height); XReparentWindow(dpy, c->window, c->parent, 0, theight(c)); send_config(c); }