all repos — dwm @ 5ed16faecb94b551ea00ea940e8d719211576de8

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	if(c == stack)
 39		draw_bar();
 40	else
 41		draw_client(c);
 42}
 43
 44void
 45focus(Client *c)
 46{
 47	Client **l;
 48	for(l=&stack; *l && *l != c; l=&(*l)->snext);
 49	eassert(*l == c);
 50	*l = c->snext;
 51	c->snext = stack;
 52	stack = c;
 53	XRaiseWindow(dpy, c->win);
 54	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
 55	XFlush(dpy);
 56}
 57
 58void
 59manage(Window w, XWindowAttributes *wa)
 60{
 61	Client *c, **l;
 62	XSetWindowAttributes twa;
 63	long msize;
 64
 65	c = emallocz(sizeof(Client));
 66	c->win = w;
 67	c->r[RFloat].x = wa->x;
 68	c->r[RFloat].y = wa->y;
 69	c->r[RFloat].width = wa->width;
 70	c->r[RFloat].height = wa->height;
 71	c->border = wa->border_width;
 72	XSetWindowBorderWidth(dpy, c->win, 0);
 73	XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
 74	XGetTransientForHint(dpy, c->win, &c->trans);
 75	if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags)
 76		c->size.flags = PSize;
 77	c->fixedsize =
 78		(c->size.flags & PMinSize && c->size.flags & PMaxSize
 79		 && c->size.min_width == c->size.max_width
 80		 && c->size.min_height == c->size.max_height);
 81	update_name(c);
 82	twa.override_redirect = 1;
 83	twa.background_pixmap = ParentRelative;
 84	twa.event_mask = ExposureMask;
 85
 86	c->title = XCreateWindow(dpy, root, c->r[RFloat].x, c->r[RFloat].y,
 87			c->r[RFloat].width, barrect.height, 0,
 88			DefaultDepth(dpy, screen), CopyFromParent,
 89			DefaultVisual(dpy, screen),
 90			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
 91
 92	for(l=&clients; *l; l=&(*l)->next);
 93	c->next = *l; /* *l == nil */
 94	*l = c;
 95	c->snext = stack;
 96	stack = c;
 97	XMapWindow(dpy, c->win);
 98	focus(c);
 99}
100
101static int
102dummy_error_handler(Display *dpy, XErrorEvent *error)
103{
104	return 0;
105}
106
107void
108unmanage(Client *c)
109{
110	Client **l;
111
112	XGrabServer(dpy);
113	XSetErrorHandler(dummy_error_handler);
114
115	XUnmapWindow(dpy, c->win);
116	XDestroyWindow(dpy, c->title);
117
118	for(l=&clients; *l && *l != c; l=&(*l)->next);
119	eassert(*l == c);
120	*l = c->next;
121	for(l=&stack; *l && *l != c; l=&(*l)->snext);
122	eassert(*l == c);
123	*l = c->snext;
124	free(c);
125
126	XFlush(dpy);
127	XSetErrorHandler(error_handler);
128	XUngrabServer(dpy);
129	flush_events(EnterWindowMask);
130	if(stack)
131		focus(stack);
132}
133
134
135Client *
136getclient(Window w)
137{
138	Client *c;
139	for(c = clients; c; c = c->next)
140		if(c->win == w)
141			return c;
142	return NULL;
143}
144
145void
146draw_client(Client *c)
147{
148	
149
150
151}