mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-12 13:30:19 +00:00
gdk: Add opaque region setters
https://bugzilla.gnome.org/show_bug.cgi?id=706922
This commit is contained in:
parent
64cf8b731e
commit
08fbba4558
@ -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);
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5555,6 +5555,51 @@ gdk_x11_window_set_frame_sync_enabled (GdkWindow *window,
|
||||
GDK_WINDOW_IMPL_X11 (window->impl)->frame_sync_enabled = FALSE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user