JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
added protocol killing stuff
[dwm.git] / client.c
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
13 void
14 update_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
40 void
41 focus(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
54 void
55 manage(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
96 static int
97 dummy_error_handler(Display *dpy, XErrorEvent *error)
98 {
99         return 0;
100 }
101
102 void
103 unmanage(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 }
126
127
128 Client *
129 getclient(Window w)
130 {
131         Client *c;
132         for(c = clients; c; c = c->next)
133                 if(c->win == w)
134                         return c;
135         return NULL;
136 }
137