Save ConfigureNotify events for unmapped windows until the window maps. If a window moves while it is unmapped, it should not affect its fade-out.

A window can move/resize while it is fading out.  Even if you don't delete the pixmap in that case, the fade-out will be shown in the wrong place and the wrong area on screen will be marked damaged when the window is gone without this patch.
This commit is contained in:
Dana Jansens 2008-02-15 00:55:17 -05:00
parent db45bafdc4
commit 27ca5f291c
1 changed files with 71 additions and 48 deletions

View File

@ -101,6 +101,9 @@ typedef struct _win {
wintype windowType;
unsigned long damage_sequence; /* sequence when damage was created */
Bool need_configure;
XConfigureEvent queue_configure;
/* for drawing translucent windows */
XserverRegion borderClip;
struct _win *prev_trans;
@ -1280,6 +1283,9 @@ determine_wintype (Display *dpy, Window w, Window top)
static unsigned int
get_opacity_prop (Display *dpy, win *w, unsigned int def);
static void
configure_win (Display *dpy, XConfigureEvent *ce);
static void
map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
{
@ -1289,19 +1295,18 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
return;
w->a.map_state = IsViewable;
/* This needs to be here or else we lose transparency messages */
XSelectInput (dpy, id, PropertyChangeMask);
/* This needs to be here since we don't get PropertyNotify when unmapped */
w->opacity = get_opacity_prop (dpy, w, OPAQUE);
determine_mode (dpy, w);
w->windowType = determine_wintype (dpy, w->id, w->id);
#if 0
printf("window 0x%x type %s\n", w->id, wintype_name(w->windowType));
#endif
/* select before reading the property so that no property changes are lost */
XSelectInput (dpy, id, PropertyChangeMask);
w->opacity = get_opacity_prop (dpy, w, OPAQUE);
determine_mode (dpy, w);
#if CAN_DO_USABLE
w->damage_bounds.x = w->damage_bounds.y = 0;
w->damage_bounds.width = w->damage_bounds.height = 0;
@ -1310,6 +1315,11 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
if (fade && winTypeFade[w->windowType])
set_fade (dpy, w, 0, get_opacity_percent (dpy, w), fade_in_step, 0, True, True);
/* if any configure events happened while the window was unmapped, then
configure the window to its correct place */
if (w->need_configure)
configure_win (dpy, &w->queue_configure);
}
static void
@ -1340,10 +1350,6 @@ finish_unmap_win (Display *dpy, win *w)
w->picture = None;
}
/* don't care about properties anymore */
set_ignore (dpy, NextRequest (dpy));
XSelectInput(dpy, w->id, 0);
if (w->borderSize)
{
set_ignore (dpy, NextRequest (dpy));
@ -1379,6 +1385,11 @@ unmap_win (Display *dpy, Window id, Bool fade)
if (!w)
return;
w->a.map_state = IsUnmapped;
/* don't care about properties anymore */
set_ignore (dpy, NextRequest (dpy));
XSelectInput(dpy, w->id, 0);
#if HAS_NAME_WINDOW_PIXMAP
if (w->pixmap && fade && winTypeFade[w->windowType])
set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step, unmap_callback, False, True);
@ -1526,6 +1537,7 @@ add_win (Display *dpy, Window id, Window prev)
new->shadow_width = 0;
new->shadow_height = 0;
new->opacity = OPAQUE;
new->need_configure = False;
new->borderClip = None;
new->prev_trans = 0;
@ -1586,50 +1598,59 @@ configure_win (Display *dpy, XConfigureEvent *ce)
}
return;
}
if (w->a.map_state == IsUnmapped) {
/* save the configure event for when the window maps */
w->need_configure = True;
w->queue_configure = *ce;
}
else {
w->need_configure = False;
#if CAN_DO_USABLE
if (w->usable)
if (w->usable)
#endif
{
damage = XFixesCreateRegion (dpy, 0, 0);
if (w->extents != None)
XFixesCopyRegion (dpy, damage, w->extents);
}
w->a.x = ce->x;
w->a.y = ce->y;
/* Only destroy the pixmap if the window is mapped */
if (w->a.map_state != IsUnmapped &&
(w->a.width != ce->width || w->a.height != ce->height))
{
{
damage = XFixesCreateRegion (dpy, 0, 0);
if (w->extents != None)
XFixesCopyRegion (dpy, damage, w->extents);
}
w->a.x = ce->x;
w->a.y = ce->y;
if (w->a.width != ce->width || w->a.height != ce->height)
{
#if HAS_NAME_WINDOW_PIXMAP
if (w->pixmap)
{
XFreePixmap (dpy, w->pixmap);
w->pixmap = None;
if (w->picture)
{
XRenderFreePicture (dpy, w->picture);
w->picture = None;
}
}
if (w->pixmap)
{
XFreePixmap (dpy, w->pixmap);
w->pixmap = None;
if (w->picture)
{
XRenderFreePicture (dpy, w->picture);
w->picture = None;
}
}
#endif
if (w->shadow)
{
XRenderFreePicture (dpy, w->shadow);
w->shadow = None;
}
if (w->shadow)
{
XRenderFreePicture (dpy, w->shadow);
w->shadow = None;
}
}
w->a.width = ce->width;
w->a.height = ce->height;
w->a.border_width = ce->border_width;
if (w->a.map_state != IsUnmapped && damage)
{
XserverRegion extents = win_extents (dpy, w);
XFixesUnionRegion (dpy, damage, damage, extents);
XFixesDestroyRegion (dpy, extents);
add_damage (dpy, damage);
}
}
w->a.width = ce->width;
w->a.height = ce->height;
w->a.border_width = ce->border_width;
w->a.override_redirect = ce->override_redirect;
restack_win (dpy, w, ce->above);
if (w->a.map_state != IsUnmapped && damage)
{
XserverRegion extents = win_extents (dpy, w);
XFixesUnionRegion (dpy, damage, damage, extents);
XFixesDestroyRegion (dpy, extents);
add_damage (dpy, damage);
}
clipChanged = True;
}
@ -1676,6 +1697,7 @@ finish_destroy_win (Display *dpy, Window id)
XDamageDestroy (dpy, w->damage);
w->damage = None;
}
cleanup_fade (dpy, w);
free (w);
break;
@ -1694,6 +1716,7 @@ static void
destroy_win (Display *dpy, Window id, Bool fade)
{
win *w = find_win (dpy, id);
#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,