From 27ca5f291c49b4fba2faa7479772ecfb1814d666 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 15 Feb 2008 00:55:17 -0500 Subject: [PATCH] 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. --- xcompmgr.c | 119 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 48 deletions(-) diff --git a/xcompmgr.c b/xcompmgr.c index 41cc3bdc..f9d101c1 100644 --- a/xcompmgr.c +++ b/xcompmgr.c @@ -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,