changed how manage client works
Anselm R. Garbe garbeam@wmii.de
Tue, 11 Jul 2006 13:02:22 +0200
M
client.c
→
client.c
@@ -3,6 +3,7 @@ * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. */ +#include <stdlib.h> #include <string.h> #include <X11/Xatom.h>@@ -36,10 +37,10 @@ }
XFree(name.value); } -Client * -create_client(Window w, XWindowAttributes *wa) +void +manage(Window w, XWindowAttributes *wa) { - Client *c; + Client *c, **l; XSetWindowAttributes twa; long msize;@@ -68,23 +69,43 @@ c->r[RFloat].width, barrect.height, 0,
DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); + + for(l=&clients; *l; l=&(*l)->next); + c->next = *l; /* *l == nil */ + *l = c; + XMapRaised(dpy, c->win); + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); XFlush(dpy); +} -#if 0 - for(t=&client, i=0; *t; t=&(*t)->next, i++); - c->next = *t; /* *t == nil */ - *t = c; -#endif - return c; +static int +dummy_error_handler(Display *dpy, XErrorEvent *error) +{ + return 0; } void -manage(Client *c) +unmanage(Client *c) { - XMapRaised(dpy, c->win); - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + Client **l; + + XGrabServer(dpy); + XSetErrorHandler(dummy_error_handler); + + XUnmapWindow(dpy, c->win); + XDestroyWindow(dpy, c->title); + + for(l=&clients; *l && *l != c; l=&(*l)->next); + eassert(*l == c); + *l = c->next; + free(c); + XFlush(dpy); + XSetErrorHandler(error_handler); + XUngrabServer(dpy); + /*flush_masked_events(EnterWindowMask); ? */ } + Client * getclient(Window w)
M
event.c
→
event.c
@@ -159,12 +159,8 @@ (StructureNotifyMask | PropertyChangeMask));
return; } - /*if(!client_of_win(ev->window))*/ - /*manage(create_client(ev->window, &wa));*/ - XMapRaised(dpy, ev->window); - XMoveResizeWindow(dpy, ev->window, rect.x, rect.y, rect.width, rect.height - barrect.height); - XSetInputFocus(dpy, ev->window, RevertToPointerRoot, CurrentTime); - XFlush(dpy); + if(!getclient(ev->window)) + manage(ev->window, &wa); } static void@@ -185,11 +181,9 @@
static void unmapnotify(XEvent *e) { -#if 0 Client *c; XUnmapEvent *ev = &e->xunmap; - if((c = client_of_win(ev->window))) - destroy_client(c); -#endif + if((c = getclient(ev->window))) + unmanage(c); }
M
wm.c
→
wm.c
@@ -20,19 +20,18 @@ Atom net_atom[NetLast];
Cursor cursor[CurLast]; XRectangle rect, barrect; Bool running = True; -Client *clients = NULL; char *bartext, tag[256]; int screen, sel_screen; -/* draw structs */ Brush brush = {0}; +Client *clients = NULL; enum { WM_PROTOCOL_DELWIN = 1 }; static Bool other_wm_running; -static int (*x_error_handler) (Display *, XErrorEvent *); static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; +static int (*x_error_handler) (Display *, XErrorEvent *); static void usage()@@ -56,7 +55,7 @@ continue;
if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) continue; if(wa.map_state == IsViewable) - manage(create_client(wins[i], &wa)); + manage(wins[i], &wa); } } if(wins)@@ -69,7 +68,7 @@ * those cases are ignored (especially on UnmapNotify's).
* Other types of errors call Xlib's default error handler, which * calls exit(). */ -static int +int error_handler(Display *dpy, XErrorEvent *error) { if(error->error_code == BadWindow
M
wm.h
→
wm.h
@@ -65,8 +65,8 @@ extern void run(char *arg);
extern void quit(char *arg); /* client.c */ -extern Client *create_client(Window w, XWindowAttributes *wa); -extern void manage(Client *c); +extern void manage(Window w, XWindowAttributes *wa); +void unmanage(Client *c); extern Client * getclient(Window w); /* key.c */@@ -74,3 +74,4 @@ extern void update_keys();
extern void keypress(XEvent *e); /* wm.c */ +extern int error_handler(Display *dpy, XErrorEvent *error);