File plugins-main-NOMAD.diff of Package compiz-fusion-plugins-main

diff --git a/src/animation/animation.c b/src/animation/animation.c
index c2bde8b..232f8b9 100644
--- a/src/animation/animation.c
+++ b/src/animation/animation.c
@@ -325,11 +325,27 @@ animRemoveExtension (CompScreen *s,
 
     // Stop all ongoing animations
     CompWindow *w;
-    for (w = s->windows; w; w = w->next)
+
+    w = s->root.windows;
+    for (;;)
     {
 	ANIM_WINDOW (w);
 	if (aw->com.curAnimEffect != AnimEffectNone)
 	    postAnimationCleanup (w);
+
+	if (w->windows)
+	{
+	    w = w->windows;
+	    continue;
+	}
+
+	while (!w->next && (w != &s->root))
+	    w = w->parent;
+	    
+	if (w == &s->root)
+	    break;
+
+	w = w->next;
     }
 
     int p;
@@ -998,6 +1014,8 @@ compTransformUpdateBB (CompOutput *output,
 static void
 damageBoundingBox (CompWindow * w)
 {
+    CompWindow *p;
+
     ANIM_WINDOW(w);
 
     if (aw->BB.x1 == MAXSHORT) // unintialized BB
@@ -1023,6 +1041,9 @@ damageBoundingBox (CompWindow * w)
     rect.height = lastBB->y2 - lastBB->y1 + 2;
     XUnionRectWithRegion (&rect, regionToDamage, regionToDamage);
 
+    for (p = w->parent; p != &w->screen->root; p = p->parent)
+	XOffsetRegion (regionToDamage, p->attrib.x, p->attrib.y);
+
     damageScreenRegion (w->screen, regionToDamage);
 }
 
@@ -1033,7 +1054,7 @@ Bool getMousePointerXY(CompScreen * s, short *x, short *y)
     unsigned int m;
 
     if (XQueryPointer
-	(s->display->display, s->root, &w1, &w2, &xj, &yj, &xp, &yp, &m))
+	(s->display->display, s->root.id, &w1, &w2, &xj, &yj, &xp, &yp, &m))
     {
 	*x = xp;
 	*y = yp;
@@ -1543,7 +1564,7 @@ static void postAnimationCleanupCustom (CompWindow * w,
     if (aw->com.curAnimEffect == AnimEffectFocusFade)
     {
 	CompWindow *w2;
-	for (w2 = w->screen->windows; w2; w2 = w2->next)
+	for (w2 = w->parent->windows; w2; w2 = w2->next)
 	{
 	    AnimWindow *aw2;
 
@@ -1715,7 +1736,7 @@ animActivateEvent (CompScreen *s,
 
     o[0].type = CompOptionTypeInt;
     o[0].name = "root";
-    o[0].value.i = s->root;
+    o[0].value.i = s->root.id;
 
     o[1].type = CompOptionTypeBool;
     o[1].name = "active";
@@ -2081,7 +2102,8 @@ restackInfoStillGood(CompScreen *s, RestackInfo *restackInfo)
     Bool wRestackedGood = FALSE;
 
     CompWindow *w;
-    for (w = s->windows; w; w = w->next)
+    w = s->root.windows;
+    for (;;)
     {
 	if (restackInfo->wStart == w && isWinVisible(w))
 	    wStartGood = TRUE;
@@ -2091,7 +2113,22 @@ restackInfoStillGood(CompScreen *s, RestackInfo *restackInfo)
 	    wRestackedGood = TRUE;
 	if (restackInfo->wOldAbove == w && isWinVisible(w))
 	    wOldAboveGood = TRUE;
+
+	if (w->windows)
+	{
+	    w = w->windows;
+	    continue;
+	}
+
+	while (!w->next && (w != &s->root))
+	    w = w->parent;
+	    
+	if (w == &s->root)
+	    break;
+
+	w = w->next;
     }
+
     return (wStartGood && wEndGood && wOldAboveGood && wRestackedGood);
 }
 
@@ -2100,7 +2137,8 @@ static void
 resetStackingInfo (CompScreen *s)
 {
     CompWindow *w;
-    for (w = s->windows; w; w = w->next)
+    w = s->root.windows;
+    for (;;)
     {
 	ANIM_WINDOW (w);
 
@@ -2110,6 +2148,20 @@ resetStackingInfo (CompScreen *s)
 	    free (aw->restackInfo);
 	    aw->restackInfo = NULL;
 	}
+
+	if (w->windows)
+	{
+	    w = w->windows;
+	    continue;
+	}
+
+	while (!w->next && (w != &s->root))
+	    w = w->parent;
+	    
+	if (w == &s->root)
+	    break;
+
+	w = w->next;
     }
 }
 
@@ -2173,7 +2225,9 @@ static void animPreparePaintScreen(CompScreen * s, int msSinceLastPaint)
 	  now: C0001B 36000A5 3205B63 1E0000C 1E00050 1E0005B 600003 
 	*/
 	CompWindow *wOldAbove = NULL;
-	for (w = s->windows; w; w = w->next)
+
+	w = s->root.windows;
+	for (;;)
 	{
 	    ANIM_WINDOW(w);
 	    if (aw->restackInfo)
@@ -2198,10 +2252,26 @@ static void animPreparePaintScreen(CompScreen * s, int msSinceLastPaint)
 			aw->restackInfo->wOldAbove = wOldAbove;
 		}
 	    }
+
+	    if (w->windows)
+	    {
+		w = w->windows;
+		continue;
+	    }
+
+	    while (!w->next && (w != &s->root))
+	    	w = w->parent;
+	    
+	    if (w == &s->root)
+		break;
+
+	    w = w->next;
 	}
+	
 	// do in reverse order so that focus-fading chains are handled
 	// properly
-	for (w = s->reverseWindows; w; w = w->prev)
+	w = s->root.reverseWindows;
+	for (;;)
 	{
 	    ANIM_WINDOW(w);
 	    if (aw->restackInfo)
@@ -2259,27 +2329,56 @@ static void animPreparePaintScreen(CompScreen * s, int msSinceLastPaint)
 		}
 		initiateFocusAnimation(w);
 	    }
+
+	    if (w->reverseWindows)
+	    {
+		w = w->reverseWindows;
+		continue;
+	    }
+
+	    while (!w->prev && (w != &s->root))
+	    	w = w->parent;
+	    
+	    if (w == &s->root)
+		break;
+
+	    w = w->prev;
 	}
 
-	for (w = s->reverseWindows; w; w = w->prev)
+	w = s->root.reverseWindows;
+	for (;;)
 	{
 	    ANIM_WINDOW(w);
+	    if (aw->isDodgeSubject)
+	    {
+		Bool dodgersAreOnlySubjects = TRUE;
+		CompWindow *dw;
+		AnimWindow *adw;
+		for (dw = aw->dodgeChainStart; dw; dw = adw->dodgeChainNext)
+		{
+		    adw = GET_ANIM_WINDOW(dw, as);
+		    if (!adw)
+			break;
+		    if (!adw->isDodgeSubject)
+			dodgersAreOnlySubjects = FALSE;
+		}
+		if (dodgersAreOnlySubjects)
+		    aw->skipPostPrepareScreen = TRUE;
+	    }
 
-	    if (!aw->isDodgeSubject)
-		continue;
-	    Bool dodgersAreOnlySubjects = TRUE;
-	    CompWindow *dw;
-	    AnimWindow *adw;
-	    for (dw = aw->dodgeChainStart; dw; dw = adw->dodgeChainNext)
+	    if (w->reverseWindows)
 	    {
-		adw = GET_ANIM_WINDOW(dw, as);
-		if (!adw)
-		    break;
-		if (!adw->isDodgeSubject)
-		    dodgersAreOnlySubjects = FALSE;
+		w = w->reverseWindows;
+		continue;
 	    }
-	    if (dodgersAreOnlySubjects)
-		aw->skipPostPrepareScreen = TRUE;
+
+	    while (!w->prev && (w != &s->root))
+	    	w = w->parent;
+	    
+	    if (w == &s->root)
+		break;
+
+	    w = w->prev;
 	}
     }
 	
