From: Ville Syrjälä <[email protected]>

When window redirection is changed, UnmapWindow() is called internally,
which leads to windows temporarily getting unrealized. When a window is
unrealized, ClipNotify() is called with an empty clip. In the case of
Xv this leads to video overlays blinking off and on in a very annoying
fashion. Suppress these ClipNotify() calls around the UnmapWindow()
calls made from the composite code.

Signed-off-by: Ville Syrjälä <[email protected]>
---
I'm not 100% sure about the safety of this patch, hence to RFC. However
it seems to me that all other windows whose clipping may be affected
should get a ClipNotify via ValidateTree. And the redirected window
itself will get a ClipNotity again when it gets remapped.

 composite/compalloc.c |    6 ++++++
 dix/window.c          |   24 ++++++++++++++++++++++++
 include/window.h      |    4 ++++
 mi/mioverlay.c        |    3 ++-
 mi/miwindow.c         |    3 ++-
 5 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 246e4c5..0ae8c3b 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -130,7 +130,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int 
update)
        if (wasMapped)
        {
            DisableMapUnmapEvents (pWin);
+           DisableUnrealizeClipNotify ();
            UnmapWindow (pWin, FALSE);
+           EnableUnrealizeClipNotify ();
            EnableMapUnmapEvents (pWin);
        }
 
@@ -159,7 +161,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int 
update)
        if (pWin->mapped) 
        {
            DisableMapUnmapEvents (pWin);
+           DisableUnrealizeClipNotify ();
            UnmapWindow (pWin, FALSE);
+           EnableUnrealizeClipNotify ();
            EnableMapUnmapEvents (pWin);
        }
        if (cw->damageRegistered)
@@ -217,7 +221,9 @@ compFreeClientWindow (WindowPtr pWin, XID id)
        if (wasMapped)
        {
            DisableMapUnmapEvents (pWin);
+           DisableUnrealizeClipNotify ();
            UnmapWindow (pWin, FALSE);
+           EnableUnrealizeClipNotify ();
            EnableMapUnmapEvents (pWin);
        }
     
diff --git a/dix/window.c b/dix/window.c
index 0362dce..26e9c5f 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -2575,6 +2575,30 @@ MapUnmapEventsEnabled(WindowPtr pWin)
     return pWin != windowDisableMapUnmapEvents;
 }
 
+static Bool disableUnrealizeClipNotify;
+
+void
+DisableUnrealizeClipNotify(void)
+{
+    assert (!disableUnrealizeClipNotify);
+
+    disableUnrealizeClipNotify = TRUE;
+}
+
+void
+EnableUnrealizeClipNotify(void)
+{
+    assert (disableUnrealizeClipNotify);
+
+    disableUnrealizeClipNotify = FALSE;
+}
+
+Bool
+UnrealizeClipNotifyEnabled(void)
+{
+    return !disableUnrealizeClipNotify;
+}
+
 /*****
  * MapWindow
  *    If some other client has selected SubStructureReDirect on the parent
diff --git a/include/window.h b/include/window.h
index 6fb2f8c..221d9f3 100644
--- a/include/window.h
+++ b/include/window.h
@@ -266,4 +266,8 @@ extern _X_EXPORT void DisableMapUnmapEvents(
 extern _X_EXPORT void EnableMapUnmapEvents(
     WindowPtr /* pWin */ );
 
+extern void DisableUnrealizeClipNotify(void);
+extern void EnableUnrealizeClipNotify(void);
+extern Bool UnrealizeClipNotifyEnabled(void);
+
 #endif /* WINDOW_H */
diff --git a/mi/mioverlay.c b/mi/mioverlay.c
index 766c5e7..61a1bed 100644
--- a/mi/mioverlay.c
+++ b/mi/mioverlay.c
@@ -711,7 +711,8 @@ miOverlayMarkUnrealizedWindow(
        miOverlayTreePtr pTree;
 
         RegionEmpty(&pChild->clipList);
-        if (pChild->drawable.pScreen->ClipNotify)
+        if (pChild->drawable.pScreen->ClipNotify &&
+           UnrealizeClipNotifyEnabled())
             (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
         RegionEmpty(&pChild->borderClip);
        if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
diff --git a/mi/miwindow.c b/mi/miwindow.c
index 25dd1c0..ad15e65 100644
--- a/mi/miwindow.c
+++ b/mi/miwindow.c
@@ -805,7 +805,8 @@ miMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, 
Bool fromConfigure)
     if ((pChild != pWin) || fromConfigure)
     {
        RegionEmpty(&pChild->clipList);
-       if (pChild->drawable.pScreen->ClipNotify)
+       if (pChild->drawable.pScreen->ClipNotify &&
+           UnrealizeClipNotifyEnabled())
            (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
        RegionEmpty(&pChild->borderClip);
     }
-- 
1.7.2.2

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to