2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
3 * See LICENSE file for license details.
21 stack->w = sw - 2 * stack->border;
22 stack->h = sh - bh - 2 * stack->border;
24 discard_events(EnterWindowMask);
31 int n, cols, rows, gw, gh, i, j;
36 for(n = 0, c = clients; c; c = c->next, n++);
38 if(modff(rt, &fd) < 0.5)
48 gh = (sh - bh - 2) / rows;
50 for(i = j = 0, c = clients; c; c = c->next) {
61 discard_events(EnterWindowMask);
67 const char *arg = aux;
72 if(!strncmp(arg, "next", 5))
73 c = stack->snext ? stack->snext : stack;
74 else if(!strncmp(arg, "prev", 5))
75 for(c = stack; c && c->snext; c = c->snext);
89 if(c->proto & WM_PROTOCOL_DELWIN)
90 send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
92 XKillClient(dpy, c->win);
96 resize_title(Client *c)
98 c->tw = textw(&brush.font, c->name) + bh;
101 c->tx = c->x + c->w - c->tw + 2;
103 XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
107 update_name(Client *c)
115 XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]);
117 XGetWMName(dpy, c->win, &name);
120 if(name.encoding == XA_STRING)
121 strncpy(c->name, (char *)name.value, sizeof(c->name));
123 if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
126 strncpy(c->name, *list, sizeof(c->name));
127 XFreeStringList(list);
135 update_size(Client *c)
139 if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags)
141 c->flags = size.flags;
142 if(c->flags & PBaseSize) {
143 c->basew = size.base_width;
144 c->baseh = size.base_height;
147 c->basew = c->baseh = 0;
148 if(c->flags & PResizeInc) {
149 c->incw = size.width_inc;
150 c->inch = size.height_inc;
153 c->incw = c->inch = 0;
154 if(c->flags & PMaxSize) {
155 c->maxw = size.max_width;
156 c->maxh = size.max_height;
159 c->maxw = c->maxh = 0;
160 if(c->flags & PMinSize) {
161 c->minw = size.min_width;
162 c->minh = size.min_height;
165 c->minw = c->minh = 0;
166 if(c->flags & PWinGravity)
167 c->grav = size.win_gravity;
169 c->grav = NorthWestGravity;
175 XRaiseWindow(dpy, c->win);
176 XRaiseWindow(dpy, c->title);
182 XLowerWindow(dpy, c->title);
183 XLowerWindow(dpy, c->win);
192 for(l = &stack; *l && *l != c; l = &(*l)->snext);
197 if(old && old != c) {
198 XMapWindow(dpy, old->title);
201 XUnmapWindow(dpy, c->title);
203 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
208 manage(Window w, XWindowAttributes *wa)
211 XSetWindowAttributes twa;
213 c = emallocz(sizeof(Client));
215 c->tx = c->x = wa->x;
216 c->ty = c->y = wa->y;
219 c->tw = c->w = wa->width;
224 XSetWindowBorderWidth(dpy, c->win, 1);
225 XSetWindowBorder(dpy, c->win, brush.border);
226 XSelectInput(dpy, c->win,
227 StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
228 XGetTransientForHint(dpy, c->win, &c->trans);
229 twa.override_redirect = 1;
230 twa.background_pixmap = ParentRelative;
231 twa.event_mask = ExposureMask;
233 c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
234 0, DefaultDepth(dpy, screen), CopyFromParent,
235 DefaultVisual(dpy, screen),
236 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
239 for(l=&clients; *l; l=&(*l)->next);
240 c->next = *l; /* *l == nil */
244 XMapRaised(dpy, c->win);
245 XMapRaised(dpy, c->title);
246 XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask,
247 GrabModeAsync, GrabModeSync, None, None);
248 XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask,
249 GrabModeAsync, GrabModeSync, None, None);
250 XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
251 GrabModeAsync, GrabModeSync, None, None);
257 gravitate(Client *c, Bool invert)
263 case NorthWestGravity:
265 case NorthEastGravity:
271 dy = -(c->h / 2) + c->border;
273 case SouthEastGravity:
275 case SouthWestGravity:
284 case NorthWestGravity:
286 case SouthWestGravity:
292 dx = -(c->w / 2) + c->border;
294 case NorthEastGravity:
296 case SouthEastGravity:
297 dx = -(c->w + c->border);
317 XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
318 e.type = ConfigureNotify;
325 e.border_width = c->border;
327 e.override_redirect = False;
328 XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e);
333 dummy_error_handler(Display *dpy, XErrorEvent *error)
344 XSetErrorHandler(dummy_error_handler);
346 XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
347 XDestroyWindow(dpy, c->title);
349 for(l=&clients; *l && *l != c; l=&(*l)->next);
352 for(l=&stack; *l && *l != c; l=&(*l)->snext);
358 XSetErrorHandler(error_handler);
368 for(c = clients; c; c = c->next)
378 for(c = clients; c; c = c->next)
385 draw_client(Client *c)
392 brush.x = brush.y = 0;
396 draw(dpy, &brush, True, c->name);
397 XCopyArea(dpy, brush.drawable, c->title, brush.gc,
398 0, 0, c->tw, c->th, 0, 0);