[PATCH] Supporting pretty window destory effects in metacity-clutter

Robert Bragg robert at sixbynine.org
Thu Oct 23 11:14:09 PDT 2008


I have been investigating some composite manager (metacity-clutter)
issues that have been plaguing us for a while which revolve around us
implementing window destroy effects:

Basically when the CM knows that an app is being destroyed we want to
run an effect that uses the window pixmap as a texture on some geometry
that gets scaled down to a thin line. (think old style TV power off)

We have been struggling with reliably detecting when the window is being
destroyed such that the pixmap is still in a consistent state.

If an application is asked to close then it is free to close the windows
in any order it likes, and in closing various sub windows the app can
cause lots of damage events to its top level window. The CM receives the
damage events and updates its corresponding tfp. It can't distinguish
them from normal damage because it hasn't yet received any notification
that the top level window is being destroyed.

There is another case though where the application is forcefully closed
and does not control the order in which windows are destroyed. If an app
is killed then control moves to the server:

In the server:
CloseDownClient() ends up calling FreeClientResources() which involves
deleting all the windows of that client. Notably they also seem to be
deleted in no particular order, and that causes the same problem
described above.

To try and solve this I changed the way that exposures are handled in
the dix UnmapWindow. (Note UnmapWindow always gets called by
DeleteWindow) I changed it so that it never deals with exposures if the
clientState == ClientStateGone and the parent of the window being
unmapped belongs to the same client.

The end result is that no damage is generated until after sending the
unmap notify of the applications top level window.

I have tested that the following patch seems to fix the destroy window
effects for the cases where the xserver is responsible for destroying
the windows, and would be interested to get some feedback from someone
more familiar with the X server dix code.

kind regards,
- Robert

diff --git a/dix/window.c b/dix/window.c
index a780d64..31423a8 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -3061,8 +3061,16 @@ UnmapWindow(WindowPtr pWin, Bool fromConfigure)
        if (!fromConfigure)
-           (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
-           (*pScreen->HandleExposures)(pLayerWin->parent);
+            ClientPtr client = wClient (pLayerWin);
+            /* If a Client is in the process of being destroyed, then we dont
+             * deal with exposures for windows also belonging to the client */
+            if (client->clientState != ClientStateGone
+                || client != wClient (pLayerWin->parent))
+            {
+                (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+                (*pScreen->HandleExposures)(pLayerWin->parent);
+            }
        if (DO_SAVE_UNDERS(pWin))
Robert Bragg, Intel Open Source Technology Center

More information about the xorg mailing list