aewl

view client.c @ 18:1efa34c6e1b6

added mouse-based resizals
author Anselm R. Garbe <garbeam@wmii.de>
date Tue, 11 Jul 2006 21:24:10 +0200
parents 359b6e563b95
children b5510d0c6d43
line source
1 /*
2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
3 * See LICENSE file for license details.
4 */
6 #include <stdlib.h>
7 #include <string.h>
8 #include <X11/Xatom.h>
10 #include "util.h"
11 #include "wm.h"
13 #define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask | EnterWindowMask)
15 void
16 update_name(Client *c)
17 {
18 XTextProperty name;
19 int n;
20 char **list = NULL;
22 name.nitems = 0;
23 c->name[0] = 0;
24 XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]);
25 if(!name.nitems)
26 XGetWMName(dpy, c->win, &name);
27 if(!name.nitems)
28 return;
29 if(name.encoding == XA_STRING)
30 strncpy(c->name, (char *)name.value, sizeof(c->name));
31 else {
32 if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
33 && n > 0 && *list)
34 {
35 strncpy(c->name, *list, sizeof(c->name));
36 XFreeStringList(list);
37 }
38 }
39 XFree(name.value);
40 if(c == stack)
41 draw_bar();
42 else
43 draw_client(c);
44 }
46 void
47 focus(Client *c)
48 {
49 Client **l;
50 for(l=&stack; *l && *l != c; l=&(*l)->snext);
51 eassert(*l == c);
52 *l = c->snext;
53 c->snext = stack;
54 stack = c;
55 XRaiseWindow(dpy, c->win);
56 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
57 XFlush(dpy);
58 }
60 void
61 manage(Window w, XWindowAttributes *wa)
62 {
63 Client *c, **l;
64 XSetWindowAttributes twa;
65 long msize;
67 c = emallocz(sizeof(Client));
68 c->win = w;
69 c->r[RFloat].x = wa->x;
70 c->r[RFloat].y = wa->y;
71 c->r[RFloat].width = wa->width;
72 c->r[RFloat].height = wa->height;
73 c->border = wa->border_width;
74 XSetWindowBorderWidth(dpy, c->win, 0);
75 XSelectInput(dpy, c->win, CLIENT_MASK);
76 XGetTransientForHint(dpy, c->win, &c->trans);
77 if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags)
78 c->size.flags = PSize;
79 c->fixedsize =
80 (c->size.flags & PMinSize && c->size.flags & PMaxSize
81 && c->size.min_width == c->size.max_width
82 && c->size.min_height == c->size.max_height);
83 update_name(c);
84 twa.override_redirect = 1;
85 twa.background_pixmap = ParentRelative;
86 twa.event_mask = ExposureMask;
88 c->title = XCreateWindow(dpy, root, c->r[RFloat].x, c->r[RFloat].y,
89 c->r[RFloat].width, barrect.height, 0,
90 DefaultDepth(dpy, screen), CopyFromParent,
91 DefaultVisual(dpy, screen),
92 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
94 for(l=&clients; *l; l=&(*l)->next);
95 c->next = *l; /* *l == nil */
96 *l = c;
97 c->snext = stack;
98 stack = c;
99 XMapWindow(dpy, c->win);
100 XGrabButton(dpy, AnyButton, Mod1Mask, c->win, False, ButtonPressMask,
101 GrabModeAsync, GrabModeSync, None, None);
102 focus(c);
103 }
105 void
106 resize(Client *c)
107 {
108 XConfigureEvent e;
110 XMoveResizeWindow(dpy, c->win, c->r[RFloat].x, c->r[RFloat].y,
111 c->r[RFloat].width, c->r[RFloat].height);
112 e.type = ConfigureNotify;
113 e.event = c->win;
114 e.window = c->win;
115 e.x = c->r[RFloat].x;
116 e.y = c->r[RFloat].y;
117 e.width = c->r[RFloat].width;
118 e.height = c->r[RFloat].height;
119 e.border_width = c->border;
120 e.above = None;
121 e.override_redirect = False;
122 XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
123 XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e);
124 XSelectInput(dpy, c->win, CLIENT_MASK);
125 XFlush(dpy);
126 }
128 static int
129 dummy_error_handler(Display *dpy, XErrorEvent *error)
130 {
131 return 0;
132 }
134 void
135 unmanage(Client *c)
136 {
137 Client **l;
139 XGrabServer(dpy);
140 XSetErrorHandler(dummy_error_handler);
142 XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
143 XUnmapWindow(dpy, c->win);
144 XDestroyWindow(dpy, c->title);
146 for(l=&clients; *l && *l != c; l=&(*l)->next);
147 eassert(*l == c);
148 *l = c->next;
149 for(l=&stack; *l && *l != c; l=&(*l)->snext);
150 eassert(*l == c);
151 *l = c->snext;
152 free(c);
154 XFlush(dpy);
155 XSetErrorHandler(error_handler);
156 XUngrabServer(dpy);
157 discard_events(EnterWindowMask);
158 if(stack)
159 focus(stack);
160 }
163 Client *
164 getclient(Window w)
165 {
166 Client *c;
167 for(c = clients; c; c = c->next)
168 if(c->win == w)
169 return c;
170 return NULL;
171 }
173 void
174 draw_client(Client *c)
175 {
179 }