[PATCH 3/3] xcompmgr: fix window adding with re-used window ids
Forest Bond
forest at alittletooquiet.net
Sat Jun 12 16:29:03 PDT 2010
Hi,
Please disregard this patch. I will resend with adjustments tomorrow. Sorry
for the noise.
Thanks,
Forest
On Sat, Jun 12, 2010 at 06:39:59PM -0400, Forest Bond wrote:
> The X server can re-use window ids once a window has been destroyed.
> However, xcompmgr does not forget about window ids until after the
> window has finished fading out. If a window is destroyed and a new
> window with the same id is added before the first window fades out,
> the new window never appears because xcompmgr has two win structures
> with the same window id and chooses the wrong one to map. This patch
> fixes this problem by tracking which windows have been destroyed and
> looking only at windows that have not been destroyed when matching
> window ids from the server.
>
> Signed-off-by: Forest Bond <forest at alittletooquiet.net>
> ---
> xcompmgr.c | 150 +++++++++++++++++++++++++++++++++++++++--------------------
> 1 files changed, 99 insertions(+), 51 deletions(-)
>
> diff --git a/xcompmgr.c b/xcompmgr.c
> index 47f5667..d25323d 100644
> --- a/xcompmgr.c
> +++ b/xcompmgr.c
> @@ -67,6 +67,7 @@ typedef struct _win {
> Bool usable; /* mapped and all damaged at one point */
> XRectangle damage_bounds; /* bounds of damage */
> #endif
> + int destroyed;
> int mode;
> int damaged;
> Damage damage;
> @@ -156,6 +157,7 @@ static conv *gaussianMap;
>
> #define TRANS_OPACITY 0.75
>
> +#define DEBUG_WINDWS 0
> #define DEBUG_REPAINT 0
> #define DEBUG_EVENTS 0
> #define MONITOR_REPAINT 0
> @@ -751,7 +753,7 @@ find_win (Display *dpy, Window id)
> win *w;
>
> for (w = list; w; w = w->next)
> - if (w->id == id)
> + if ((!w->destroyed) && (w->id == id))
> return w;
> return NULL;
> }
> @@ -948,12 +950,20 @@ paint_all (Display *dpy, XserverRegion region)
> continue;
> #endif
> /* never painted, ignore it */
> - if ((!screen_damaged) && (!w->damaged))
> + if ((!screen_damaged) && (!w->damaged)) {
> +#if DEBUG_REPAINT
> + printf(" [not damaged: 0x%x]", w->id);
> +#endif
> continue;
> + }
> /* if invisible, ignore it */
> if (w->a.x + w->a.width < 1 || w->a.y + w->a.height < 1
> - || w->a.x >= root_width || w->a.y >= root_height)
> + || w->a.x >= root_width || w->a.y >= root_height) {
> +#if DEBUG_REPAINT
> + printf(" [invisible: 0x%x]", w->id);
> +#endif
> continue;
> + }
> if (!w->picture)
> {
> XRenderPictureAttributes pa;
> @@ -974,7 +984,7 @@ paint_all (Display *dpy, XserverRegion region)
> &pa);
> }
> #if DEBUG_REPAINT
> - printf (" 0x%x", w->id);
> + printf (" [painting 0x%x]", w->id);
> #endif
> if (clipChanged)
> {
> @@ -1177,6 +1187,10 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
> {
> win *w = find_win (dpy, id);
>
> +#if DEBUG_WINDOWS
> + printf("map_win: 0x%x\n", w->id);
> +#endif
> +
> if (!w)
> return;
>
> @@ -1202,6 +1216,9 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
> static void
> finish_unmap_win (Display *dpy, win *w)
> {
> +#if DEBUG_WINDOWS
> + printf("finish_unmap_win: 0x%x\n", w->id);
> +#endif
> w->damaged = 0;
> #if CAN_DO_USABLE
> w->usable = False;
> @@ -1263,6 +1280,11 @@ static void
> unmap_win (Display *dpy, Window id, Bool fade)
> {
> win *w = find_win (dpy, id);
> +
> +#if DEBUG_WINDOWS
> + printf("unmap_win: 0x%x\n", w->id);
> +#endif
> +
> if (!w)
> return;
> w->a.map_state = IsUnmapped;
> @@ -1427,12 +1449,16 @@ add_win (Display *dpy, Window id, Window prev)
> win *new = malloc (sizeof (win));
> win **p;
>
> +#if DEBUG_WINDOWS
> + printf("add_win: 0x%x\n", id);
> +#endif
> +
> if (!new)
> return;
> if (prev)
> {
> for (p = &list; *p; p = &(*p)->next)
> - if ((*p)->id == prev)
> + if ((!(*p)->destroyed) && ((*p)->id == prev))
> break;
> }
> else
> @@ -1442,8 +1468,12 @@ add_win (Display *dpy, Window id, Window prev)
> if (!XGetWindowAttributes (dpy, id, &new->a))
> {
> free (new);
> +#if DEBUG_WINDOWS
> + printf("not adding 0x%x: failed to get attributes\n", new->id);
> +#endif
> return;
> }
> + new->destroyed = 0;
> new->damaged = 0;
> #if CAN_DO_USABLE
> new->usable = False;
> @@ -1489,6 +1519,10 @@ restack_win (Display *dpy, win *w, Window new_above)
> {
> Window old_above;
>
> +#if DEBUG_WINDOWS
> + printf("restack_win: 0x%x\n", w->id);
> +#endif
> +
> if (w->next)
> old_above = w->next->id;
> else
> @@ -1506,7 +1540,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)->destroyed) && ((*prev)->id == new_above))
> break;
> }
> w->next = *prev;
> @@ -1597,54 +1631,61 @@ circulate_win (Display *dpy, XCirculateEvent *ce)
> }
>
> static void
> -finish_destroy_win (Display *dpy, Window id, Bool gone)
> +finish_destroy_win (Display *dpy, win *w, Bool gone)
> {
> - win **prev, *w;
> + win *prev;
>
> - for (prev = &list; (w = *prev); prev = &w->next)
> - if (w->id == id)
> - {
> - if (gone)
> - finish_unmap_win (dpy, w);
> - *prev = w->next;
> - if (w->picture)
> - {
> - set_ignore (dpy, NextRequest (dpy));
> - XRenderFreePicture (dpy, w->picture);
> - w->picture = None;
> - }
> - if (w->alphaPict)
> - {
> - XRenderFreePicture (dpy, w->alphaPict);
> - w->alphaPict = None;
> - }
> - if (w->shadowPict)
> - {
> - XRenderFreePicture (dpy, w->shadowPict);
> - w->shadowPict = None;
> - }
> - if (w->shadow)
> - {
> - XRenderFreePicture (dpy, w->shadow);
> - w->shadow = None;
> - }
> - if (w->damage != None)
> - {
> - set_ignore (dpy, NextRequest (dpy));
> - XDamageDestroy (dpy, w->damage);
> - w->damage = None;
> - }
> - cleanup_fade (dpy, w);
> - free (w);
> +#if DEBUG_WINDOWS
> + printf("finish_destroy_win: 0x%x\n", w->id);
> +#endif
> +
> + for (prev = list; prev; prev = prev->next)
> + if (prev->next == w)
> break;
> - }
> +
> + if (! prev)
> + /* Couldn't find the window? */
> + return;
> +
> + if (gone)
> + finish_unmap_win (dpy, w);
> + prev->next = w->next;
> + if (w->picture)
> + {
> + set_ignore (dpy, NextRequest (dpy));
> + XRenderFreePicture (dpy, w->picture);
> + w->picture = None;
> + }
> + if (w->alphaPict)
> + {
> + XRenderFreePicture (dpy, w->alphaPict);
> + w->alphaPict = None;
> + }
> + if (w->shadowPict)
> + {
> + XRenderFreePicture (dpy, w->shadowPict);
> + w->shadowPict = None;
> + }
> + if (w->shadow)
> + {
> + XRenderFreePicture (dpy, w->shadow);
> + w->shadow = None;
> + }
> + if (w->damage != None)
> + {
> + set_ignore (dpy, NextRequest (dpy));
> + XDamageDestroy (dpy, w->damage);
> + w->damage = None;
> + }
> + cleanup_fade (dpy, w);
> + free (w);
> }
>
> #if HAS_NAME_WINDOW_PIXMAP
> static void
> destroy_callback (Display *dpy, win *w, Bool gone)
> {
> - finish_destroy_win (dpy, w->id, gone);
> + finish_destroy_win (dpy, w, gone);
> }
> #endif
>
> @@ -1652,22 +1693,27 @@ static void
> destroy_win (Display *dpy, Window id, Bool gone, Bool fade)
> {
> win *w = find_win (dpy, id);
> +#if DEBUG_WINDOWS
> + printf("destroy_win: 0x%x\n", w->id);
> +#endif
> + w->destroyed = 1;
> #if HAS_NAME_WINDOW_PIXMAP
> if (w && w->pixmap && fade && fadeWindows)
> set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step, destroy_callback, gone, False, True);
> else
> #endif
> {
> - finish_destroy_win (dpy, id, gone);
> + finish_destroy_win (dpy, w, gone);
> }
> }
>
> -/*
> +#if DEBUG_WINDOWS
> static void
> dump_win (win *w)
> {
> - printf ("\t%08lx: %d x %d + %d + %d (%d)\n", w->id,
> - w->a.width, w->a.height, w->a.x, w->a.y, w->a.border_width);
> + printf ("\t%08lx: %d x %d + %d + %d (%d)%s\n", w->id,
> + w->a.width, w->a.height, w->a.x, w->a.y, w->a.border_width,
> + w->destroyed ? " (destroyed)" : "");
> }
>
>
> @@ -1680,7 +1726,7 @@ dump_wins (void)
> for (w = list; w; w = w->next)
> dump_win (w);
> }
> -*/
> +#endif
>
> static void
> damage_win (Display *dpy, XDamageNotifyEvent *de)
> @@ -2128,7 +2174,9 @@ main (int argc, char **argv)
> paint_all (dpy, None);
> for (;;)
> {
> - /* dump_wins (); */
> +#if DEBUG_WINDOWS
> + dump_wins ();
> +#endif
> do {
> if (autoRedirect)
> XFlush (dpy);
> --
> 1.7.0.4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.x.org/archives/xorg-devel/attachments/20100612/33547772/attachment.pgp>
More information about the xorg-devel
mailing list