From 93395847717133d0210877a1efa4f18ab632293b Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 18 Feb 2008 16:44:41 -0500 Subject: [PATCH] Fix races that occur when a window id is destroyed and recreated very quickly. This behaviour happens when restarting the window manager. Don't use windows that are destroyed when restacking other windows or when handling events on a window id. It is possible for the same window id to appear in the window list multiple times if it is destroyed then created before the destroy fade-out completes. --- xcompmgr.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/xcompmgr.c b/xcompmgr.c index 291624b..276d1bd 100644 --- a/xcompmgr.c +++ b/xcompmgr.c @@ -100,6 +100,7 @@ typedef struct _win { unsigned int opacity; wintype windowType; unsigned long damage_sequence; /* sequence when damage was created */ + Bool destroyed; Bool need_configure; XConfigureEvent queue_configure; @@ -779,7 +780,7 @@ find_win (Display *dpy, Window id) win *w; for (w = list; w; w = w->next) - if (w->id == id) + if (w->id == id && !w->destroyed) return w; return 0; } @@ -1513,7 +1514,7 @@ add_win (Display *dpy, Window id, Window prev) if (prev) { for (p = &list; *p; p = &(*p)->next) - if ((*p)->id == prev) + if ((*p)->id == prev && !(*p)->destroyed) break; } else @@ -1553,6 +1554,7 @@ add_win (Display *dpy, Window id, Window prev) new->shadow_width = 0; new->shadow_height = 0; new->opacity = OPAQUE; + new->destroyed = False; new->need_configure = False; new->borderClip = None; @@ -1586,7 +1588,7 @@ restack_win (Display *dpy, win *w, Window new_above) /* rehook */ for (prev = &list; *prev; prev = &(*prev)->next) { - if ((*prev)->id == new_above) + if ((*prev)->id == new_above && !(*prev)->destroyed) break; } w->next = *prev; @@ -1693,7 +1695,7 @@ finish_destroy_win (Display *dpy, Window id) win **prev, *w; for (prev = &list; (w = *prev); prev = &w->next) - if (w->id == id) + if (w->id == id && w->destroyed) { finish_unmap_win (dpy, w); *prev = w->next; @@ -1733,6 +1735,8 @@ destroy_win (Display *dpy, Window id, Bool fade) { win *w = find_win (dpy, id); + if (w) w->destroyed = True; + #if HAS_NAME_WINDOW_PIXMAP if (w && w->pixmap && fade && winTypeFade[w->windowType]) set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step, -- 1.9.1