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.
This commit is contained in:
Dana Jansens 2008-02-18 16:44:41 -05:00
parent dde2509cdc
commit 9339584771
1 changed files with 8 additions and 4 deletions

View File

@ -100,6 +100,7 @@ typedef struct _win {
unsigned int opacity; unsigned int opacity;
wintype windowType; wintype windowType;
unsigned long damage_sequence; /* sequence when damage was created */ unsigned long damage_sequence; /* sequence when damage was created */
Bool destroyed;
Bool need_configure; Bool need_configure;
XConfigureEvent queue_configure; XConfigureEvent queue_configure;
@ -779,7 +780,7 @@ find_win (Display *dpy, Window id)
win *w; win *w;
for (w = list; w; w = w->next) for (w = list; w; w = w->next)
if (w->id == id) if (w->id == id && !w->destroyed)
return w; return w;
return 0; return 0;
} }
@ -1513,7 +1514,7 @@ add_win (Display *dpy, Window id, Window prev)
if (prev) if (prev)
{ {
for (p = &list; *p; p = &(*p)->next) for (p = &list; *p; p = &(*p)->next)
if ((*p)->id == prev) if ((*p)->id == prev && !(*p)->destroyed)
break; break;
} }
else else
@ -1553,6 +1554,7 @@ add_win (Display *dpy, Window id, Window prev)
new->shadow_width = 0; new->shadow_width = 0;
new->shadow_height = 0; new->shadow_height = 0;
new->opacity = OPAQUE; new->opacity = OPAQUE;
new->destroyed = False;
new->need_configure = False; new->need_configure = False;
new->borderClip = None; new->borderClip = None;
@ -1586,7 +1588,7 @@ restack_win (Display *dpy, win *w, Window new_above)
/* rehook */ /* rehook */
for (prev = &list; *prev; prev = &(*prev)->next) for (prev = &list; *prev; prev = &(*prev)->next)
{ {
if ((*prev)->id == new_above) if ((*prev)->id == new_above && !(*prev)->destroyed)
break; break;
} }
w->next = *prev; w->next = *prev;
@ -1693,7 +1695,7 @@ finish_destroy_win (Display *dpy, Window id)
win **prev, *w; win **prev, *w;
for (prev = &list; (w = *prev); prev = &w->next) for (prev = &list; (w = *prev); prev = &w->next)
if (w->id == id) if (w->id == id && w->destroyed)
{ {
finish_unmap_win (dpy, w); finish_unmap_win (dpy, w);
*prev = w->next; *prev = w->next;
@ -1733,6 +1735,8 @@ destroy_win (Display *dpy, Window id, Bool fade)
{ {
win *w = find_win (dpy, id); win *w = find_win (dpy, id);
if (w) w->destroyed = True;
#if HAS_NAME_WINDOW_PIXMAP #if HAS_NAME_WINDOW_PIXMAP
if (w && w->pixmap && fade && winTypeFade[w->windowType]) if (w && w->pixmap && fade && winTypeFade[w->windowType])
set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step, set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step,