aewl

annotate client.c @ 21:3ef108a5ca0a

implemented draw_client stuff
author Anselm R. Garbe <garbeam@wmii.de>
date Tue, 11 Jul 2006 23:18:30 +0200
parents 4560e0882c1d
children bd3a44353916
rev   line source
garbeam@5 1 /*
garbeam@5 2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
garbeam@5 3 * See LICENSE file for license details.
garbeam@5 4 */
garbeam@5 5
garbeam@10 6 #include <stdlib.h>
garbeam@5 7 #include <string.h>
garbeam@5 8 #include <X11/Xatom.h>
garbeam@5 9
garbeam@5 10 #include "util.h"
garbeam@5 11 #include "wm.h"
garbeam@5 12
garbeam@18 13 #define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask | EnterWindowMask)
garbeam@18 14
garbeam@13 15 void
garbeam@13 16 update_name(Client *c)
garbeam@5 17 {
garbeam@5 18 XTextProperty name;
garbeam@5 19 int n;
garbeam@7 20 char **list = NULL;
garbeam@5 21
garbeam@5 22 name.nitems = 0;
garbeam@5 23 c->name[0] = 0;
garbeam@5 24 XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]);
garbeam@5 25 if(!name.nitems)
garbeam@5 26 XGetWMName(dpy, c->win, &name);
garbeam@5 27 if(!name.nitems)
garbeam@5 28 return;
garbeam@5 29 if(name.encoding == XA_STRING)
garbeam@5 30 strncpy(c->name, (char *)name.value, sizeof(c->name));
garbeam@5 31 else {
garbeam@5 32 if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
garbeam@5 33 && n > 0 && *list)
garbeam@5 34 {
garbeam@5 35 strncpy(c->name, *list, sizeof(c->name));
garbeam@5 36 XFreeStringList(list);
garbeam@5 37 }
garbeam@5 38 }
garbeam@5 39 XFree(name.value);
garbeam@5 40 }
garbeam@5 41
garbeam@10 42 void
garbeam@20 43 update_size(Client *c)
garbeam@20 44 {
garbeam@20 45 XSizeHints size;
garbeam@20 46 long msize;
garbeam@20 47 if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags)
garbeam@20 48 size.flags = PSize;
garbeam@20 49 c->flags = size.flags;
garbeam@21 50 if(c->flags & PBaseSize) {
garbeam@21 51 c->basew = size.base_width;
garbeam@21 52 c->baseh = size.base_height;
garbeam@21 53 }
garbeam@21 54 else
garbeam@21 55 c->basew = c->baseh = 0;
garbeam@21 56 if(c->flags & PResizeInc) {
garbeam@21 57 c->incw = size.width_inc;
garbeam@21 58 c->inch = size.height_inc;
garbeam@21 59 }
garbeam@21 60 else
garbeam@21 61 c->incw = c->inch = 0;
garbeam@21 62 if(c->flags & PMaxSize) {
garbeam@21 63 c->maxw = size.max_width;
garbeam@21 64 c->maxh = size.max_height;
garbeam@21 65 }
garbeam@21 66 else
garbeam@21 67 c->maxw = c->maxh = 0;
garbeam@21 68 if(c->flags & PMinSize) {
garbeam@21 69 c->minw = size.min_width;
garbeam@21 70 c->minh = size.min_height;
garbeam@21 71 }
garbeam@21 72 else
garbeam@21 73 c->minw = c->minh = 0;
garbeam@20 74 }
garbeam@20 75
garbeam@20 76 void
garbeam@13 77 focus(Client *c)
garbeam@13 78 {
garbeam@21 79 Client **l, *old;
garbeam@21 80
garbeam@21 81 old = stack;
garbeam@13 82 for(l=&stack; *l && *l != c; l=&(*l)->snext);
garbeam@13 83 eassert(*l == c);
garbeam@13 84 *l = c->snext;
garbeam@13 85 c->snext = stack;
garbeam@13 86 stack = c;
garbeam@13 87 XRaiseWindow(dpy, c->win);
garbeam@21 88 XRaiseWindow(dpy, c->title);
garbeam@13 89 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
garbeam@21 90 if(old && old != c) {
garbeam@21 91 XMapWindow(dpy, old->title);
garbeam@21 92 draw_client(old);
garbeam@21 93 }
garbeam@21 94 XUnmapWindow(dpy, c->title);
garbeam@21 95 draw_bar();
garbeam@13 96 XFlush(dpy);
garbeam@13 97 }
garbeam@13 98
garbeam@13 99 void
garbeam@10 100 manage(Window w, XWindowAttributes *wa)
garbeam@5 101 {
garbeam@10 102 Client *c, **l;
garbeam@5 103 XSetWindowAttributes twa;
garbeam@5 104
garbeam@5 105 c = emallocz(sizeof(Client));
garbeam@5 106 c->win = w;
garbeam@20 107 c->x = wa->x;
garbeam@20 108 c->y = wa->y;
garbeam@20 109 c->w = wa->width;
garbeam@20 110 c->h = wa->height;
garbeam@20 111 update_size(c);
garbeam@19 112 XSetWindowBorderWidth(dpy, c->win, 1);
garbeam@18 113 XSelectInput(dpy, c->win, CLIENT_MASK);
garbeam@5 114 XGetTransientForHint(dpy, c->win, &c->trans);
garbeam@5 115 twa.override_redirect = 1;
garbeam@5 116 twa.background_pixmap = ParentRelative;
garbeam@5 117 twa.event_mask = ExposureMask;
garbeam@5 118
garbeam@20 119 c->title = XCreateWindow(dpy, root, c->x, c->y, c->w, barrect.height,
garbeam@20 120 0, DefaultDepth(dpy, screen), CopyFromParent,
garbeam@5 121 DefaultVisual(dpy, screen),
garbeam@5 122 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
garbeam@21 123 update_name(c);
garbeam@5 124
garbeam@10 125 for(l=&clients; *l; l=&(*l)->next);
garbeam@10 126 c->next = *l; /* *l == nil */
garbeam@10 127 *l = c;
garbeam@13 128 c->snext = stack;
garbeam@13 129 stack = c;
garbeam@13 130 XMapWindow(dpy, c->win);
garbeam@21 131 XMapWindow(dpy, c->title);
garbeam@19 132 XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask,
garbeam@19 133 GrabModeAsync, GrabModeSync, None, None);
garbeam@19 134 XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask,
garbeam@19 135 GrabModeAsync, GrabModeSync, None, None);
garbeam@19 136 XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
garbeam@18 137 GrabModeAsync, GrabModeSync, None, None);
garbeam@21 138 resize(c);
garbeam@13 139 focus(c);
garbeam@5 140 }
garbeam@9 141
garbeam@18 142 void
garbeam@18 143 resize(Client *c)
garbeam@18 144 {
garbeam@18 145 XConfigureEvent e;
garbeam@18 146
garbeam@20 147 XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
garbeam@21 148 XMoveResizeWindow(dpy, c->title, c->x + c->w / 3, c->y, 2 * c->w / 3, barrect.height);
garbeam@18 149 e.type = ConfigureNotify;
garbeam@18 150 e.event = c->win;
garbeam@18 151 e.window = c->win;
garbeam@20 152 e.x = c->x;
garbeam@20 153 e.y = c->y;
garbeam@20 154 e.width = c->w;
garbeam@20 155 e.height = c->h;
garbeam@19 156 e.border_width = 0;
garbeam@18 157 e.above = None;
garbeam@18 158 e.override_redirect = False;
garbeam@18 159 XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
garbeam@18 160 XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e);
garbeam@18 161 XSelectInput(dpy, c->win, CLIENT_MASK);
garbeam@18 162 XFlush(dpy);
garbeam@18 163 }
garbeam@18 164
garbeam@10 165 static int
garbeam@10 166 dummy_error_handler(Display *dpy, XErrorEvent *error)
garbeam@10 167 {
garbeam@10 168 return 0;
garbeam@10 169 }
garbeam@10 170
garbeam@10 171 void
garbeam@10 172 unmanage(Client *c)
garbeam@10 173 {
garbeam@10 174 Client **l;
garbeam@10 175
garbeam@10 176 XGrabServer(dpy);
garbeam@10 177 XSetErrorHandler(dummy_error_handler);
garbeam@10 178
garbeam@18 179 XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
garbeam@10 180 XUnmapWindow(dpy, c->win);
garbeam@10 181 XDestroyWindow(dpy, c->title);
garbeam@10 182
garbeam@10 183 for(l=&clients; *l && *l != c; l=&(*l)->next);
garbeam@10 184 eassert(*l == c);
garbeam@10 185 *l = c->next;
garbeam@13 186 for(l=&stack; *l && *l != c; l=&(*l)->snext);
garbeam@13 187 eassert(*l == c);
garbeam@13 188 *l = c->snext;
garbeam@10 189 free(c);
garbeam@10 190
garbeam@10 191 XFlush(dpy);
garbeam@10 192 XSetErrorHandler(error_handler);
garbeam@10 193 XUngrabServer(dpy);
garbeam@18 194 discard_events(EnterWindowMask);
garbeam@14 195 if(stack)
garbeam@14 196 focus(stack);
garbeam@10 197 }
garbeam@10 198
garbeam@10 199
garbeam@9 200 Client *
garbeam@9 201 getclient(Window w)
garbeam@9 202 {
garbeam@9 203 Client *c;
garbeam@9 204 for(c = clients; c; c = c->next)
garbeam@9 205 if(c->win == w)
garbeam@9 206 return c;
garbeam@9 207 return NULL;
garbeam@9 208 }
garbeam@13 209
garbeam@14 210 void
garbeam@14 211 draw_client(Client *c)
garbeam@14 212 {
garbeam@21 213 if(!c)
garbeam@21 214 return;
garbeam@21 215 if(c == stack)
garbeam@21 216 draw_bar();
garbeam@14 217
garbeam@21 218 brush.rect.x = brush.rect.y = 0;
garbeam@21 219 brush.rect.width = 2 * c->w / 3;
garbeam@21 220 brush.rect.height = barrect.height;
garbeam@14 221
garbeam@21 222 draw(dpy, &brush, True, c->name);
garbeam@21 223 XCopyArea(dpy, brush.drawable, c->title, brush.gc, 0, 0,
garbeam@21 224 brush.rect.width, brush.rect.height, 0, 0);
garbeam@21 225 XFlush(dpy);
garbeam@14 226 }