Manual redirection effect on parent and sibling clipping

Keith Packard keithp at keithp.com
Wed Mar 7 13:55:33 PST 2007


Right now, all redirected windows have precisely the same effect on clip
lists as unredirected windows. This becomes problematic when attempting
to do redirection within an application using a window which is not
redirected itself. When exposures occur to the application window, the
child doesn't receive any events (as it is redirected) but neither does
the parent, for areas covered by the child (those areas aren't part of
the clip list for the parent).

Owen Taylor had a fairly simple suggestion, which is also easy to
implement. Treat the redirected windows as if they weren't there. Leave
the region covered by these windows in the parent clip list; exposures
will then be delivered to the parent.

The only question is what to do about siblings. For that, he suggested
that we also compute sibling clip lists as though the redirected window
was not present. Of course, this means that areas nominally owned by the
redirected window will be overdrawn by the non-redirected sibling, but
it's hard to see how this will make things worse.

The overriding semantic idea here is that manually redirected windows
are not presented on the screen at all. The contract is that the
redirecting client is responsible for presenting the contents in the
parent window. Leaving the parent unclipped by the redirected windows
actually makes this easier -- the client need not worry about
overwriting unredirected windows by being forced to use IncludeInferiors
rendering mode.

I've written (but not tested even to start the server) some code that
should do this; the real change is just a couple of lines inside the
tree validation code where children that are manually redirected are not
removed from the parent clip list as it is constructed.

# On branch refs/heads/server-1.3-branch
# Updated but not checked in:
#   (will commit)
#
#	modified:   composite/compext.c
#	modified:   mi/mi.h
#	modified:   mi/mivaltree.c
#
# 
diff --git a/composite/compext.c b/composite/compext.c
index 13936fa..9e1fd5c 100644
--- a/composite/compext.c
+++ b/composite/compext.c
@@ -672,6 +672,14 @@ SProcCompositeDispatch (ClientPtr client)
 	return BadRequest;
 }
 
+static Bool
+compWindowIsManualRedirect (WindowPtr pWindow)
+{
+    CompWindowPtr   cw = GetCompWindow (pWindow);
+
+    return cw && cw->update == CompositeRedirectManual;
+}
+
 void
 CompositeExtensionInit (void)
 {
@@ -709,4 +717,5 @@ CompositeExtensionInit (void)
 	    return;
     miRegisterRedirectBorderClipProc (compSetRedirectBorderClip,
 				      compGetRedirectBorderClip);
+    miRegisterManualRedirectTestProc (compWindowIsManualRedirect);
 }
diff --git a/mi/mi.h b/mi/mi.h
index 97e1b6f..a60b0e9 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -489,10 +489,16 @@ typedef void
 typedef RegionPtr
 (*GetRedirectBorderClipProcPtr) (WindowPtr pWindow);
 
+typedef Bool
+(*WindowIsManualRedirectProcPtr) (WindowPtr pWindow);
+
 void
 miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
 				  GetRedirectBorderClipProcPtr getBorderClip);
 
+void
+miRegisterManualRedirectTestProc (WindowIsManualRedirectProcPtr isManualRedir);
+				  
 extern int miValidateTree(
     WindowPtr /*pParent*/,
     WindowPtr /*pChild*/,
diff --git a/mi/mivaltree.c b/mi/mivaltree.c
index 0e5ed61..3d4ee11 100644
--- a/mi/mivaltree.c
+++ b/mi/mivaltree.c
@@ -170,6 +170,7 @@ miShapedWindowIn (pScreen, universe, bounding, rect, x, y)
 
 static GetRedirectBorderClipProcPtr	miGetRedirectBorderClipProc;
 static SetRedirectBorderClipProcPtr	miSetRedirectBorderClipProc;
+static WindowIsManualRedirectProcPtr	miWindowIsManualRedirectProc;
 
 void
 miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
@@ -179,6 +180,20 @@ miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
     miGetRedirectBorderClipProc = getBorderClip;
 }
 
+void
+miRegisterManualRedirectTestProc (WindowIsManualRedirectProcPtr isManualRedir)
+{
+    miWindowIsManualRedirectProc = isManualRedir;
+}
+
+/*
+ * Manual redirected windows are treated as transparent; they do not obscure
+ * siblings or parent windows
+ */
+
+#define TreatAsTransparent(w)	((w)->redirectDraw && \
+				 miWindowIsManualRedirectProc (w))
+
 #define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
 				    HasBorder(w) && \
 				    (w)->backgroundState == ParentRelative)
@@ -432,7 +447,7 @@ miComputeClips (
 	{
 	    for (; pChild; pChild = pChild->nextSib)
 	    {
-		if (pChild->viewable)
+		if (pChild->viewable && !TreatAsTransparent(pChild))
 		    REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
 	    }
 	}
@@ -440,7 +455,7 @@ miComputeClips (
 	{
 	    for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
 	    {
-		if (pChild->viewable)
+		if (pChild->viewable && !TreatAsTransparent(pChild))
 		    REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
 	    }
 	}
@@ -472,7 +487,7 @@ miComputeClips (
 		 * from the current universe, thus denying its space to any
 		 * other sibling.
 		 */
-		if (overlap)
+		if (overlap && !TreatAsTransparent (pChild))
 		    REGION_SUBTRACT( pScreen, universe, universe,
 					  &pChild->borderSize);
 	    }
@@ -644,7 +659,7 @@ miValidateTree (pParent, pChild, kind)
 	
 	for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib)
 	{
-	    if (pWin->viewable)
+	    if (pWin->viewable && !TreatAsTransparent (pWin))
 		REGION_SUBTRACT (pScreen, &totalClip, &totalClip, &pWin->borderSize);
 	}
 	for (pWin = pChild; pWin; pWin = pWin->nextSib)
@@ -724,7 +739,7 @@ miValidateTree (pParent, pChild, kind)
 	    if (forward)
 	    {
 		for (pWin = pChild; pWin; pWin = pWin->nextSib)
-		    if (pWin->valdata && pWin->viewable)
+		    if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin))
 			REGION_APPEND( pScreen, &childUnion,
 						   &pWin->borderSize);
 	    }
@@ -733,7 +748,7 @@ miValidateTree (pParent, pChild, kind)
 		pWin = pParent->lastChild;
 		while (1)
 		{
-		    if (pWin->valdata && pWin->viewable)
+		    if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin))
 			REGION_APPEND( pScreen, &childUnion,
 						   &pWin->borderSize);
 		    if (pWin == pChild)
@@ -757,7 +772,7 @@ miValidateTree (pParent, pChild, kind)
 					&totalClip,
  					&pWin->borderSize);
 		miComputeClips (pWin, pScreen, &childClip, kind, &exposed);
-		if (overlap)
+		if (overlap && !TreatAsTransparent (pWin))
 		{
 		    REGION_SUBTRACT( pScreen, &totalClip,
 				       	   &totalClip,

-- 
keith.packard at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://lists.x.org/archives/xorg/attachments/20070307/9307e16f/attachment.pgp>


More information about the xorg mailing list