From ad2f96ff482d1cde7a91ffc30bbc81e2b9bde01b Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 26 Feb 2014 00:02:04 +0100 Subject: [PATCH] Gdk: fix wrong user_data handling in resize_cairo_surface() Instead of destroying the surface in the backend if this is unable to resize, let the core code do it, and do it properly. Based on a patch by Benjamin Otte. https://bugzilla.gnome.org/show_bug.cgi?id=725172 --- gdk/broadway/gdkwindow-broadway.c | 6 ++---- gdk/gdkoffscreenwindow.c | 4 ++-- gdk/gdkwindow.c | 18 +++++++++--------- gdk/gdkwindowimpl.h | 12 ++++++++---- gdk/quartz/gdkwindow-quartz.c | 6 ++---- gdk/wayland/gdkwindow-wayland.c | 4 ++-- gdk/win32/gdkwindow-win32.c | 6 ++---- gdk/x11/gdkwindow-x11.c | 4 ++-- 8 files changed, 29 insertions(+), 31 deletions(-) diff --git a/gdk/broadway/gdkwindow-broadway.c b/gdk/broadway/gdkwindow-broadway.c index bfcba8a9ea..dae6ebf4be 100644 --- a/gdk/broadway/gdkwindow-broadway.c +++ b/gdk/broadway/gdkwindow-broadway.c @@ -365,16 +365,14 @@ _gdk_broadway_window_destroy (GdkWindow *window, impl->id); } -static cairo_surface_t * +static gboolean gdk_window_broadway_resize_cairo_surface (GdkWindow *window, cairo_surface_t *surface, gint width, gint height) { /* Image surfaces cannot be resized */ - cairo_surface_destroy (surface); - - return NULL; + return FALSE; } static void diff --git a/gdk/gdkoffscreenwindow.c b/gdk/gdkoffscreenwindow.c index cd32d595ec..ead3dfae26 100644 --- a/gdk/gdkoffscreenwindow.c +++ b/gdk/gdkoffscreenwindow.c @@ -550,7 +550,7 @@ gdk_offscreen_window_queue_antiexpose (GdkWindow *window, return FALSE; } -static cairo_surface_t * +static gboolean gdk_offscreen_window_resize_cairo_surface (GdkWindow *window, cairo_surface_t *surface, gint width, @@ -559,7 +559,7 @@ gdk_offscreen_window_resize_cairo_surface (GdkWindow *window, /* No-op. The surface gets resized in * gdk_offscreen_window_move_resize_internal(). */ - return surface; + return TRUE; } /** diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 3f89d860b9..f02eb82ef0 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -1003,17 +1003,17 @@ recompute_visible_regions_internal (GdkWindow *private, } } - if (private->cairo_surface && gdk_window_has_impl (private)) + if (private->cairo_surface) { - GdkWindowImplClass *iface = GDK_WINDOW_IMPL_GET_CLASS (private->impl); - - private->cairo_surface = iface->resize_cairo_surface (private, - private->cairo_surface, - private->width, - private->height); + if (!gdk_window_has_impl (private) || + !GDK_WINDOW_IMPL_GET_CLASS (private->impl)->resize_cairo_surface (private, + private->cairo_surface, + private->width, + private->height)) + { + gdk_window_drop_cairo_surface (private); + } } - else if (private->cairo_surface) - gdk_window_drop_cairo_surface (private); } /* Call this when private has changed in one or more of these ways: diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h index ab04985c98..ed7d4c55c0 100644 --- a/gdk/gdkwindowimpl.h +++ b/gdk/gdkwindowimpl.h @@ -158,10 +158,14 @@ struct _GdkWindowImplClass */ void (*destroy_foreign) (GdkWindow *window); - cairo_surface_t * (* resize_cairo_surface) (GdkWindow *window, - cairo_surface_t *surface, - gint width, - gint height); + /* Resizes @surface to a new size. If successful, return %TRUE. + * If the backend cannot resize surfaces, return %FALSE and a new + * surface will be created instead. + */ + gboolean (* resize_cairo_surface) (GdkWindow *window, + cairo_surface_t *surface, + gint width, + gint height); /* optional */ gboolean (* beep) (GdkWindow *window); diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index fe798e5b2a..7baf8a3b33 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -1104,16 +1104,14 @@ gdk_quartz_window_destroy (GdkWindow *window, } } -static cairo_surface_t * +static gboolean gdk_window_quartz_resize_cairo_surface (GdkWindow *window, cairo_surface_t *surface, gint width, gint height) { /* Quartz surfaces cannot be resized */ - cairo_surface_destroy (surface); - - return NULL; + return FALSE; } static void diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 82dafb21ff..a97ec8ca07 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -1481,14 +1481,14 @@ gdk_window_wayland_destroy_foreign (GdkWindow *window) { } -static cairo_surface_t * +static gboolean gdk_window_wayland_resize_cairo_surface (GdkWindow *window, cairo_surface_t *surface, gint width, gint height) { /* cairo image surfaces cannot be resized */ - return NULL; + return FALSE; } static cairo_region_t * diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index 18e35cddb2..72266e76ad 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -796,16 +796,14 @@ gdk_win32_window_destroy (GdkWindow *window, } } -static cairo_surface_t * +static gboolean gdk_win32_window_resize_cairo_surface (GdkWindow *window, cairo_surface_t *surface, gint width, gint height) { /* XXX: Make Cairo surface use DC clip */ - cairo_surface_destroy (surface); - - return NULL; + return FALSE; } static void diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index c9328133c1..337c82e5d3 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -1337,7 +1337,7 @@ gdk_x11_window_destroy (GdkWindow *window, XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); } -static cairo_surface_t * +static gboolean gdk_window_x11_resize_cairo_surface (GdkWindow *window, cairo_surface_t *surface, gint width, @@ -1345,7 +1345,7 @@ gdk_window_x11_resize_cairo_surface (GdkWindow *window, { cairo_xlib_surface_set_size (surface, width, height); - return surface; + return TRUE; } static void