[gtk+/client-side-windows: 197/197] Handle flushing implicit paint while there is a paint outstanding



commit 8a689f2e15411572b4bc8e5db65e625237ebfdcd
Author: Alexander Larsson <alexl redhat com>
Date:   Tue May 26 11:30:46 2009 +0200

    Handle flushing implicit paint while there is a paint outstanding
    
    If a native window or a window with a native subwindow is moved or resized
    then the client window moves and implicit paints need to be flushed since
    the native window move will copy/overwrite data. This may happen while there
    is an outstanding paint if the move is inside an expose event (weird, but
    flash embedded in webkit hit this).
    
    Right now we're asserting here, but the right fix is to allow this but
    to not flush the parts that are currently in a (non-implicit) paint. This
    means we flush all results from previous not-yet-flushed exposes, but not
    the ones being drawn.
---
 gdk/gdkwindow.c |   19 ++++++++++++++-----
 1 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index d2798ba..d20cb44 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -2031,7 +2031,8 @@ gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
 }
 
 /* Ensure that all content related to this (sub)window is pushed to the
-   native region */
+   native region. If there is an active paint then that area is not
+   pushed, in order to not show partially finished double buffers. */
 static void
 gdk_window_flush_implicit_paint (GdkWindow *window)
 {
@@ -2040,19 +2041,27 @@ gdk_window_flush_implicit_paint (GdkWindow *window)
   GdkWindowPaint *paint;
   GdkRegion *region;
   GdkGC *tmp_gc;
+  GSList *list;
 
-  /* Ensure that there is no explicit paint region. */
-  g_assert (private->paint_stack == NULL);
-  
   impl_window = gdk_window_get_impl_window (private);
   if (impl_window->implicit_paint == NULL)
     return;
 
   paint = impl_window->implicit_paint;
   region = gdk_region_copy (private->clip_region_with_children);
+
+  /* Don't flush active double buffers, as that may show partially done
+   * rendering */
+  for (list = private->paint_stack; list != NULL; list = list->next)
+    {
+      GdkWindowPaint *tmp_paint = list->data;
+
+      gdk_region_subtract (region, tmp_paint->region);
+    }
+
   gdk_region_offset (region, private->abs_x, private->abs_y);
   gdk_region_intersect (region, paint->region);
-  
+
   if (!gdk_region_empty (region))
     {
       /* Some regions are valid, push these to window now */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]