all repos — dwm @ 586f66331d1105be03c42e6faeae1672b974a98a

fork of suckless dynamic window manager

client.c (view raw)

  1/*
  2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
  3 * See LICENSE file for license details.
  4 */
  5
  6#include <stdlib.h>
  7#include <string.h>
  8#include <X11/Xatom.h>
  9
 10#include "util.h"
 11#include "wm.h"
 12
 13void
 14update_name(Client *c)
 15{
 16	XTextProperty name;
 17	int n;
 18	char **list = NULL;
 19
 20	name.nitems = 0;
 21	c->name[0] = 0;
 22	XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]);
 23	if(!name.nitems)
 24		XGetWMName(dpy, c->win, &name);
 25	if(!name.nitems)
 26		return;
 27	if(name.encoding == XA_STRING)
 28		strncpy(c->name, (char *)name.value, sizeof(c->name));
 29	else {
 30		if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
 31				&& n > 0 && *list)
 32		{
 33			strncpy(c->name, *list, sizeof(c->name));
 34			XFreeStringList(list);
 35		}
 36	}
 37	XFree(name.value);
 38}
 39
 40void
 41focus(Client *c)
 42{
 43	Client **l;
 44	for(l=&stack; *l && *l != c; l=&(*l)->snext);
 45	eassert(*l == c);
 46	*l = c->snext;
 47	c->snext = stack;
 48	stack = c;
 49	XRaiseWindow(dpy, c->win);
 50	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
 51	XFlush(dpy);
 52}
 53
 54void
 55manage(Window w, XWindowAttributes *wa)
 56{
 57	Client *c, **l;
 58	XSetWindowAttributes twa;
 59	long msize;
 60
 61	c = emallocz(sizeof(Client));
 62	c->win = w;
 63	c->r[RFloat].x = wa->x;
 64	c->r[RFloat].y = wa->y;
 65	c->r[RFloat].width = wa->width;
 66	c->r[RFloat].height = wa->height;
 67	c->border = wa->border_width;
 68	XSetWindowBorderWidth(dpy, c->win, 0);
 69	XGetTransientForHint(dpy, c->win, &c->trans);
 70	if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags)
 71		c->size.flags = PSize;
 72	c->fixedsize =
 73		(c->size.flags & PMinSize && c->size.flags & PMaxSize
 74		 && c->size.min_width == c->size.max_width
 75		 && c->size.min_height == c->size.max_height);
 76	update_name(c);
 77	twa.override_redirect = 1;
 78	twa.background_pixmap = ParentRelative;
 79	twa.event_mask = ExposureMask;
 80
 81	c->title = XCreateWindow(dpy, root, c->r[RFloat].x, c->r[RFloat].y,
 82			c->r[RFloat].width, barrect.height, 0,
 83			DefaultDepth(dpy, screen), CopyFromParent,
 84			DefaultVisual(dpy, screen),
 85			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
 86
 87	for(l=&clients; *l; l=&(*l)->next);
 88	c->next = *l; /* *l == nil */
 89	*l = c;
 90	c->snext = stack;
 91	stack = c;
 92	XMapWindow(dpy, c->win);
 93	focus(c);
 94}
 95
 96static int
 97dummy_error_handler(Display *dpy, XErrorEvent *error)
 98{
 99	return 0;
100}
101
102void
103unmanage(Client *c)
104{
105	Client **l;
106
107	XGrabServer(dpy);
108	XSetErrorHandler(dummy_error_handler);
109
110	XUnmapWindow(dpy, c->win);
111	XDestroyWindow(dpy, c->title);
112
113	for(l=&clients; *l && *l != c; l=&(*l)->next);
114	eassert(*l == c);
115	*l = c->next;
116	for(l=&stack; *l && *l != c; l=&(*l)->snext);
117	eassert(*l == c);
118	*l = c->snext;
119	free(c);
120
121	XFlush(dpy);
122	XSetErrorHandler(error_handler);
123	XUngrabServer(dpy);
124	flush_events(EnterWindowMask);
125	if(stack)
126		focus(stack);
127}
128
129
130Client *
131getclient(Window w)
132{
133	Client *c;
134	for(c = clients; c; c = c->next)
135		if(c->win == w)
136			return c;
137	return NULL;
138}
139
140void
141draw_client(Client *c)
142{
143	
144
145
146}