From 5fbfa251ad6e7467cc6501e1fe44cd5d108567f1 Mon Sep 17 00:00:00 2001 From: Marco Peereboom Date: Sun, 4 Oct 2009 21:53:31 +0000 Subject: [PATCH] This fixes most of the stress issues but not all yet. Fucking X sucks. --- scrotwm.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/scrotwm.c b/scrotwm.c index 9055dc7..5c61da0 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -52,7 +52,7 @@ static const char *cvstag = "$scrotwm$"; -#define SWM_VERSION "0.9.9" +#define SWM_VERSION "0.9.10" #include #include @@ -937,14 +937,23 @@ set_win_state(struct ws_win *win, long state) { long data[] = {state, None}; XEvent ev; + XWindowAttributes wa; DNPRINTF(SWM_D_EVENT, "set_win_state: window: %lu\n", win->id); + /* make sure we drain everything */ + XSync(display, True); + + /* make sure we still exist too */ + if (XGetWindowAttributes(display, win->id, &wa) == BadWindow) + return; + XChangeProperty(display, win->id, astate, astate, 32, PropModeReplace, (unsigned char *)data, 2); - if (state != WithdrawnState) - XIfEvent(display, &ev, set_win_notify_cb, (char *)win); + /* wait for completion of XChangeProperty */ + while (XCheckIfEvent(display, &ev, set_win_notify_cb, (char *)win)) + ; } long @@ -1053,14 +1062,25 @@ void unmap_window(struct ws_win *win) { XEvent ev; + XWindowAttributes wa; if (win == NULL) return; + /* make sure we still exist too */ + if (XGetWindowAttributes(display, win->id, &wa) == BadWindow) + return; + + /* don't unmap again */ + if (wa.map_state == IsUnmapped && getstate(win->id) == IconicState) + return; + set_win_state(win, IconicState); XUnmapWindow(display, win->id); - XIfEvent(display, &ev, unmap_window_cb, (char *)win); + /* make sure we wait for XUnmapWindow completion */ + while (XCheckIfEvent(display, &ev, unmap_window_cb, (char *)win)) + ; } void @@ -1201,7 +1221,6 @@ spawn(struct swm_region *r, union arg *args) } exit(0); } - wait(0); } void @@ -3438,15 +3457,22 @@ void unmanage_window(struct ws_win *win) { struct workspace *ws; + XEvent ev; if (win == NULL) return; DNPRINTF(SWM_D_MISC, "unmanage_window: %lu\n", win->id); + set_win_state(win, WithdrawnState); + XSync(display, True); + + /* drain all events for this window, just in case */ + while (XCheckTypedWindowEvent(display, win->id, -1, &ev)) + ; + ws = win->ws; TAILQ_REMOVE(&win->ws->winlist, win, entry); - set_win_state(win, WithdrawnState); if (win->ch.res_class) XFree(win->ch.res_class); if (win->ch.res_name) @@ -3603,6 +3629,8 @@ destroynotify(XEvent *e) DNPRINTF(SWM_D_EVENT, "destroynotify: window %lu\n", ev->window); + XSync(display, True); + SWM_EV_PROLOGUE(display); if ((win = find_window(ev->window)) != NULL) { -- 1.7.10.4