summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Fourdan <ofourdan@redhat.com>2016-11-16 15:31:28 +0100
committerOlivier Fourdan <ofourdan@redhat.com>2017-01-09 11:51:25 +0100
commitffa7aa95d8ec62efbbc20e5aacc29d52555f3145 (patch)
tree489d6a4261afae5d992396f30c00e3ccfb58b54c
parent55093e304ec0c8cdc287ed933f4d78ca6eea5e07 (diff)
downloadclutter-ffa7aa95d8ec62efbbc20e5aacc29d52555f3145.tar.gz
gdk: stage: Use gdk for the Wayland subsurface
GDK has all the bits required to deal with the subsurface, by using the GDK Wayland API instead of the Wayland API directly, we can save a few lines of code. https://bugzilla.gnome.org/show_bug.cgi?id=774546
-rw-r--r--clutter/gdk/clutter-stage-gdk.c137
-rw-r--r--clutter/gdk/clutter-stage-gdk.h4
2 files changed, 50 insertions, 91 deletions
diff --git a/clutter/gdk/clutter-stage-gdk.c b/clutter/gdk/clutter-stage-gdk.c
index 742de5867..0a40a5ee2 100644
--- a/clutter/gdk/clutter-stage-gdk.c
+++ b/clutter/gdk/clutter-stage-gdk.c
@@ -63,6 +63,7 @@
#include "clutter-stage-private.h"
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
+static int clutter_stage_gdk_get_scale_factor (ClutterStageWindow *stage_window);
static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
@@ -164,7 +165,7 @@ clutter_stage_gdk_resize (ClutterStageWindow *stage_window,
#if defined(GDK_WINDOWING_WAYLAND) && defined(COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
else if (GDK_IS_WAYLAND_WINDOW (stage_gdk->window))
{
- int scale = gdk_window_get_scale_factor (stage_gdk->window);
+ int scale = clutter_stage_gdk_get_scale_factor (CLUTTER_STAGE_WINDOW (stage_gdk));
cogl_wayland_onscreen_resize (CLUTTER_STAGE_COGL (stage_gdk)->onscreen,
width * scale, height * scale, 0, 0);
}
@@ -208,11 +209,6 @@ clutter_stage_gdk_unrealize (ClutterStageWindow *stage_window)
}
clutter_stage_window_parent_iface->unrealize (stage_window);
-
-#if defined(GDK_WINDOWING_WAYLAND)
- g_clear_pointer (&stage_gdk->subsurface, wl_subsurface_destroy);
- g_clear_pointer (&stage_gdk->clutter_surface, wl_surface_destroy);
-#endif
}
#if defined(GDK_WINDOWING_WAYLAND)
@@ -220,47 +216,42 @@ static struct wl_surface *
clutter_stage_gdk_wayland_surface (ClutterStageGdk *stage_gdk)
{
GdkDisplay *display;
- struct wl_compositor *compositor;
- struct wl_surface *parent_surface;
- struct wl_region *input_region;
- gint x, y;
+ cairo_region_t *input_region;
+ cairo_rectangle_int_t empty_rect = { 0, };
+ GdkWindowAttr attributes;
+ gint attributes_mask;
if (!stage_gdk->foreign_window ||
gdk_window_get_window_type (stage_gdk->window) != GDK_WINDOW_CHILD)
return gdk_wayland_window_get_wl_surface (stage_gdk->window);
- if (stage_gdk->clutter_surface)
- return stage_gdk->clutter_surface;
+ if (stage_gdk->subsurface)
+ goto out;
/* On Wayland if we render to a foreign window, we setup our own
* surface to not render in the same buffers as the embedding
* framework.
*/
- display = gdk_display_get_default ();
- compositor = gdk_wayland_display_get_wl_compositor (display);
- stage_gdk->clutter_surface = wl_compositor_create_surface (compositor);
+ display = gdk_window_get_display (stage_gdk->window);
+
+ attributes.window_type = GDK_WINDOW_SUBSURFACE;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.x = 0;
+ attributes.y = 0;
+ attributes_mask = GDK_WA_X | GDK_WA_Y;
+
+ stage_gdk->subsurface = gdk_window_new (stage_gdk->window, &attributes, attributes_mask);
+ gdk_window_set_transient_for (stage_gdk->subsurface, stage_gdk->window);
/* Since we run inside GDK, we can let the embedding framework
* dispatch the events to Clutter. For that to happen we need to
* disable input on our surface. */
- input_region = wl_compositor_create_region (compositor);
- wl_region_add (input_region, 0, 0, 0, 0);
- wl_surface_set_input_region (stage_gdk->clutter_surface, input_region);
- wl_region_destroy (input_region);
+ input_region = cairo_region_create_rectangle (&empty_rect);
+ gdk_window_input_shape_combine_region (stage_gdk->subsurface, input_region, 0, 0);
+ cairo_region_destroy (input_region);
- wl_surface_set_buffer_scale (stage_gdk->clutter_surface,
- gdk_window_get_scale_factor (stage_gdk->window));
-
- parent_surface = gdk_wayland_window_get_wl_surface (gdk_window_get_toplevel (stage_gdk->window));
- stage_gdk->subsurface = wl_subcompositor_get_subsurface (stage_gdk->subcompositor,
- stage_gdk->clutter_surface,
- parent_surface);
-
- gdk_window_get_origin (stage_gdk->window, &x, &y);
- wl_subsurface_set_position (stage_gdk->subsurface, x, y);
- wl_subsurface_set_desync (stage_gdk->subsurface);
-
- return stage_gdk->clutter_surface;
+out:
+ return gdk_wayland_window_get_wl_surface (stage_gdk->subsurface);
}
#endif
@@ -277,18 +268,13 @@ _clutter_stage_gdk_notify_configure (ClutterStageGdk *stage_gdk,
if (stage_gdk->foreign_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_gdk);
- int scale = gdk_window_get_scale_factor (stage_gdk->window);
+ int scale = clutter_stage_gdk_get_scale_factor (CLUTTER_STAGE_WINDOW (stage_gdk));
#if defined(GDK_WINDOWING_WAYLAND) && defined(COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
if (GDK_IS_WAYLAND_WINDOW (stage_gdk->window) &&
gdk_window_get_window_type (stage_gdk->window) == GDK_WINDOW_CHILD &&
stage_gdk->subsurface)
{
- gint rx, ry;
- gdk_window_get_origin (stage_gdk->window, &rx, &ry);
- wl_subsurface_set_position (stage_gdk->subsurface, rx, ry);
-
- wl_surface_set_buffer_scale (stage_gdk->clutter_surface, scale);
cogl_wayland_onscreen_resize (stage_cogl->onscreen,
width * scale, height * scale, 0, 0);
}
@@ -432,10 +418,9 @@ clutter_stage_gdk_realize (ClutterStageWindow *stage_window)
g_object_set_data (G_OBJECT (stage_gdk->window), "clutter-stage-window", stage_gdk);
- scale = gdk_window_get_scale_factor (stage_gdk->window);
+ scale = clutter_stage_gdk_get_scale_factor (CLUTTER_STAGE_WINDOW (stage_gdk));
stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context,
width * scale, height * scale);
-
#if defined(GDK_WINDOWING_X11) && defined(COGL_HAS_XLIB_SUPPORT)
if (GDK_IS_X11_WINDOW (stage_gdk->window))
{
@@ -602,6 +587,11 @@ clutter_stage_gdk_show (ClutterStageWindow *stage_window,
clutter_actor_map (CLUTTER_ACTOR (CLUTTER_STAGE_COGL (stage_gdk)->wrapper));
+#if defined(GDK_WINDOWING_WAYLAND) && defined(COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
+ if (GDK_IS_WAYLAND_WINDOW (stage_gdk->subsurface))
+ gdk_window_show (stage_gdk->subsurface);
+#endif
+
/* Foreign window should be shown by the embedding framework. */
if (!stage_gdk->foreign_window)
{
@@ -622,6 +612,11 @@ clutter_stage_gdk_hide (ClutterStageWindow *stage_window)
clutter_actor_unmap (CLUTTER_ACTOR (CLUTTER_STAGE_COGL (stage_gdk)->wrapper));
/* Foreign window should be hidden by the embedding framework. */
+#if defined(GDK_WINDOWING_WAYLAND) && defined(COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
+ if (GDK_IS_WAYLAND_WINDOW (stage_gdk->subsurface))
+ gdk_window_hide (stage_gdk->subsurface);
+#endif
+
if (!stage_gdk->foreign_window)
gdk_window_hide (stage_gdk->window);
}
@@ -640,6 +635,12 @@ clutter_stage_gdk_get_scale_factor (ClutterStageWindow *stage_window)
if (stage_gdk->window == NULL)
return 1;
+/* For Wayland using a subsurface, scaling is handled by gdk */
+#if defined(GDK_WINDOWING_WAYLAND) && defined(COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
+ if (GDK_IS_WAYLAND_WINDOW (stage_gdk->subsurface))
+ return 1;
+ else
+#endif
return gdk_window_get_scale_factor (stage_gdk->window);
}
@@ -704,6 +705,14 @@ clutter_stage_gdk_dispose (GObject *gobject)
{
ClutterStageGdk *stage_gdk = CLUTTER_STAGE_GDK (gobject);
+#if defined(GDK_WINDOWING_WAYLAND) && defined(COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
+ if (GDK_IS_WAYLAND_WINDOW (stage_gdk->subsurface))
+ {
+ gdk_window_destroy (stage_gdk->subsurface);
+ stage_gdk->subsurface = NULL;
+ }
+#endif
+
if (stage_gdk->window != NULL)
{
g_object_set_data (G_OBJECT (stage_gdk->window),
@@ -732,57 +741,9 @@ clutter_stage_gdk_class_init (ClutterStageGdkClass *klass)
gobject_class->dispose = clutter_stage_gdk_dispose;
}
-#if defined(GDK_WINDOWING_WAYLAND)
-static void
-registry_handle_global (void *data,
- struct wl_registry *registry,
- uint32_t name,
- const char *interface,
- uint32_t version)
-{
- ClutterStageGdk *stage_gdk = data;
-
- if (strcmp (interface, "wl_subcompositor") == 0)
- {
- stage_gdk->subcompositor = wl_registry_bind (registry,
- name,
- &wl_subcompositor_interface,
- 1);
- }
-}
-
-static void
-registry_handle_global_remove (void *data,
- struct wl_registry *registry,
- uint32_t name)
-{
-}
-
-static const struct wl_registry_listener registry_listener = {
- registry_handle_global,
- registry_handle_global_remove
-};
-#endif
-
static void
clutter_stage_gdk_init (ClutterStageGdk *stage)
{
-#if defined(GDK_WINDOWING_WAYLAND)
- {
- GdkDisplay *gdk_display = gdk_display_get_default ();
- if (GDK_IS_WAYLAND_DISPLAY (gdk_display))
- {
- struct wl_display *display;
- struct wl_registry *registry;
-
- display = gdk_wayland_display_get_wl_display (gdk_display);
- registry = wl_display_get_registry (display);
- wl_registry_add_listener (registry, &registry_listener, stage);
-
- wl_display_roundtrip (display);
- }
- }
-#endif
}
static void
diff --git a/clutter/gdk/clutter-stage-gdk.h b/clutter/gdk/clutter-stage-gdk.h
index effc3098c..061c611da 100644
--- a/clutter/gdk/clutter-stage-gdk.h
+++ b/clutter/gdk/clutter-stage-gdk.h
@@ -52,9 +52,7 @@ struct _ClutterStageGdk
gboolean foreign_window;
#if defined(GDK_WINDOWING_WAYLAND)
- struct wl_subcompositor *subcompositor;
- struct wl_surface *clutter_surface;
- struct wl_subsurface *subsurface;
+ GdkWindow *subsurface;
#endif
};