@@ -2288,7 +2387,8 @@ static void animPreparePaintScreen(CompScreen * s, int msSinceLastPaint)
 	AnimWindow *aw;
 	Bool animStillInProgress = FALSE;
 
-	for (w = s->windows; w; w = w->next)
+	w = s->root.windows;
+	for (;;)
 	{
 	    aw = GET_ANIM_WINDOW(w, as);
 
@@ -2374,9 +2474,24 @@ static void animPreparePaintScreen(CompScreen * s, int msSinceLastPaint)
 		aw->com.curWindowEvent = WindowEventNone;
 		aw->com.curAnimEffect = AnimEffectNone;
 	    }
+
+	    if (w->windows)
+	    {
+		w = w->windows;
+		continue;
+	    }
+
+	    while (!w->next && (w != &s->root))
+	    	w = w->parent;
+	    
+	    if (w == &s->root)
+		break;
+
+	    w = w->next;
 	}
 
-	for (w = s->windows; w; w = w->next)
+	w = s->root.windows;
+	for (;;)
 	{
 	    aw = GET_ANIM_WINDOW(w, as);
 	    if (aw && aw->com.curAnimEffect->properties.
@@ -2384,6 +2499,20 @@ static void animPreparePaintScreen(CompScreen * s, int msSinceLastPaint)
 	    {
 		aw->com.curAnimEffect->properties.postPrepPaintScreenFunc (w);
 	    }
+
+	    if (w->windows)
+	    {
+		w = w->windows;
+		continue;
+	    }
+
+	    while (!w->next && (w != &s->root))
+	    	w = w->parent;
+	    
+	    if (w == &s->root)
+		break;
+
+	    w = w->next;
 	}
 
 	if (!animStillInProgress)
@@ -3118,10 +3247,10 @@ getBottommostInFocusChain (CompWindow *w)
 }
 
 static void
