window: copy back window surface data when the implicit paint is flushed

When an implicit paint is flushed during expose, e.g. because a
non-double buffered widget is painting, make sure to copy the existing
data from the window surface we rendered before flushing back to the
paint surface, instead of using an empty base.
Code was already handling that (and said so in the comment), but only
when no implicit paint was used at all, and not in the case when it's
flushed mid-expose.
This commit is contained in:
Cosimo Cecchi 2011-12-06 18:41:33 -05:00 committed by Alexander Larsson
parent 2fad8eb0c3
commit 8f4f7faa11

View File

@ -2959,21 +2959,25 @@ gdk_window_begin_paint_region (GdkWindow *window,
gdk_window_get_content (window),
MAX (clip_box.width, 1),
MAX (clip_box.height, 1));
/* Normally alpha backgrounded client side windows are composited on the implicit paint
by being drawn in back to front order. However, if implicit paints are not used, for
instance if it was flushed due to a non-double-buffered paint in the middle of the
expose we need to copy in the existing data here. */
if (!gdk_window_has_impl (window) && window->has_alpha_background)
{
cairo_t *cr = cairo_create (paint->surface);
gdk_cairo_set_source_window (cr, impl_window,
- (window->abs_x + clip_box.x),
- (window->abs_y + clip_box.y));
cairo_paint (cr);
cairo_destroy (cr);
}
}
/* Normally alpha backgrounded client side windows are composited on the implicit paint
by being drawn in back to front order. However, if implicit paints are not used, for
instance if it was flushed due to a non-double-buffered paint in the middle of the
expose we need to copy in the existing data here. */
if (!gdk_window_has_impl (window) &&
window->has_alpha_background &&
(!implicit_paint ||
(implicit_paint && implicit_paint->flushed)))
{
cairo_t *cr = cairo_create (paint->surface);
gdk_cairo_set_source_window (cr, impl_window,
- (window->abs_x + clip_box.x),
- (window->abs_y + clip_box.y));
cairo_paint (cr);
cairo_destroy (cr);
}
cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
for (list = window->paint_stack; list != NULL; list = list->next)