changed how manage client works
00536204
4 file(s) · +44 −29
| 3 | 3 | * See LICENSE file for license details. |
|
| 4 | 4 | */ |
|
| 5 | 5 | ||
| 6 | + | #include <stdlib.h> |
|
| 6 | 7 | #include <string.h> |
|
| 7 | 8 | #include <X11/Xatom.h> |
|
| 8 | 9 | ||
| 36 | 37 | XFree(name.value); |
|
| 37 | 38 | } |
|
| 38 | 39 | ||
| 39 | - | Client * |
|
| 40 | - | create_client(Window w, XWindowAttributes *wa) |
|
| 40 | + | void |
|
| 41 | + | manage(Window w, XWindowAttributes *wa) |
|
| 41 | 42 | { |
|
| 42 | - | Client *c; |
|
| 43 | + | Client *c, **l; |
|
| 43 | 44 | XSetWindowAttributes twa; |
|
| 44 | 45 | long msize; |
|
| 45 | 46 | ||
| 68 | 69 | DefaultDepth(dpy, screen), CopyFromParent, |
|
| 69 | 70 | DefaultVisual(dpy, screen), |
|
| 70 | 71 | CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); |
|
| 72 | + | ||
| 73 | + | for(l=&clients; *l; l=&(*l)->next); |
|
| 74 | + | c->next = *l; /* *l == nil */ |
|
| 75 | + | *l = c; |
|
| 76 | + | XMapRaised(dpy, c->win); |
|
| 77 | + | XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
|
| 71 | 78 | XFlush(dpy); |
|
| 79 | + | } |
|
| 72 | 80 | ||
| 73 | - | #if 0 |
|
| 74 | - | for(t=&client, i=0; *t; t=&(*t)->next, i++); |
|
| 75 | - | c->next = *t; /* *t == nil */ |
|
| 76 | - | *t = c; |
|
| 77 | - | #endif |
|
| 78 | - | return c; |
|
| 81 | + | static int |
|
| 82 | + | dummy_error_handler(Display *dpy, XErrorEvent *error) |
|
| 83 | + | { |
|
| 84 | + | return 0; |
|
| 79 | 85 | } |
|
| 80 | 86 | ||
| 81 | 87 | void |
|
| 82 | - | manage(Client *c) |
|
| 88 | + | unmanage(Client *c) |
|
| 83 | 89 | { |
|
| 84 | - | XMapRaised(dpy, c->win); |
|
| 85 | - | XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
|
| 90 | + | Client **l; |
|
| 91 | + | ||
| 92 | + | XGrabServer(dpy); |
|
| 93 | + | XSetErrorHandler(dummy_error_handler); |
|
| 94 | + | ||
| 95 | + | XUnmapWindow(dpy, c->win); |
|
| 96 | + | XDestroyWindow(dpy, c->title); |
|
| 97 | + | ||
| 98 | + | for(l=&clients; *l && *l != c; l=&(*l)->next); |
|
| 99 | + | eassert(*l == c); |
|
| 100 | + | *l = c->next; |
|
| 101 | + | free(c); |
|
| 102 | + | ||
| 86 | 103 | XFlush(dpy); |
|
| 104 | + | XSetErrorHandler(error_handler); |
|
| 105 | + | XUngrabServer(dpy); |
|
| 106 | + | /*flush_masked_events(EnterWindowMask); ? */ |
|
| 87 | 107 | } |
|
| 108 | + | ||
| 88 | 109 | ||
| 89 | 110 | Client * |
|
| 90 | 111 | getclient(Window w) |
|
| 159 | 159 | return; |
|
| 160 | 160 | } |
|
| 161 | 161 | ||
| 162 | - | /*if(!client_of_win(ev->window))*/ |
|
| 163 | - | /*manage(create_client(ev->window, &wa));*/ |
|
| 164 | - | XMapRaised(dpy, ev->window); |
|
| 165 | - | XMoveResizeWindow(dpy, ev->window, rect.x, rect.y, rect.width, rect.height - barrect.height); |
|
| 166 | - | XSetInputFocus(dpy, ev->window, RevertToPointerRoot, CurrentTime); |
|
| 167 | - | XFlush(dpy); |
|
| 162 | + | if(!getclient(ev->window)) |
|
| 163 | + | manage(ev->window, &wa); |
|
| 168 | 164 | } |
|
| 169 | 165 | ||
| 170 | 166 | static void |
|
| 185 | 181 | static void |
|
| 186 | 182 | unmapnotify(XEvent *e) |
|
| 187 | 183 | { |
|
| 188 | - | #if 0 |
|
| 189 | 184 | Client *c; |
|
| 190 | 185 | XUnmapEvent *ev = &e->xunmap; |
|
| 191 | 186 | ||
| 192 | - | if((c = client_of_win(ev->window))) |
|
| 193 | - | destroy_client(c); |
|
| 194 | - | #endif |
|
| 187 | + | if((c = getclient(ev->window))) |
|
| 188 | + | unmanage(c); |
|
| 195 | 189 | } |
|
| 20 | 20 | Cursor cursor[CurLast]; |
|
| 21 | 21 | XRectangle rect, barrect; |
|
| 22 | 22 | Bool running = True; |
|
| 23 | - | Client *clients = NULL; |
|
| 24 | 23 | ||
| 25 | 24 | char *bartext, tag[256]; |
|
| 26 | 25 | int screen, sel_screen; |
|
| 27 | 26 | ||
| 28 | - | /* draw structs */ |
|
| 29 | 27 | Brush brush = {0}; |
|
| 28 | + | Client *clients = NULL; |
|
| 30 | 29 | ||
| 31 | 30 | enum { WM_PROTOCOL_DELWIN = 1 }; |
|
| 32 | 31 | ||
| 33 | 32 | static Bool other_wm_running; |
|
| 34 | - | static int (*x_error_handler) (Display *, XErrorEvent *); |
|
| 35 | 33 | static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; |
|
| 34 | + | static int (*x_error_handler) (Display *, XErrorEvent *); |
|
| 36 | 35 | ||
| 37 | 36 | static void |
|
| 38 | 37 | usage() |
|
| 56 | 55 | if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) |
|
| 57 | 56 | continue; |
|
| 58 | 57 | if(wa.map_state == IsViewable) |
|
| 59 | - | manage(create_client(wins[i], &wa)); |
|
| 58 | + | manage(wins[i], &wa); |
|
| 60 | 59 | } |
|
| 61 | 60 | } |
|
| 62 | 61 | if(wins) |
|
| 69 | 68 | * Other types of errors call Xlib's default error handler, which |
|
| 70 | 69 | * calls exit(). |
|
| 71 | 70 | */ |
|
| 72 | - | static int |
|
| 71 | + | int |
|
| 73 | 72 | error_handler(Display *dpy, XErrorEvent *error) |
|
| 74 | 73 | { |
|
| 75 | 74 | if(error->error_code == BadWindow |
|
| 65 | 65 | extern void quit(char *arg); |
|
| 66 | 66 | ||
| 67 | 67 | /* client.c */ |
|
| 68 | - | extern Client *create_client(Window w, XWindowAttributes *wa); |
|
| 69 | - | extern void manage(Client *c); |
|
| 68 | + | extern void manage(Window w, XWindowAttributes *wa); |
|
| 69 | + | void unmanage(Client *c); |
|
| 70 | 70 | extern Client * getclient(Window w); |
|
| 71 | 71 | ||
| 72 | 72 | /* key.c */ |
|
| 74 | 74 | extern void keypress(XEvent *e); |
|
| 75 | 75 | ||
| 76 | 76 | /* wm.c */ |
|
| 77 | + | extern int error_handler(Display *dpy, XErrorEvent *error); |
|