summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorJasper St. Pierre <jstpierre@mecheye.net>2013-05-14 16:23:33 -0400
committerJasper St. Pierre <jstpierre@mecheye.net>2013-08-28 10:33:57 -0400
commit08fbba45581bc7debb76264c9aac8f51eba5c960 (patch)
tree8d13659659b16e1487a71e04406891fdd65e8b47 /gdk
parent64cf8b731ea294615d877d43ad8df406d0013d00 (diff)
downloadgtk+-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.c36
-rw-r--r--gdk/gdkwindow.h4
-rw-r--r--gdk/gdkwindowimpl.h3
-rw-r--r--gdk/wayland/gdkwindow-wayland.c41
-rw-r--r--gdk/x11/gdkwindow-x11.c46
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;
}