diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 6b45e4eed8..8eafcf6664 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -144,6 +144,8 @@ struct _GdkWindowImplWayland int margin_right; int margin_top; int margin_bottom; + + cairo_region_t *opaque_region; }; struct _GdkWindowImplWaylandClass @@ -808,6 +810,8 @@ gdk_window_impl_wayland_finalize (GObject *object) g_free (impl->title); + g_clear_pointer (&impl->opaque_region, cairo_region_destroy); + G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object); } @@ -898,6 +902,47 @@ gdk_wayland_window_sync_margin (GdkWindow *window) impl->margin_bottom); } +static struct wl_region * +wl_region_from_cairo_region (GdkWaylandDisplay *display, + cairo_region_t *region) +{ + struct wl_region *wl_region; + int i, n_rects; + + wl_region = wl_compositor_create_region (display->compositor); + if (wl_region == NULL) + return NULL; + + n_rects = cairo_region_num_rectangles (region); + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (region, i, &rect); + wl_region_add (wl_region, rect.x, rect.y, rect.width, rect.height); + } + + return wl_region; +} + +static void +gdk_wayland_window_sync_opaque_region (GdkWindow *window) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + struct wl_region *wl_region = NULL; + + if (!impl->surface) + return; + + if (impl->opaque_region != NULL) + wl_region = wl_region_from_cairo_region (GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)), + impl->opaque_region); + + wl_surface_set_opaque_region (impl->surface, wl_region); + + if (wl_region != NULL) + wl_region_destroy (wl_region); +} + static void surface_enter (void *data, struct wl_surface *wl_surface, @@ -936,10 +981,10 @@ gdk_wayland_window_create_surface (GdkWindow *window) GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); impl->surface = wl_compositor_create_surface (display_wayland->compositor); - wl_surface_set_user_data (impl->surface, window); - wl_surface_add_listener (impl->surface, - &surface_listener, window); + wl_surface_add_listener (impl->surface, &surface_listener, window); + + gdk_wayland_window_sync_opaque_region (window); } static void @@ -2091,48 +2136,18 @@ gdk_wayland_window_get_scale_factor (GdkWindow *window) return impl->scale; } -static struct wl_region * -wl_region_from_cairo_region (GdkWaylandDisplay *display, - cairo_region_t *region) -{ - struct wl_region *wl_region; - int i, n_rects; - - wl_region = wl_compositor_create_region (display->compositor); - if (wl_region == NULL) - return NULL; - - n_rects = cairo_region_num_rectangles (region); - for (i = 0; i < n_rects; i++) - { - cairo_rectangle_int_t rect; - cairo_region_get_rectangle (region, i, &rect); - wl_region_add (wl_region, rect.x, rect.y, rect.width, rect.height); - } - - return wl_region; -} - static void gdk_wayland_window_set_opaque_region (GdkWindow *window, cairo_region_t *region) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); - struct wl_region *wl_region = NULL; if (GDK_WINDOW_DESTROYED (window)) return; - if (!impl->surface) - gdk_wayland_window_create_surface (window); - - if (region != NULL) - wl_region = wl_region_from_cairo_region (GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)), region); - - wl_surface_set_opaque_region (impl->surface, wl_region); - - if (wl_region != NULL) - wl_region_destroy (wl_region); + g_clear_pointer (&impl->opaque_region, cairo_region_destroy); + impl->opaque_region = cairo_region_reference (region); + gdk_wayland_window_sync_opaque_region (window); } static void