diff options
author | Jasper St. Pierre <jstpierre@mecheye.net> | 2013-05-14 16:23:33 -0400 |
---|---|---|
committer | Jasper St. Pierre <jstpierre@mecheye.net> | 2013-08-28 10:33:57 -0400 |
commit | 08fbba45581bc7debb76264c9aac8f51eba5c960 (patch) | |
tree | 8d13659659b16e1487a71e04406891fdd65e8b47 /gdk | |
parent | 64cf8b731ea294615d877d43ad8df406d0013d00 (diff) | |
download | gtk+-08fbba45581bc7debb76264c9aac8f51eba5c960.tar.gz |
gdk: Add opaque region setters
https://bugzilla.gnome.org/show_bug.cgi?id=706922
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/gdkwindow.c | 36 | ||||
-rw-r--r-- | gdk/gdkwindow.h | 4 | ||||
-rw-r--r-- | gdk/gdkwindowimpl.h | 3 | ||||
-rw-r--r-- | gdk/wayland/gdkwindow-wayland.c | 41 | ||||
-rw-r--r-- | gdk/x11/gdkwindow-x11.c | 46 |
5 files changed, 130 insertions, 0 deletions
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index cf5d75113f..55f5bf2855 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -10787,3 +10787,39 @@ gdk_window_get_scale_factor (GdkWindow *window) return 1; } + +/** + * gdk_window_set_opaque_region: + * @window: a top-level or non-native #GdkWindow + * @region: a region + * + * For optimizization purposes, compositing window managers may + * like to not draw obscured regions of windows, or turn off blending + * during for these regions. With RGB windows with no transparency, + * this is just the shape of the window, but with ARGB32 windows, the + * compositor does not know what regions of the window are transparent + * or not. + * + * This function only works for toplevel windows. + * + * GTK+ will automatically update this property automatically if + * the @window background is opaque, as we know where the opaque regions + * are. If your window background is not opaque, please update this + * property in your #GtkWindow::style_updated handler. + * + * Since: 3.10 + */ +void +gdk_window_set_opaque_region (GdkWindow *window, + cairo_region_t *region) +{ + GdkWindowImplClass *impl_class; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (!GDK_WINDOW_DESTROYED (window)); + + impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl); + + if (impl_class->set_opaque_region) + return impl_class->set_opaque_region (window, region); +} diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h index eff71783cc..de7872e4bb 100644 --- a/gdk/gdkwindow.h +++ b/gdk/gdkwindow.h @@ -1086,6 +1086,10 @@ gboolean gdk_window_get_support_multidevice (GdkWindow *window); GDK_AVAILABLE_IN_3_8 GdkFrameClock* gdk_window_get_frame_clock (GdkWindow *window); +GDK_AVAILABLE_IN_3_10 +void gdk_window_set_opaque_region (GdkWindow *window, + cairo_region_t *region); + G_END_DECLS #endif /* __GDK_WINDOW_H__ */ diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h index 97ac21ce07..b0b43b9105 100644 --- a/gdk/gdkwindowimpl.h +++ b/gdk/gdkwindowimpl.h @@ -292,6 +292,9 @@ struct _GdkWindowImplClass GdkAtom property); gint (* get_scale_factor) (GdkWindow *window); + + void (* set_opaque_region) (GdkWindow *window, + cairo_region_t *region); }; /* Interface Functions */ diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index acb29e3f7f..d2d0b644f5 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -2020,6 +2020,46 @@ 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; + + if (GDK_WINDOW_DESTROYED (window)) + return; + + wl_region = wl_region_from_cairo_region (GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)), region); + if (wl_region == NULL) + return; + + wl_surface_set_opaque_region (impl->surface, wl_region); + wl_region_destroy (wl_region); +} + static void _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass) @@ -2109,6 +2149,7 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass) impl_class->change_property = gdk_wayland_window_change_property; impl_class->delete_property = gdk_wayland_window_delete_property; impl_class->get_scale_factor = gdk_wayland_window_get_scale_factor; + impl_class->set_opaque_region = gdk_wayland_window_set_opaque_region; } diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index cff720eeed..a88cf8e242 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -5556,6 +5556,51 @@ gdk_x11_window_set_frame_sync_enabled (GdkWindow *window, } static void +gdk_x11_window_set_opaque_region (GdkWindow *window, + cairo_region_t *region) +{ + GdkDisplay *display; + + int nitems; + gulong *data; + + if (region != NULL) + { + int i, nrects; + + nrects = cairo_region_num_rectangles (region); + nitems = nrects * 4; + data = g_new (gulong, nitems); + + for (i = 0; i < nrects; i++) + { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (region, i, &rect); + data[i+0] = rect.x; + data[i+1] = rect.y; + data[i+2] = rect.width; + data[i+3] = rect.height; + } + } + else + { + nitems = 0; + data = NULL; + } + + display = gdk_window_get_display (window); + + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_OPAQUE_REGION"), + XA_CARDINAL, 32, PropModeReplace, + (guchar *) data, nitems); + + if (data != NULL) + g_free (data); +} + +static void gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -5643,4 +5688,5 @@ gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass) impl_class->change_property = _gdk_x11_window_change_property; impl_class->delete_property = _gdk_x11_window_delete_property; impl_class->get_scale_factor = gdk_x11_window_get_scale_factor; + impl_class->set_opaque_region = gdk_x11_window_set_opaque_region; } |