-resetWalkerMarks (CompScreen *s)
+resetWalkerMarks (CompWindow *parent)
 {
     CompWindow *w;
-    for (w = s->windows; w; w = w->next)
+    for (w = parent->windows; w; w = w->next)
     {
 	ANIM_WINDOW(w);
 	aw->walkerOverNewCopy = FALSE;
@@ -3130,13 +3259,13 @@ resetWalkerMarks (CompScreen *s)
 }
 
 static CompWindow*
-animWalkFirst (CompScreen *s)
+animWalkFirst (CompWindow *parent)
 {
-    ANIM_SCREEN (s);
+    ANIM_SCREEN (parent->screen);
 
-    resetWalkerMarks (s);
+    resetWalkerMarks (parent);
 
-    CompWindow *w = getBottommostInFocusChain(s->windows);
+    CompWindow *w = getBottommostInFocusChain(parent->windows);
     if (w)
     {
 	AnimWindow *aw = GET_ANIM_WINDOW (w, as);
@@ -3146,13 +3275,13 @@ animWalkFirst (CompScreen *s)
 }
 
 static CompWindow*
-animWalkLast (CompScreen *s)
+animWalkLast (CompWindow *parent)
 {
-    ANIM_SCREEN (s);
+    ANIM_SCREEN (parent->screen);
 
-    resetWalkerMarks (s);
+    resetWalkerMarks (parent);
 
-    CompWindow *w = s->reverseWindows;
+    CompWindow *w = parent->reverseWindows;
     if (w)
     {
 	AnimWindow *aw = GET_ANIM_WINDOW (w, as);
@@ -3259,12 +3388,13 @@ animWalkPrev (CompWindow *w)
 
 static void
 animInitWindowWalker (CompScreen *s,
+		      CompWindow *w,
 		      CompWalker *walker)
 {
     ANIM_SCREEN (s);
 
     UNWRAP (as, s, initWindowWalker);
-    (*s->initWindowWalker) (s, walker);
+    (*s->initWindowWalker) (s, w, walker);
     WRAP (as, s, initWindowWalker, animInitWindowWalker);
 
     if (as->walkerAnimCount > 0) // only walk if necessary
@@ -3717,7 +3847,7 @@ static void animHandleEvent(CompDisplay * d, XEvent * event)
     {
 	XConfigureEvent *ce = &event->xconfigure;
 	w = findWindowAtDisplay (d, ce->window);
-	if (!w)
+	if (!w || !w->parent)
 	    break;
 	if (w->prev)
 	{
@@ -3823,7 +3953,7 @@ static void animHandleEvent(CompDisplay * d, XEvent * event)
 		    onlyTwo = TRUE;
 		}
 		// Clear all configureNotified's
-		for (w2 = s->windows; w2; w2 = w2->next)
+		for (w2 = w->parent->windows; w2; w2 = w2->next)
 		{
 		    AnimWindow *aw2 = GET_ANIM_WINDOW(w2, as);
 		    aw2->configureNotified = FALSE;
@@ -4254,7 +4384,9 @@ animWindowMoveNotify(CompWindow * w, int dx, int dy, Bool immediate)
 		if (as->animInProgress)
 		{
 		    Bool animStillInProgress = FALSE;
-		    for (w2 = w->screen->windows; w2; w2 = w2->next)
+
+		    w2 = w->screen->root.windows;
+		    for (;;)
 		    {
 			AnimWindow *aw2;
 
@@ -4264,6 +4396,20 @@ animWindowMoveNotify(CompWindow * w, int dx, int dy, Bool immediate)
 			    animStillInProgress = TRUE;
 			    break;
 			}
+
+			if (w2->windows)
+			{
+			    w2 = w2->windows;
+			    continue;
+			}
+
+			while (!w2->next && (w2 != &w->screen->root))
+			    w2 = w2->parent;
+
+			if (w2 == &w->screen->root)
+			    break;
+
+			w2 = w2->next;
 		    }
 
 		    if (!animStillInProgress)
@@ -4353,10 +4499,25 @@ animPaintOutput(CompScreen * s,
 	if (as->markAllWinCreatedCountdown == 1)
 	{
 	    // Mark all windows as "created"
-	    for (w = s->windows; w; w = w->next)
+	    w = s->root.windows;
+	    for (;;)
 	    {
 		ANIM_WINDOW(w);
 		aw->created = TRUE;
+
+		if (w->windows)
+		{
+		    w = w->windows;
+		    continue;
+		}
+
+		while (!w->next && (w != &s->root))
+		    w = w->parent;
+	    
+		if (w == &s->root)
+		    break;
+
+		w = w->next;
 	    }
 	}
 	as->markAllWinCreatedCountdown--;
diff --git a/src/colorfilter/colorfilter.c b/src/colorfilter/colorfilter.c
index f7674d1..4a94e45 100644
--- a/src/colorfilter/colorfilter.c
+++ b/src/colorfilter/colorfilter.c
@@ -135,6 +135,10 @@ colorFilterToggleWindow (CompWindow * w)
 
     /* Ensure window is going to be repainted */
     addWindowDamage (w);
+
+    /* toggle child windows */
+    for (w = w->windows; w; w = w->next)
+	colorFilterToggleWindow (w);
 }
 
 /*
@@ -151,7 +155,7 @@ colorFilterToggleScreen (CompScreen * s)
     cfs->isFiltered = !cfs->isFiltered;
 
     /* Toggle filtering for every window */
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
 	if (w)
 	    colorFilterToggleWindow (w);
 }
@@ -190,7 +194,7 @@ colorFilterSwitchFilter (CompScreen * s)
     }
 
     /* Damage currently filtered windows */
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
     {
 	FILTER_WINDOW (w);
 	if (cfw->isFiltered)
@@ -348,7 +352,7 @@ loadFilters (CompScreen *s, CompTexture *texture)
 	cfs->filtersCount = 0;
 
     /* Damage currently filtered windows */
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
     {
 	FILTER_WINDOW (w);
 	if (cfw->isFiltered)
@@ -422,14 +426,24 @@ colorFilterDrawWindowTexture (CompWindow *w, CompTexture *texture,
  * Filter windows when they are open if they match the filtering rules
  */
 static void
-colorFilterWindowAdd (CompScreen *s,
+colorFilterWindowAdd (CompObject *parent,
 		      CompWindow *w)
 {
-    FILTER_SCREEN (s);
+    Bool isFiltered = FALSE;
+
+    FILTER_SCREEN (w->screen);
 
     /* cfw->isFiltered is initialized to FALSE in InitWindow, so we only
        have to toggle it to TRUE if necessary */
-    if (cfs->isFiltered && matchEval (colorfilterGetFilterMatch (s), w))
+    if (w->parent)
+    {
+	if (w->parent == &w->screen->root)
+	    isFiltered = cfs->isFiltered;
+	else
+	    isFiltered = GET_FILTER_WINDOW (w->parent, cfs)->isFiltered;
+    }
+
+    if (isFiltered && matchEval (colorfilterGetFilterMatch (w->screen), w))
 	colorFilterToggleWindow (w);
 }
 
@@ -447,7 +461,7 @@ colorFilterMatchsChanged (CompScreen *s, CompOption *opt,
     FILTER_SCREEN (s);
 
     /* Re-check every window against new match settings */
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
     {
 	FILTER_WINDOW (w);
 	if (matchEval (colorfilterGetFilterMatch (s), w) &&
@@ -470,7 +484,7 @@ colorFilterExcludeMatchsChanged (CompScreen *s, CompOption *opt,
     FILTER_SCREEN (s);
 
     /* Re-check every window against new match settings */
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
     {
 	Bool isExcluded;
 
diff --git a/src/expo/expo.c b/src/expo/expo.c
index 46fa27b..7357755 100644
--- a/src/expo/expo.c
+++ b/src/expo/expo.c
@@ -272,7 +272,7 @@ expoDnDFini (CompDisplay     *d,
     {
     	EXPO_SCREEN (s);
 
-	if (xid && (s->root != xid))
+	if (xid && (s->root.id != xid))
 	    continue;
 
 	if (es->dndState == DnDDuring || es->dndState == DnDStart)
@@ -641,7 +641,8 @@ invertTransformedVertex (CompScreen              *s,
 
     alpha = -p1[2] / v[2];
 
-    if (expoGetDeform (s->display) == DeformCurve && s->desktopWindowCount)
+    if (expoGetDeform (s->display) == DeformCurve &&
+	s->root.desktopWindowCount)
     {
 	const float sws = s->width * s->width;
 	const float rs = (es->curveDistance * es->curveDistance) + 0.25;
@@ -1259,7 +1260,7 @@ expoAddWindowGeometry (CompWindow *w,
     EXPO_SCREEN (s);
 
     if (es->expoCam > 0.0 && expoGetDeform (s->display) == DeformCurve &&
-        s->desktopWindowCount)
+        s->root.desktopWindowCount)
     {
 	int         x1, x2, i, oldVCount = w->vCount;
 	REGION      reg;
@@ -1318,10 +1319,12 @@ expoAddWindowGeometry (CompWindow *w,
 	v  = w->vertices + (w->vertexStride - 3);
 	v += w->vertexStride * oldVCount;
 
-	if (!windowOnAllViewports (w))
+	if (!windowOnAllViewports (w) && w->parent)
 	{
-	    getWindowMovementForOffset (w, s->windowOffsetX,
-                                        s->windowOffsetY, &offX, &offY);
+	    getWindowMovementForOffset (w,
+					w->parent->viewportOffsetX,
+                                        w->parent->viewportOffsetY,
+					&offX, &offY);
 	}
 
 	lastX = -1000000000.0;
@@ -1369,7 +1372,7 @@ expoDrawWindowTexture (CompWindow	    *w,
     EXPO_SCREEN (s);
 
     if (es->expoCam > 0.0 && expoGetDeform (s->display) == DeformCurve &&
-        s->desktopWindowCount && s->lighting)
+        s->root.desktopWindowCount && s->lighting)
     {
 	int     i, idx;
 	int     offX = 0, offY = 0;
@@ -1388,10 +1391,12 @@ expoDrawWindowTexture (CompWindow	    *w,
 	    es->winNormSize = w->vCount * 3;
 	}
 	
-	if (!windowOnAllViewports (w))
+	if (!windowOnAllViewports (w) && w->parent)
 	{
-	    getWindowMovementForOffset (w, s->windowOffsetX,
-                                        s->windowOffsetY, &offX, &offY);
+	    getWindowMovementForOffset (w,
+					w->parent->viewportOffsetX,
+                                        w->parent->viewportOffsetY,
+					&offX, &offY);
 	}
 	
 	v = w->vertices + (w->vertexStride - 3);
@@ -1556,7 +1561,7 @@ expoDonePaintScreen (CompScreen * s)
 	{
 	    CompWindow *w;
 
-	    for (w = s->reverseWindows; w; w = w->prev)
+	    for (w = s->root.reverseWindows; w; w = w->prev)
 	    {
 		Bool inWindow;
 		int xOffset, yOffset;
diff --git a/src/ezoom/ezoom.c b/src/ezoom/ezoom.c
index 90bf4ca..91cea99 100644
--- a/src/ezoom/ezoom.c
+++ b/src/ezoom/ezoom.c
@@ -1406,7 +1406,7 @@ cursorZoomInactive (CompScreen *s)
     if (zs->cursorInfoSelected)
     {
 	zs->cursorInfoSelected = FALSE;
-	XFixesSelectCursorInput (s->display->display, s->root, 0);
+	XFixesSelectCursorInput (s->display->display, s->root.id, 0);
     }
 
     if (zs->cursor.isSet)
@@ -1417,7 +1417,7 @@ cursorZoomInactive (CompScreen *s)
     if (zs->cursorHidden)
     {
 	zs->cursorHidden = FALSE;
-	XFixesShowCursor (s->display->display, s->root);
+	XFixesShowCursor (s->display->display, s->root.id);
     }
 }
 
@@ -1440,7 +1440,7 @@ cursorZoomActive (CompScreen *s)
     if (!zs->cursorInfoSelected)
     {
 	zs->cursorInfoSelected = TRUE;
-        XFixesSelectCursorInput (s->display->display, s->root,
+        XFixesSelectCursorInput (s->display->display, s->root.id,
 				 XFixesDisplayCursorNotifyMask);
 	zoomUpdateCursor (s, &zs->cursor);
     }
@@ -1448,7 +1448,7 @@ cursorZoomActive (CompScreen *s)
 	zs->opt[SOPT_HIDE_ORIGINAL_MOUSE].value.b)
     {
 	zs->cursorHidden = TRUE;
-	XFixesHideCursor (s->display->display, s->root);
+	XFixesHideCursor (s->display->display, s->root.id);
     }
 }
 
@@ -1735,7 +1735,7 @@ zoomSpecific (CompDisplay     *d,
 
 	w = findWindowAtDisplay(d, d->activeWindow);
 	if (zd->opt[DOPT_SPECIFIC_TARGET_FOCUS].value.b
-	    && w && w->screen->root == s->root)
+	    && w && w->screen->root.id == s->root.id)
 	{
 	    zoomAreaToWindow (w);
 	}
@@ -1812,7 +1812,7 @@ zoomToWindow (CompDisplay     *d,
 
     xid = getIntOptionNamed (option, nOption, "window", 0);
     w = findWindowAtDisplay (d, xid);
-    if (!w || w->screen->root != s->root)
+    if (!w || w->screen->root.id != s->root.id)
 	return TRUE;
     width = w->width + w->input.left + w->input.right;
     height = w->height + w->input.top + w->input.bottom;
@@ -2044,7 +2044,7 @@ zoomTerminate (CompDisplay     *d,
 	int out;
 	ZOOM_SCREEN (s);
 
-	if (xid && s->root != xid)
+	if (xid && s->root.id != xid)
 	    continue;
 	
 	out = outputDeviceForPoint (s, pointerX, pointerY);
diff --git a/src/mousepoll/mousepoll.c b/src/mousepoll/mousepoll.c
index d64d641..d552ea6 100644
--- a/src/mousepoll/mousepoll.c
+++ b/src/mousepoll/mousepoll.c
@@ -90,12 +90,12 @@ getMousePosition (CompScreen *s)
 
     MOUSEPOLL_SCREEN (s);
 
-    status = XQueryPointer (s->display->display, s->root,
+    status = XQueryPointer (s->display->display, s->root.id,
 			    &root_return, &child_return,
 			    &rootX, &rootY, &winX, &winY, &maskReturn);
 
     if (!status || rootX > s->width || rootY > s->height ||
-	s->root != root_return)
+	s->root.id != root_return)
 	return FALSE;
 
     if ((rootX != ms->posX || rootY != ms->posY))
diff --git a/src/neg/neg.c b/src/neg/neg.c
index 4535f55..9d4a6d3 100644
--- a/src/neg/neg.c
+++ b/src/neg/neg.c
@@ -91,6 +91,10 @@ NEGToggle (CompWindow *w)
 
     /* cause repainting */
     addWindowDamage (w);
+
+    /* toggle child windows */
+    for (w = w->windows; w; w = w->next)
+	NEGToggle (w);
 }
 
 static void
@@ -104,7 +108,7 @@ NEGToggleScreen (CompScreen *s)
     ns->isNeg = !ns->isNeg;
 
     /* toggle every window */
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
 	if (w)
 	    NEGToggle (w);
 }
@@ -546,14 +550,24 @@ NEGDrawWindowTexture (CompWindow           *w,
 }
 
 static void
-NEGWindowAdd (CompScreen *s,
+NEGWindowAdd (CompObject *parent,
 	      CompWindow *w)
 {
-    NEG_SCREEN (s);
+    Bool isNeg = FALSE;
+
+    NEG_SCREEN (w->screen);
 
     /* nw->isNeg is initialized to FALSE in InitWindow, so we only
        have to toggle it to TRUE if necessary */
-    if (ns->isNeg && matchEval (negGetNegMatch (s), w))
+     if (w->parent)
+     {
+	 if (w->parent == &w->screen->root)
+	     isNeg = ns->isNeg;
+	 else
+	     isNeg = GET_NEG_WINDOW (w->parent, ns)->isNeg;
+     }
+
+    if (isNeg && matchEval (negGetNegMatch (w->screen), w))
 	NEGToggle (w);
 }
 
@@ -570,7 +584,7 @@ NEGScreenOptionChanged (CompScreen       *s,
 	    CompWindow *w;
 	    NEG_SCREEN (s);
 
-	    for (w = s->windows; w; w = w->next)
+	    for (w = s->root.windows; w; w = w->next)
 	    {
 		Bool isNeg;
 		NEG_WINDOW (w);
diff --git a/src/opacify/opacify.c b/src/opacify/opacify.c
index 67d2261..7b90ae1 100644
--- a/src/opacify/opacify.c
+++ b/src/opacify/opacify.c
@@ -169,7 +169,7 @@ passiveWindows (CompScreen *s,
 
     OPACIFY_SCREEN (s);
 
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
     {
 	if (w->id == os->active)
 	{
@@ -314,7 +314,7 @@ checkDelay (CompScreen *s)
 	return TRUE;
     if (!opacifyGetTimeout (d))
 	return TRUE;
-    if (!os->newActive || (os->newActive->id == s->root))
+    if (!os->newActive || (os->newActive->id == s->root.id))
 	return FALSE;
     if (os->newActive->type & (CompWindowTypeDesktopMask |
 			       CompWindowTypeDockMask))
@@ -558,7 +558,7 @@ opacifyInitDisplay (CompPlugin  *p,
     }
     d->base.privates[displayPrivateIndex].ptr = od;
     od->timeoutHandle = 0;
-    od->activeScreen = d->screens->screenNum;
+    od->activeScreen = 0;
     od->toggle = TRUE;
 
     opacifySetToggleKeyInitiate (d, opacifyToggle);	
diff --git a/src/put/put.c b/src/put/put.c
index 116b9e2..a36f923 100644
--- a/src/put/put.c
+++ b/src/put/put.c
@@ -178,7 +178,7 @@ putPreparePaintScreen (CompScreen *s,
 	    Window endAnimationWindow = None;
 
 	    ps->moreAdjust = 0;
-	    for (w = s->windows; w; w = w->next)
+	    for (w = s->root.windows; w; w = w->next)
 	    {
 		PUT_WINDOW (w);
 
diff --git a/src/resizeinfo/resizeinfo.c b/src/resizeinfo/resizeinfo.c
index bfde570..d1b69c9 100644
--- a/src/resizeinfo/resizeinfo.c
+++ b/src/resizeinfo/resizeinfo.c
@@ -130,7 +130,7 @@ setupCairoLayer (CompScreen *s,
     format = XRenderFindStandardFormat (s->display->display,
 	    				PictStandardARGB32);
 
-    il->pixmap = XCreatePixmap (s->display->display, s->root, w, h, 32);
+    il->pixmap = XCreatePixmap (s->display->display, s->root.id, w, h, 32);
     if (!bindPixmapToTexture (s, &il->texture, il->pixmap, w, h, 32))
     {
 	compLogMessage ("resizeinfo", CompLogLevelWarn,
diff --git a/src/ring/ring.c b/src/ring/ring.c
index 44f0a80..28c5e42 100644
--- a/src/ring/ring.c
+++ b/src/ring/ring.c
@@ -388,20 +388,29 @@ ringPaintWindow (CompWindow		 *w,
 
 	RING_WINDOW (w);
 
-    	if (w->mapNum)
-	{
-	    if (!w->texture->pixmap && !w->bindFailed)
-		bindWindow (w);
-	}
-
 	if (rw->adjust || rw->slot)
 	{
-	    scaled = rw->adjust || (rw->slot && rs->paintingSwitcher);
+	    if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
+		return FALSE;
+
+	    if (rw->adjust || (rw->slot && rs->paintingSwitcher))
+	    {
+		if (rw->slot)
+		    sAttrib.brightness = (float) sAttrib.brightness * 
+			rw->slot->depthBrightness;
+
+		if (w->id != rs->selectedWindow)
+		    sAttrib.opacity = (float) sAttrib.opacity *
+			ringGetInactiveOpacity (s) / 100;
+
+		scaled = TRUE;
+	    }
+
 	    mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
 	}
 	else if (rs->state != RingStateIn)
 	{
-	    if (ringGetDarkenBack (s))
+	    if (w->parent == &w->screen->root && ringGetDarkenBack (s))
 	    {
 		/* modify brightness of the other windows */
 		sAttrib.brightness = sAttrib.brightness / 2;
@@ -412,28 +421,21 @@ ringPaintWindow (CompWindow		 *w,
 	status = (*s->paintWindow) (w, &sAttrib, transform, region, mask);
 	WRAP (rs, s, paintWindow, ringPaintWindow);
 
-	if (scaled && w->texture->pixmap)
-	{
-	    FragmentAttrib fragment;
-	    CompTransform  wTransform = *transform;
-
-	    if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
-		return FALSE;
+	if (w->attrib.map_state != IsViewable)
+	    return status;
 
-	    initFragmentAttrib (&fragment, &w->lastPaint);
+	if (!w->damaged)
+	    return status;
 
-	    if (rw->slot)
-	    {
-    		fragment.brightness = (float) fragment.brightness * 
-		                      rw->slot->depthBrightness;
-
-		if (w->id != rs->selectedWindow)
-		    fragment.opacity = (float)fragment.opacity *
-			               ringGetInactiveOpacity (s) / 100;
-	    }
+	if (w->mapNum)
+        {
+	    if (!w->texture->pixmap && !w->bindFailed)
+		bindWindow (w);
+	}
 
-	    if (w->alpha || fragment.opacity != OPAQUE)
-		mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
+	if (scaled && w->texture->pixmap)
+	{
+	    CompTransform wTransform = *transform;
 
 	    matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f);
 	    matrixScale (&wTransform, rw->scale, rw->scale, 1.0f);
@@ -442,13 +444,7 @@ ringPaintWindow (CompWindow		 *w,
 			     rw->ty / rw->scale - w->attrib.y,
 			     0.0f);
 
-	    glPushMatrix ();
-	    glLoadMatrixf (wTransform.m);
-
-	    (*s->drawWindow) (w, &wTransform, &fragment, region,
-			      mask | PAINT_WINDOW_TRANSFORMED_MASK);
-
-	    glPopMatrix ();
+	    drawTransformedWindowWithChildren (w, &sAttrib, &wTransform);
 	}
 
 	if (scaled && (rs->state != RingStateIn) &&
@@ -764,7 +760,7 @@ ringCreateWindowList (CompScreen *s)
 
     rs->nWindows = 0;
 
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
     {
 	if (isRingWin (w))
 	{
@@ -830,7 +826,7 @@ ringCountWindows (CompScreen *s)
     CompWindow *w;
     int	       count = 0;
 
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
     {
 	if (isRingWin (w))
 	    count++;
@@ -1028,7 +1024,7 @@ ringPreparePaintScreen (CompScreen *s,
 	    rs->rotateAdjust = adjustRingRotation (s, chunk);
 	    rs->moreAdjust = FALSE;
 
-	    for (w = s->windows; w; w = w->next)
+	    for (w = s->root.windows; w; w = w->next)
 	    {
 		RING_WINDOW (w);
 
@@ -1106,7 +1102,7 @@ ringTerminate (CompDisplay     *d,
     {
 	RING_SCREEN (s);
 
-	if (xid && s->root != xid)
+	if (xid && s->root.id != xid)
 	    continue;
 
 	if (rs->grabIndex)
@@ -1119,7 +1115,7 @@ ringTerminate (CompDisplay     *d,
     	{
     	    CompWindow *w;
 
-    	    for (w = s->windows; w; w = w->next)
+    	    for (w = s->root.windows; w; w = w->next)
     	    {
     		RING_WINDOW (w);
     
@@ -1375,7 +1371,7 @@ ringWindowSelectAt (CompScreen *s,
 
     	o.type = CompOptionTypeInt;
     	o.name = "root";
-	o.value.i = s->root;
+	o.value.i = s->root.id;
 
 	ringTerminate (s->display, NULL, 0, &o, 1);
     }
@@ -1439,7 +1435,7 @@ ringWindowRemove (CompDisplay *d,
 
 	    o.type = CompOptionTypeInt;
 	    o.name = "root";
-	    o.value.i = w->screen->root;
+	    o.value.i = w->screen->root.id;
 
 	    ringTerminate (d, NULL, 0, &o, 1);
 	    return;
diff --git a/src/scaleaddon/scaleaddon.c b/src/scaleaddon/scaleaddon.c
index ae876ab..c151e6a 100644
--- a/src/scaleaddon/scaleaddon.c
+++ b/src/scaleaddon/scaleaddon.c
@@ -345,7 +345,7 @@ scaleaddonCheckForWindowAt (CompScreen *s,
     float      x1, y1, x2, y2;
     CompWindow *w;
 
-    for (w = s->reverseWindows; w; w = w->prev)
+    for (w = s->root.reverseWindows; w; w = w->prev)
     {
         SCALE_WINDOW (w);
 
@@ -494,7 +494,7 @@ scaleaddonPullWindow  (CompDisplay     *d,
 
 		    o[0].type    = CompOptionTypeInt;
 		    o[0].name    = "root";
-		    o[0].value.i = s->root;
+		    o[0].value.i = s->root.id;
 
 		    if (action->terminate)
 			(*action->terminate) (d, action, 0, o, 1);
@@ -732,7 +732,7 @@ scaleaddonDonePaintScreen (CompScreen *s)
     {
 	CompWindow *w;
 
-	for (w = s->windows; w; w = w->next)
+	for (w = s->root.windows; w; w = w->next)
 	    scaleaddonRenderWindowTitle (w);
     }
     else if (ss->state == SCALE_STATE_NONE &&
@@ -740,7 +740,7 @@ scaleaddonDonePaintScreen (CompScreen *s)
     {
 	CompWindow *w;
 
-	for (w = s->windows; w; w = w->next)
+	for (w = s->root.windows; w; w = w->next)
 	    scaleaddonFreeWindowTitle (w);
     }
 
@@ -808,7 +808,7 @@ scaleaddonHandleCompizEvent (CompDisplay *d,
 	    {
 		CompWindow *w;
 
-		for (w = s->windows; w; w = w->next)
+		for (w = s->root.windows; w; w = w->next)
 		{
 		    ADDON_WINDOW (w);
 		    aw->rescaled = FALSE;
@@ -1261,7 +1261,7 @@ scaleaddonScreenOptionChanged (CompScreen              *s,
 	    {
 		CompWindow *w;
 
-		for (w = s->windows; w; w = w->next)
+		for (w = s->root.windows; w; w = w->next)
 		{
 		    ADDON_WINDOW (w);
 
diff --git a/src/session/session.c b/src/session/session.c
index 6b58320..ef20671 100644
--- a/src/session/session.c
+++ b/src/session/session.c
@@ -481,7 +481,7 @@ saveState (CompDisplay *d,
     {
 	CompWindow *w;
 
-	for (w = s->windows; w; w = w->next)
+	for (w = s->root.windows; w; w = w->next)
 	{
 	    if (!isSessionWindow (w))
 		continue;
@@ -853,7 +853,7 @@ sessionWindowAddTimeout (void *closure)
     SESSION_DISPLAY (d);
 
     for (s = d->screens; s; s = s->next)
-	for (w = s->windows; w; w = w->next)
+	for (w = s->root.windows; w; w = w->next)
 	    sessionWindowAdd (s, w);
 
     sd->windowAddTimeout = 0;
diff --git a/src/shift/shift.c b/src/shift/shift.c
index 4978c9f..6ee308b 100644
--- a/src/shift/shift.c
+++ b/src/shift/shift.c
@@ -203,7 +203,7 @@ shiftActivateEvent (CompScreen *s,
 
     o[0].type = CompOptionTypeInt;
     o[0].name = "root";
-    o[0].value.i = s->root;
+    o[0].value.i = s->root.id;
 
     o[1].type = CompOptionTypeBool;
     o[1].name = "active";
@@ -465,17 +465,29 @@ shiftPaintWindow (CompWindow		 *w,
     {
 	WindowPaintAttrib sAttrib = *attrib;
 	Bool		  scaled = FALSE;
+	float             anim   = MIN (1.0, MAX (0.0, ss->anim));
 
-    	if (w->mapNum)
+	if (sw->active)
 	{
-	    if (!w->texture->pixmap && !w->bindFailed)
-		bindWindow (w);
+	    if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
+		return FALSE;
+
+	    if (ss->activeSlot)
+	    {
+		if (ss->activeSlot->slot->primary && !ss->reflectActive)
+		    sAttrib.opacity *=
+			(ss->anim * ss->activeSlot->slot->opacity) +
+			(1 - ss->anim);
+		else
+		    sAttrib.opacity *= anim * anim *
+			ss->activeSlot->slot->opacity;
+
+		mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
+
+		scaled = TRUE;
+	    }
 	}
 
-	
-	if (sw->active)
-	    scaled = (ss->activeSlot != NULL);
-	
 	if (sw->opacity > 0.01 && (ss->activeSlot == NULL))
 	{
 	    sAttrib.brightness = sAttrib.brightness * sw->brightness;
@@ -487,53 +499,43 @@ shiftPaintWindow (CompWindow		 *w,
 	if (sw->active &&
 	    (ss->output->id == ss->usedOutput || ss->output->id == ~0))
 	    mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
-	
 
 	UNWRAP (ss, s, paintWindow);
 	status = (*s->paintWindow) (w, &sAttrib, transform, region, mask);
 	WRAP (ss, s, paintWindow, shiftPaintWindow);
 
+	if (w->attrib.map_state != IsViewable)
+	    return status;
+
+	if (!w->damaged)
+	    return status;
+
+	if (w->mapNum)
+        {
+	    if (!w->texture->pixmap && !w->bindFailed)
+		bindWindow (w);
+	}
+
 	if (scaled && w->texture->pixmap)
 	{
-	    FragmentAttrib fragment;
-	    CompTransform  wTransform = *transform;
-	    ShiftSlot      *slot = ss->activeSlot->slot;
+	    CompTransform wTransform = *transform;
+	    ShiftSlot     *slot = ss->activeSlot->slot;
 
 	    float sx     = ss->anim * slot->tx;
 	    float sy     = ss->anim * slot->ty;
 	    float sz     = ss->anim * slot->z;
 	    float srot   = (ss->anim * slot->rotation);
-	    float anim   = MIN (1.0, MAX (0.0, ss->anim));
 
 	    float sscale;
-	    float sopacity;
-	    
 
 	    if (slot->primary)
 		sscale = (ss->anim * slot->scale) + (1 - ss->anim);
 	    else
 		sscale = ss->anim * slot->scale;
 	
-	    if (slot->primary && !ss->reflectActive)
-		sopacity = (ss->anim * slot->opacity) + (1 - ss->anim);
-	    else
-		sopacity = anim * anim * slot->opacity;
-
-	    if (sopacity <= 0.05)
+	    if (w->lastPaint.opacity <= (0.05 * OPAQUE))
 		return status;
 
-	    if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
-		return FALSE;
-
-	    initFragmentAttrib (&fragment, attrib);
-
-	    fragment.opacity    = (float)fragment.opacity * sopacity;
-	    fragment.brightness = (float)fragment.brightness *
-				  ss->reflectBrightness;
-
-	    if (w->alpha || fragment.opacity != OPAQUE)
-		mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
-
 	    matrixTranslate (&wTransform, sx, sy, sz);
 
 	    matrixTranslate (&wTransform,
@@ -553,13 +555,7 @@ shiftPaintWindow (CompWindow		 *w,
 	    matrixTranslate (&wTransform, -w->attrib.x - (w->width / 2),
 			     -w->attrib.y - (w->attrib.height / 2), 0.0f);
 
-	    glPushMatrix ();
-	    glLoadMatrixf (wTransform.m);
-
-	    (*s->drawWindow) (w, &wTransform, &fragment, region,
-			      mask | PAINT_WINDOW_TRANSFORMED_MASK);
-
-	    glPopMatrix ();
+	    drawTransformedWindowWithChildren (w, &sAttrib, &wTransform);
 	}
 
 	if (scaled && ((shiftGetOverlayIcon (s) != OverlayIconNone) ||
@@ -1144,7 +1140,7 @@ shiftCreateWindowList (CompScreen *s)
 
     ss->nWindows = 0;
 
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
     {
 	if (isShiftWin (w))
 	{
@@ -1209,7 +1205,7 @@ shiftCountWindows (CompScreen *s)
     CompWindow *w;
     int	       count = 0;
 
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
     {
 	if (isShiftWin (w))
 	    count++;
@@ -1629,7 +1625,7 @@ shiftPreparePaintScreen (CompScreen *s,
 	{
 	    ss->moreAdjust = adjustShiftAnimationAttribs (s, chunk);
 
-	    for (w = s->windows; w; w = w->next)
+	    for (w = s->root.windows; w; w = w->next)
 	    {
 		SHIFT_WINDOW (w);
 
@@ -1687,7 +1683,7 @@ shiftDonePaintScreen (CompScreen *s)
 	    {
 		ss->state = ShiftStateNone;
 		shiftActivateEvent(s, FALSE);
-		for (w = s->windows; w; w = w->next)
+		for (w = s->root.windows; w; w = w->next)
 		{
 		    SHIFT_WINDOW (w);
 		    sw->active = FALSE;
@@ -1783,7 +1779,7 @@ shiftTerminate (CompDisplay     *d,
 
     for (s = d->screens; s; s = s->next)
     {
-	if (xid && s->root != xid)
+	if (xid && s->root.id != xid)
 	    continue;
 
 	shiftTerm (s, (state & CompActionStateCancel));
@@ -2125,7 +2121,7 @@ shiftWindowRemove (CompDisplay * d,
 
 	    o.type = CompOptionTypeInt;
 	    o.name = "root";
-	    o.value.i = w->screen->root;
+	    o.value.i = w->screen->root.id;
 
 	    shiftTerminate (d, NULL, 0, &o, 1);
 	    return;
diff --git a/src/snap/snap.c b/src/snap/snap.c
index da316bc..bf0450c 100644
--- a/src/snap/snap.c
+++ b/src/snap/snap.c
@@ -338,7 +338,7 @@ static void snapUpdateWindowsEdges(CompWindow * w)
 	Bool remove = FALSE;
 
 	// First add all the windows
-	c = w->screen->windows;
+	c = w->screen->root.windows;
 	while (c)
 	{
 		// Just check that we're not trying to snap to current window,
@@ -366,7 +366,7 @@ static void snapUpdateWindowsEdges(CompWindow * w)
 	// If an edge has been passed, check if it's in the region window,
 	// if the edge is fully under the window, drop it, or if it's only
 	// partly covered, cut it/split it in one/two smaller visible edges
-	for (c = w->screen->windows; c; c = c->next)
+	for (c = w->screen->root.windows; c; c = c->next)
 	{
 		if (c == w || !isSnapWindow(c))
 			continue;
@@ -461,7 +461,7 @@ static void snapUpdateScreenEdges(CompWindow * w)
 
 	// Drop screen edges parts that are under struts, basically apply the
 	// same strategy than for windows edges visibility
-	for (c = w->screen->windows; c; c = c->next)
+	for (c = w->screen->root.windows; c; c = c->next)
 	{
 		if (c == w || !c->struts)
 			continue;
diff --git a/src/staticswitcher/staticswitcher.c b/src/staticswitcher/staticswitcher.c
index 316cbf7..d55a48c 100644
--- a/src/staticswitcher/staticswitcher.c
+++ b/src/staticswitcher/staticswitcher.c
@@ -184,7 +184,7 @@ switchActivateEvent (CompScreen *s,
 
     o[0].type = CompOptionTypeInt;
     o[0].name = "root";
-    o[0].value.i = s->root;
+    o[0].value.i = s->root.id;
 
     o[1].type = CompOptionTypeBool;
     o[1].name = "active";
@@ -324,7 +324,7 @@ switchCreateWindowList (CompScreen *s,
 
     ss->nWindows = 0;
 
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
     {
 	if (isSwitchWin (w))
 	    switchAddWindowToList (s, w);
@@ -445,7 +445,7 @@ switchToWindow (CompScreen *s,
 	    xev.xclient.format = 32;
 
 	    xev.xclient.message_type = s->display->desktopViewportAtom;
-	    xev.xclient.window = s->root;
+	    xev.xclient.window = s->root.id;
 
 	    xev.xclient.data.l[0] = x * s->width;
 	    xev.xclient.data.l[1] = y * s->height;
@@ -453,7 +453,7 @@ switchToWindow (CompScreen *s,
 	    xev.xclient.data.l[3] = 0;
 	    xev.xclient.data.l[4] = 0;
 
-	    XSendEvent (s->display->display, s->root, FALSE,
+	    XSendEvent (s->display->display, s->root.id, FALSE,
 			SubstructureRedirectMask | SubstructureNotifyMask,
 			&xev);
 	}
@@ -495,7 +495,7 @@ switchCountWindows (CompScreen *s)
     CompWindow *w;
     int	       count = 0;
 
-    for (w = s->windows; w; w = w->next)
+    for (w = s->root.windows; w; w = w->next)
 	if (isSwitchWin (w))
 	    count++;
 
@@ -608,11 +608,11 @@ switchInitiate (CompScreen            *s,
 
 	attr.background_pixel = 0;
 	attr.border_pixel     = 0;
-	attr.colormap	      = XCreateColormap (dpy, s->root, visual,
+	attr.colormap	      = XCreateColormap (dpy, s->root.id, visual,
 						 AllocNone);
 
 	ss->popupWindow =
-	    XCreateWindow (dpy, s->root, -1, -1, 1, 1, 0,
+	    XCreateWindow (dpy, s->root.id, -1, -1, 1, 1, 0,
 			   32, InputOutput, visual,
 			   CWBackPixel | CWBorderPixel | CWColormap, &attr);
 
@@ -697,7 +697,7 @@ switchTerminate (CompDisplay     *d,
     {
 	SWITCH_SCREEN (s);
 
-	if (xid && s->root != xid)
+	if (xid && s->root.id != xid)
 	    continue;
 
 	if (ss->grabIndex)
@@ -973,7 +973,7 @@ switchWindowRemove (CompDisplay *d,
 
 	    o.type    = CompOptionTypeInt;
 	    o.name    = "root";
-	    o.value.i = w->screen->root;
+	    o.value.i = w->screen->root.id;
 
 	    switchTerminate (d, NULL, 0, &o, 1);
 	    return;
@@ -1242,8 +1242,9 @@ switchPaintOutput (CompScreen		   *s,
 		for (w = zoomed->prev; w && w->id <= 1; w = w->prev);
 		zoomedAbove = (w) ? w->id : None;
 
-		unhookWindowFromScreen (s, zoomed);
-		insertWindowIntoScreen (s, zoomed, s->reverseWindows->id);
+		unhookWindow (zoomed->parent, zoomed);
+		insertWindow (zoomed->parent, zoomed,
+			      s->root.reverseWindows->id);
 	    }
 	}
 	else
@@ -1258,8 +1259,8 @@ switchPaintOutput (CompScreen		   *s,
 
 	if (zoomed)
 	{
-	    unhookWindowFromScreen (s, zoomed);
-	    insertWindowIntoScreen (s, zoomed, zoomedAbove);
+	    unhookWindow (zoomed->parent, zoomed);
+	    insertWindow (zoomed->parent, zoomed, zoomedAbove);
 	}
 
 	if (switcher || mode == HighlightModeShowRectangle)
@@ -1392,7 +1393,6 @@ switchPaintThumb (CompWindow		  *w,
     if (w->texture->pixmap)
     {
 	AddWindowGeometryProc oldAddWindowGeometry;
-	FragmentAttrib	      fragment;
 	CompTransform	      wTransform = *transform;
 	int		      ww, wh;
 
@@ -1434,11 +1434,6 @@ switchPaintThumb (CompWindow		  *w,
 	sAttrib.xTranslate = wx - w->attrib.x + w->input.left * sAttrib.xScale;
 	sAttrib.yTranslate = wy - w->attrib.y + w->input.top  * sAttrib.yScale;
 
-	initFragmentAttrib (&fragment, &sAttrib);
-
-	if (w->alpha || fragment.opacity != OPAQUE)
-	    mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
-
 	matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f);
 	matrixScale (&wTransform, sAttrib.xScale, sAttrib.yScale, 1.0f);
 	matrixTranslate (&wTransform,
@@ -1446,20 +1441,14 @@ switchPaintThumb (CompWindow		  *w,
 			 sAttrib.yTranslate / sAttrib.yScale - w->attrib.y,
 			 0.0f);
 
-	glPushMatrix ();
-	glLoadMatrixf (wTransform.m);
-
 	/* XXX: replacing the addWindowGeometry function like this is
 	   very ugly but necessary until the vertex stage has been made
 	   fully pluggable. */
 	oldAddWindowGeometry = w->screen->addWindowGeometry;
 	w->screen->addWindowGeometry = addWindowGeometry;
-	(w->screen->drawWindow) (w, &wTransform, &fragment, &infiniteRegion,
-				 mask);
+	drawTransformedWindowWithChildren (w, &sAttrib, &wTransform);
 	w->screen->addWindowGeometry = oldAddWindowGeometry;
 
-	glPopMatrix ();
-
 	if (staticswitcherGetIcon (s))
 	{
 	    icon = getWindowIcon (w, ICON_SIZE, ICON_SIZE);
@@ -1671,6 +1660,12 @@ switchPaintWindow (CompWindow		   *w,
 	status = (*s->paintWindow) (w, attrib, transform, region, mask);
 	WRAP (ss, s, paintWindow, switchPaintWindow);
 
+	if (w->attrib.map_state != IsViewable)
+	    return status;
+
+	if (!w->damaged)
+	    return status;
+
 	if (!(mask & PAINT_WINDOW_TRANSFORMED_MASK) && region->numRects == 0)
 	    return TRUE;
 
diff --git a/src/text/text.c b/src/text/text.c
index d281625..fe22be3 100644
--- a/src/text/text.c
+++ b/src/text/text.c
@@ -216,7 +216,7 @@ textFileToImage (CompDisplay *d,
 	    return FALSE;
 	}
 
-	pixmap = XCreatePixmap (dpy, textAttrib->screen->root, 1, 1, 32);
+	pixmap = XCreatePixmap (dpy, textAttrib->screen->root.id, 1, 1, 32);
 	if (!pixmap)
 	{
 	    compLogMessage ("text", CompLogLevelError,
@@ -365,7 +365,8 @@ textFileToImage (CompDisplay *d,
 	pixmap = None;
 
 	if (w > 0 && h > 0)
-	    pixmap = XCreatePixmap (dpy, textAttrib->screen->root, w, h, 32);
+	    pixmap = XCreatePixmap (dpy, textAttrib->screen->root.id,
+				    w, h, 32);
 
 	if (!pixmap)
 	{
diff --git a/src/thumbnail/thumbnail.c b/src/thumbnail/thumbnail.c
index f477acb..cd859f4 100644
--- a/src/thumbnail/thumbnail.c
+++ b/src/thumbnail/thumbnail.c
@@ -439,7 +439,7 @@ positionUpdate (CompScreen *s,
 		int        x,
 		int        y)
 {
-    CompWindow *cw    = s->windows;
+    CompWindow *cw    = s->root.windows;
     CompWindow *found = NULL;
 
     THUMB_SCREEN (s);
@@ -685,8 +685,6 @@ thumbPaintThumb (CompScreen          *s,
     float                 width  = t->width;
     float                 height = t->height;
     WindowPaintAttrib     sAttrib;
-    unsigned int          mask = PAINT_WINDOW_TRANSFORMED_MASK |
-	                         PAINT_WINDOW_TRANSLUCENT_MASK;
 
     THUMB_SCREEN (s);
 
@@ -705,10 +703,9 @@ thumbPaintThumb (CompScreen          *s,
 
     if (w->texture->pixmap)
     {
-	int            off = t->offset;
-	GLenum         filter = s->display->textureFilter;
-	FragmentAttrib fragment;
-	CompTransform  wTransform = *transform;
+	int           off = t->offset;
+	GLenum        filter = s->display->textureFilter;
+	CompTransform wTransform = *transform;
 
 	glEnable (GL_BLEND);
 	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -876,8 +873,6 @@ thumbPaintThumb (CompScreen          *s,
 	if (thumbnailGetMipmap (s))
 	    s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
 
-	initFragmentAttrib (&fragment, &sAttrib);
-
 	matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f);
 	matrixScale (&wTransform, sAttrib.xScale, sAttrib.yScale, 1.0f);
 	matrixTranslate (&wTransform,
@@ -885,11 +880,7 @@ thumbPaintThumb (CompScreen          *s,
 			 sAttrib.yTranslate / sAttrib.yScale - w->attrib.y,
 			 0.0f);
 
-	glPushMatrix ();
-	glLoadMatrixf (wTransform.m);
-	(*w->screen->drawWindow) (w, &wTransform, &fragment,
-				  &infiniteRegion, mask);
-	glPopMatrix ();
+	drawTransformedWindowWithChildren (w, &sAttrib, &wTransform);
 
 	s->display->textureFilter = filter;
     }
diff --git a/src/vpswitch/vpswitch.c b/src/vpswitch/vpswitch.c
index a88e853..7fc6d51 100644
--- a/src/vpswitch/vpswitch.c
+++ b/src/vpswitch/vpswitch.c
@@ -71,7 +71,7 @@ typedef struct _VpSwitchDisplay
     xid = getIntOptionNamed (option, nOption, "window", 0); \
     w = findWindowAtDisplay (d, xid); \
     if ((!w || (w->type & CompWindowTypeDesktopMask) == 0) && \
-	xid != s->root) \
+	xid != s->root.id) \
 	return FALSE;
 
 static Bool
@@ -177,7 +177,7 @@ vpswitchGoto (CompScreen *s,
     xev.xclient.format  = 32;
 
     xev.xclient.message_type = s->display->desktopViewportAtom;
-    xev.xclient.window       = s->root;
+    xev.xclient.window       = s->root.id;
 
     xev.xclient.data.l[0] = x * s->width;
     xev.xclient.data.l[1] = y * s->height;
@@ -185,7 +185,7 @@ vpswitchGoto (CompScreen *s,
     xev.xclient.data.l[3] = 0;
     xev.xclient.data.l[4] = 0;
 
-    XSendEvent (s->display->display, s->root, FALSE,
+    XSendEvent (s->display->display, s->root.id, FALSE,
 		SubstructureRedirectMask | SubstructureNotifyMask, &xev);
 }
 
diff --git a/src/wall/wall.c b/src/wall/wall.c
index dfe004b..7339e9d 100644
--- a/src/wall/wall.c
+++ b/src/wall/wall.c
@@ -403,7 +403,7 @@ wallSetupCairoContext (CompScreen       *s,
     format = XRenderFindStandardFormat (s->display->display,
 					PictStandardARGB32);
 
-    context->pixmap = XCreatePixmap (s->display->display, s->root,
+    context->pixmap = XCreatePixmap (s->display->display, s->root.id,
 				     width, height, 32);
 
     if (!bindPixmapToTexture(s, &context->texture, context->pixmap,
@@ -1760,7 +1760,7 @@ wallSetOptionForPlugin (CompObject      *o,
     status = (*core.setOptionForPlugin) (o, plugin, name, value);
     WRAP (wc, &core, setOptionForPlugin, wallSetOptionForPlugin);
 
-    if (status && o->type == COMP_OBJECT_TYPE_SCREEN)
+    if (status && o->parent && o->type == COMP_OBJECT_TYPE_SCREEN)
     {
 	if (strcmp (plugin, "core") == 0)
 	    if (strcmp (name, "hsize") == 0 || strcmp (name, "vsize") == 0)
diff --git a/src/winrules/winrules.c b/src/winrules/winrules.c
index 8f10998..6b4249c 100644
--- a/src/winrules/winrules.c
+++ b/src/winrules/winrules.c
@@ -410,7 +410,7 @@ winrulesSetScreenOption (CompPlugin *plugin,
 	{
 	    CompWindow *w;
 
-	    for (w = screen->windows; w; w = w->next)
+	    for (w = screen->root.windows; w; w = w->next)
 		winrulesSetNoAlpha (w, WINRULES_SCREEN_OPTION_NOARGB_MATCH);
 
 	    return TRUE;
@@ -421,7 +421,7 @@ winrulesSetScreenOption (CompPlugin *plugin,
 	{
 	    CompWindow *w;
 
-	    for (w = screen->windows; w; w = w->next)
+	    for (w = screen->root.windows; w; w = w->next)
 		winrulesSetNoFocus (w, WINRULES_SCREEN_OPTION_NOFOCUS_MATCH);
 
 	    return TRUE;
@@ -448,7 +448,7 @@ winrulesSetScreenOption (CompPlugin *plugin,
     {
 	CompWindow *w;
 
-	for (w = screen->windows; w; w = w->next)
+	for (w = screen->root.windows; w; w = w->next)
 	    winrulesUpdateState (w, index, updateStateMask);
 
 	return TRUE;
@@ -458,7 +458,7 @@ winrulesSetScreenOption (CompPlugin *plugin,
     {
 	CompWindow *w;
 
-	for (w = screen->windows; w; w = w->next)
+	for (w = screen->root.windows; w; w = w->next)
 	    winrulesSetAllowedActions (w, index, updateActionsMask);
 
 	return TRUE;
@@ -582,7 +582,7 @@ winrulesMatchExpHandlerChanged (CompDisplay *d)
 
     /* match options are up to date after the call to matchExpHandlerChanged */
     for (s = d->screens; s; s = s->next)
-	for (w = s->windows; w; w = w->next)
+	for (w = s->root.windows; w; w = w->next)
 	    winrulesApplyRules (w);
 }
 
diff --git a/src/workarounds/workarounds.c b/src/workarounds/workarounds.c
index 0e0f9a1..bb9941e 100644
--- a/src/workarounds/workarounds.c
+++ b/src/workarounds/workarounds.c
@@ -534,7 +534,7 @@ workaroundsDisplayOptionChanged (CompDisplay               *d,
     for (s = d->screens; s; s = s->next)
     {
 	ws = GET_WORKAROUNDS_SCREEN (s, GET_WORKAROUNDS_DISPLAY (d));
-	for (w = s->windows; w; w = w->next)
+	for (w = s->root.windows; w; w = w->next)
 	    workaroundsUpdateSticky (w);
 	workaroundsUpdateParameterFix (s);
 	if (workaroundsGetFglrxXglFix (d))
openSUSE Build Service is sponsored by