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:
parent
dde2509cdc
commit
9339584771
12
xcompmgr.c
12
xcompmgr.c
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue