aewl

annotate client.c @ 19:b5510d0c6d43

added basic mouse support (actually we don't need more)
author Anselm R. Garbe <garbeam@wmii.de>
date Tue, 11 Jul 2006 21:41:49 +0200
parents 1efa34c6e1b6
children 4560e0882c1d
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@16 40 if(c == stack)
garbeam@16 41 draw_bar();
garbeam@16 42 else
garbeam@16 43 draw_client(c);
garbeam@5 44 }
garbeam@5 45
garbeam@10 46 void
garbeam@13 47 focus(Client *c)
garbeam@13 48 {
garbeam@13 49 Client **l;
garbeam@13 50 for(l=&stack; *l && *l != c; l=&(*l)->snext);
garbeam@13 51 eassert(*l == c);
garbeam@13 52 *l = c->snext;
garbeam@13 53 c->snext = stack;
garbeam@13 54 stack = c;
garbeam@13 55 XRaiseWindow(dpy, c->win);
garbeam@13 56 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
garbeam@13 57 XFlush(dpy);
garbeam@13 58 }
garbeam@13 59
garbeam@13 60 void
garbeam@10 61 manage(Window w, XWindowAttributes *wa)
garbeam@5 62 {
garbeam@10 63 Client *c, **l;
garbeam@5 64 XSetWindowAttributes twa;
garbeam@5 65 long msize;
garbeam@5 66
garbeam@5 67 c = emallocz(sizeof(Client));
garbeam@5 68 c->win = w;
garbeam@5 69 c->r[RFloat].x = wa->x;
garbeam@5 70 c->r[RFloat].y = wa->y;
garbeam@5 71 c->r[RFloat].width = wa->width;
garbeam@5 72 c->r[RFloat].height = wa->height;
garbeam@19 73 XSetWindowBorderWidth(dpy, c->win, 1);
garbeam@18 74 XSelectInput(dpy, c->win, CLIENT_MASK);
garbeam@5 75 XGetTransientForHint(dpy, c->win, &c->trans);
garbeam@5 76 if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags)
garbeam@5 77 c->size.flags = PSize;
garbeam@5 78 c->fixedsize =
garbeam@5 79 (c->size.flags & PMinSize && c->size.flags & PMaxSize
garbeam@5 80 && c->size.min_width == c->size.max_width
garbeam@5 81 && c->size.min_height == c->size.max_height);
garbeam@13 82 update_name(c);
garbeam@5 83 twa.override_redirect = 1;
garbeam@5 84 twa.background_pixmap = ParentRelative;
garbeam@5 85 twa.event_mask = ExposureMask;
garbeam@5 86
garbeam@5 87 c->title = XCreateWindow(dpy, root, c->r[RFloat].x, c->r[RFloat].y,
garbeam@5 88 c->r[RFloat].width, barrect.height, 0,
garbeam@5 89 DefaultDepth(dpy, screen), CopyFromParent,
garbeam@5 90 DefaultVisual(dpy, screen),
garbeam@5 91 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
garbeam@5 92
garbeam@10 93 for(l=&clients; *l; l=&(*l)->next);
garbeam@10 94 c->next = *l; /* *l == nil */
garbeam@10 95 *l = c;
garbeam@13 96 c->snext = stack;
garbeam@13 97 stack = c;
garbeam@13 98 XMapWindow(dpy, c->win);
garbeam@19 99 XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask,
garbeam@19 100 GrabModeAsync, GrabModeSync, None, None);
garbeam@19 101 XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask,
garbeam@19 102 GrabModeAsync, GrabModeSync, None, None);
garbeam@19 103 XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
garbeam@18 104 GrabModeAsync, GrabModeSync, None, None);
garbeam@13 105 focus(c);
garbeam@5 106 }
garbeam@9 107
garbeam@18 108 void
garbeam@18 109 resize(Client *c)
garbeam@18 110 {
garbeam@18 111 XConfigureEvent e;
garbeam@18 112
garbeam@18 113 XMoveResizeWindow(dpy, c->win, c->r[RFloat].x, c->r[RFloat].y,
garbeam@18 114 c->r[RFloat].width, c->r[RFloat].height);
garbeam@18 115 e.type = ConfigureNotify;
garbeam@18 116 e.event = c->win;
garbeam@18 117 e.window = c->win;
garbeam@18 118 e.x = c->r[RFloat].x;
garbeam@18 119 e.y = c->r[RFloat].y;
garbeam@18 120 e.width = c->r[RFloat].width;
garbeam@18 121 e.height = c->r[RFloat].height;
garbeam@19 122 e.border_width = 0;
garbeam@18 123 e.above = None;
garbeam@18 124 e.override_redirect = False;
garbeam@18 125 XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
garbeam@18 126 XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e);
garbeam@18 127 XSelectInput(dpy, c->win, CLIENT_MASK);
garbeam@18 128 XFlush(dpy);
garbeam@18 129 }
garbeam@18 130
garbeam@10 131 static int
garbeam@10 132 dummy_error_handler(Display *dpy, XErrorEvent *error)
garbeam@10 133 {
garbeam@10 134 return 0;
garbeam@10 135 }
garbeam@10 136
garbeam@10 137 void
garbeam@10 138 unmanage(Client *c)
garbeam@10 139 {
garbeam@10 140 Client **l;
garbeam@10 141
garbeam@10 142 XGrabServer(dpy);
garbeam@10 143 XSetErrorHandler(dummy_error_handler);
garbeam@10 144
garbeam@18 145 XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
garbeam@10 146 XUnmapWindow(dpy, c->win);
garbeam@10 147 XDestroyWindow(dpy, c->title);
garbeam@10 148
garbeam@10 149 for(l=&clients; *l && *l != c; l=&(*l)->next);
garbeam@10 150 eassert(*l == c);
garbeam@10 151 *l = c->next;
garbeam@13 152 for(l=&stack; *l && *l != c; l=&(*l)->snext);
garbeam@13 153 eassert(*l == c);
garbeam@13 154 *l = c->snext;
garbeam@10 155 free(c);
garbeam@10 156
garbeam@10 157 XFlush(dpy);
garbeam@10 158 XSetErrorHandler(error_handler);
garbeam@10 159 XUngrabServer(dpy);
garbeam@18 160 discard_events(EnterWindowMask);
garbeam@14 161 if(stack)
garbeam@14 162 focus(stack);
garbeam@10 163 }
garbeam@10 164
garbeam@10 165
garbeam@9 166 Client *
garbeam@9 167 getclient(Window w)
garbeam@9 168 {
garbeam@9 169 Client *c;
garbeam@9 170 for(c = clients; c; c = c->next)
garbeam@9 171 if(c->win == w)
garbeam@9 172 return c;
garbeam@9 173 return NULL;
garbeam@9 174 }
garbeam@13 175
garbeam@14 176 void
garbeam@14 177 draw_client(Client *c)
garbeam@14 178 {
garbeam@14 179
garbeam@14 180
garbeam@14 181
garbeam@14 182 }