mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
Track direct window cairo access and avoid tricks when used
When a cairo surface is requested for direct window access (i.e. not when double-buffering) we can't really track when the actual drawing happens as cairo drawing is not virtualized. This means we can't properly flush any outstanding window moves or implicit paints. This actually causes problems with e.g. abiword (bug #606009) where they draw without double-buffering. If you press down it scrolls the window and then draws the caret, but the caret drawing does not flush the outstanding move from the scroll, so the caret gets drawn on the wrong screen. We fix this by never allowing either implicit paints or outstanding window moves on impl-windows where any windows related to it has an outstanding direct cairo surface. Luckily this is not very common so in practice this doesn't matter much.
This commit is contained in:
parent
269b0fe97f
commit
841fa47715
@ -273,6 +273,7 @@ struct _GdkWindowObject
|
||||
GdkRegion *input_shape;
|
||||
|
||||
cairo_surface_t *cairo_surface;
|
||||
guint outstanding_surfaces; /* only set on impl window */
|
||||
};
|
||||
|
||||
#define GDK_WINDOW_TYPE(d) (((GdkWindowObject*)(GDK_WINDOW (d)))->window_type)
|
||||
|
@ -2622,6 +2622,9 @@ gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
|
||||
private->implicit_paint != NULL)
|
||||
return FALSE; /* Don't stack implicit paints */
|
||||
|
||||
if (private->outstanding_surfaces != 0)
|
||||
return FALSE; /* May conflict with direct drawing to cairo surface */
|
||||
|
||||
/* Never do implicit paints for foreign windows, they don't need
|
||||
* double buffer combination since they have no client side children,
|
||||
* and creating pixmaps for them is risky since they could disappear
|
||||
@ -3327,7 +3330,7 @@ move_region_on_impl (GdkWindowObject *impl_window,
|
||||
gdk_region_destroy (exposing);
|
||||
}
|
||||
|
||||
if (1) /* Enable flicker free handling of moves. */
|
||||
if (impl_window->outstanding_surfaces == 0) /* Enable flicker free handling of moves. */
|
||||
append_move_region (impl_window, region, dx, dy);
|
||||
else
|
||||
do_move_region_bits_on_impl (impl_window,
|
||||
@ -4846,6 +4849,7 @@ gdk_window_cairo_surface_destroy (void *data)
|
||||
GdkWindowObject *private = (GdkWindowObject*) data;
|
||||
|
||||
private->cairo_surface = NULL;
|
||||
private->impl_window->outstanding_surfaces--;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
@ -4889,11 +4893,12 @@ gdk_window_ref_cairo_surface (GdkDrawable *drawable)
|
||||
|
||||
source = _gdk_drawable_get_source_drawable (drawable);
|
||||
|
||||
/* TODO: Avoid the typecheck crap by adding virtual call */
|
||||
private->cairo_surface = _gdk_drawable_create_cairo_surface (source, width, height);
|
||||
|
||||
if (private->cairo_surface)
|
||||
{
|
||||
private->impl_window->outstanding_surfaces++;
|
||||
|
||||
cairo_surface_set_device_offset (private->cairo_surface,
|
||||
private->abs_x,
|
||||
private->abs_y);
|
||||
|
Loading…
Reference in New Issue
Block a user