summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ådahl <jadahl@gmail.com>2017-12-20 17:40:22 +0800
committerJonas Ådahl <jadahl@gmail.com>2018-02-23 18:57:40 +0800
commit704b73b04125a11e5bb004b1857975f252dc029c (patch)
tree3768665ae417e26608a4bf691647701cc000e223
parentbd5e36cf0e0f2337ab595648a1d31f5e4fd9a588 (diff)
downloadmutter-704b73b04125a11e5bb004b1857975f252dc029c.tar.gz
wayland: Restructure surface role building blocks code
This commit moves out non-core wl_surface related code into separate code units, while renaming types to fit a common scheme. The changes done are: * ClutterActor based surface roles built upon MetaWalyandSurfaceRoleActorSurface. This object has been renamed to MetaWaylandActorSurface and related functionality has moved into meta-wayland-actor-surface.c. * The code related to roles backed by a MetaWindow (i.e. built upon MetaWaylandShellSurface) was moved into meta-wayland-shell-surface.c * The majority of subsurface related code was moved into into meta-wayland-subsurface.c and the object was renamed MetaWaylandSubsurface. https://gitlab.gnome.org/GNOME/mutter/merge_requests/5 https://bugzilla.gnome.org/show_bug.cgi?id=791938
-rw-r--r--src/Makefile.am6
-rw-r--r--src/wayland/meta-wayland-actor-surface.c103
-rw-r--r--src/wayland/meta-wayland-actor-surface.h37
-rw-r--r--src/wayland/meta-wayland-shell-surface.c127
-rw-r--r--src/wayland/meta-wayland-shell-surface.h64
-rw-r--r--src/wayland/meta-wayland-subsurface.c429
-rw-r--r--src/wayland/meta-wayland-subsurface.h36
-rw-r--r--src/wayland/meta-wayland-surface.c629
-rw-r--r--src/wayland/meta-wayland-surface.h45
-rw-r--r--src/wayland/meta-wayland-wl-shell.h2
-rw-r--r--src/wayland/meta-wayland-xdg-shell.h2
-rw-r--r--src/wayland/meta-wayland.c2
12 files changed, 834 insertions, 648 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index e89823180..617aada1e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -434,6 +434,12 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES += \
wayland/meta-wayland-surface-role-cursor.h \
wayland/meta-wayland-surface-role-tablet-cursor.c \
wayland/meta-wayland-surface-role-tablet-cursor.h \
+ wayland/meta-wayland-actor-surface.c \
+ wayland/meta-wayland-actor-surface.h \
+ wayland/meta-wayland-subsurface.c \
+ wayland/meta-wayland-subsurface.h \
+ wayland/meta-wayland-shell-surface.c \
+ wayland/meta-wayland-shell-surface.h \
wayland/meta-wayland-text-input.c \
wayland/meta-wayland-text-input.h \
wayland/meta-wayland-types.h \
diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c
new file mode 100644
index 000000000..a07d0d5e9
--- /dev/null
+++ b/src/wayland/meta-wayland-actor-surface.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2012,2013 Intel Corporation
+ * Copyright (C) 2013-2017 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "wayland/meta-wayland-actor-surface.h"
+
+#include "compositor/meta-surface-actor-wayland.h"
+#include "wayland/meta-wayland-surface.h"
+
+G_DEFINE_TYPE (MetaWaylandActorSurface,
+ meta_wayland_actor_surface,
+ META_TYPE_WAYLAND_SURFACE_ROLE)
+
+static void
+meta_wayland_actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
+{
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+ MetaSurfaceActorWayland *surface_actor =
+ META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
+
+ meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
+ &surface->pending_frame_callback_list);
+ wl_list_init (&surface->pending_frame_callback_list);
+}
+
+static void
+queue_surface_actor_frame_callbacks (MetaWaylandSurface *surface,
+ MetaWaylandPendingState *pending)
+{
+ MetaSurfaceActorWayland *surface_actor =
+ META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
+
+ meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
+ &pending->frame_callback_list);
+ wl_list_init (&pending->frame_callback_list);
+}
+
+static void
+meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role,
+ MetaWaylandPendingState *pending)
+{
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+ MetaWaylandSurface *toplevel_surface;
+
+ queue_surface_actor_frame_callbacks (surface, pending);
+
+ toplevel_surface = meta_wayland_surface_get_toplevel (surface);
+ if (!toplevel_surface || !toplevel_surface->window)
+ return;
+
+ meta_surface_actor_wayland_sync_state (
+ META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
+}
+
+static gboolean
+meta_wayland_actor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role,
+ MetaLogicalMonitor *logical_monitor)
+{
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+ MetaSurfaceActorWayland *actor =
+ META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
+
+ return meta_surface_actor_wayland_is_on_monitor (actor, logical_monitor);
+}
+
+static void
+meta_wayland_actor_surface_init (MetaWaylandActorSurface *role)
+{
+}
+
+static void
+meta_wayland_actor_surface_class_init (MetaWaylandActorSurfaceClass *klass)
+{
+ MetaWaylandSurfaceRoleClass *surface_role_class =
+ META_WAYLAND_SURFACE_ROLE_CLASS (klass);
+
+ surface_role_class->assigned = meta_wayland_actor_surface_assigned;
+ surface_role_class->commit = meta_wayland_actor_surface_commit;
+ surface_role_class->is_on_logical_monitor =
+ meta_wayland_actor_surface_is_on_logical_monitor;
+}
diff --git a/src/wayland/meta-wayland-actor-surface.h b/src/wayland/meta-wayland-actor-surface.h
new file mode 100644
index 000000000..9f0f79e7b
--- /dev/null
+++ b/src/wayland/meta-wayland-actor-surface.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012,2013 Intel Corporation
+ * Copyright (C) 2013-2017 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_WAYLAND_ACTOR_SURFACE_H
+#define META_WAYLAND_ACTOR_SURFACE_H
+
+#include "wayland/meta-wayland-surface.h"
+
+#define META_TYPE_WAYLAND_ACTOR_SURFACE (meta_wayland_actor_surface_get_type ())
+G_DECLARE_DERIVABLE_TYPE (MetaWaylandActorSurface,
+ meta_wayland_actor_surface,
+ META, WAYLAND_ACTOR_SURFACE,
+ MetaWaylandSurfaceRole)
+
+struct _MetaWaylandActorSurfaceClass
+{
+ MetaWaylandSurfaceRoleClass parent_class;
+};
+
+#endif /* META_WAYLAND_ACTOR_SURFACE_H */
diff --git a/src/wayland/meta-wayland-shell-surface.c b/src/wayland/meta-wayland-shell-surface.c
new file mode 100644
index 000000000..023ece00a
--- /dev/null
+++ b/src/wayland/meta-wayland-shell-surface.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2012,2013 Intel Corporation
+ * Copyright (C) 2013-2017 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "wayland/meta-wayland-shell-surface.h"
+
+#include "compositor/meta-surface-actor-wayland.h"
+#include "wayland/meta-wayland-actor-surface.h"
+#include "wayland/meta-wayland-buffer.h"
+
+G_DEFINE_TYPE (MetaWaylandShellSurface,
+ meta_wayland_shell_surface,
+ META_TYPE_WAYLAND_ACTOR_SURFACE)
+
+void
+meta_wayland_shell_surface_configure (MetaWaylandShellSurface *shell_surface,
+ int new_x,
+ int new_y,
+ int new_width,
+ int new_height,
+ MetaWaylandSerial *sent_serial)
+{
+ MetaWaylandShellSurfaceClass *shell_surface_class =
+ META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
+
+ shell_surface_class->configure (shell_surface,
+ new_x,
+ new_y,
+ new_width,
+ new_height,
+ sent_serial);
+}
+
+void
+meta_wayland_shell_surface_ping (MetaWaylandShellSurface *shell_surface,
+ uint32_t serial)
+{
+ MetaWaylandShellSurfaceClass *shell_surface_class =
+ META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
+
+ shell_surface_class->ping (shell_surface, serial);
+}
+
+void
+meta_wayland_shell_surface_close (MetaWaylandShellSurface *shell_surface)
+{
+ MetaWaylandShellSurfaceClass *shell_surface_class =
+ META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
+
+ shell_surface_class->close (shell_surface);
+}
+
+void
+meta_wayland_shell_surface_managed (MetaWaylandShellSurface *shell_surface,
+ MetaWindow *window)
+{
+ MetaWaylandShellSurfaceClass *shell_surface_class =
+ META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
+
+ shell_surface_class->managed (shell_surface, window);
+}
+
+static void
+meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role,
+ MetaWaylandPendingState *pending)
+{
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+ MetaWaylandSurfaceRoleClass *surface_role_class;
+ MetaWindow *window;
+ MetaWaylandBuffer *buffer;
+ CoglTexture *texture;
+ MetaSurfaceActorWayland *surface_actor;
+ double scale;
+
+ surface_role_class =
+ META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_shell_surface_parent_class);
+ surface_role_class->commit (surface_role, pending);
+
+ buffer = surface->buffer_ref.buffer;
+ if (!buffer)
+ return;
+
+ window = surface->window;
+ if (!window)
+ return;
+
+ surface_actor = META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
+ scale = meta_surface_actor_wayland_get_scale (surface_actor);
+ texture = meta_wayland_buffer_get_texture (buffer);
+
+ window->buffer_rect.width = cogl_texture_get_width (texture) * scale;
+ window->buffer_rect.height = cogl_texture_get_height (texture) * scale;
+}
+
+static void
+meta_wayland_shell_surface_init (MetaWaylandShellSurface *role)
+{
+}
+
+static void
+meta_wayland_shell_surface_class_init (MetaWaylandShellSurfaceClass *klass)
+{
+ MetaWaylandSurfaceRoleClass *surface_role_class =
+ META_WAYLAND_SURFACE_ROLE_CLASS (klass);
+
+ surface_role_class->commit = meta_wayland_shell_surface_surface_commit;
+}
diff --git a/src/wayland/meta-wayland-shell-surface.h b/src/wayland/meta-wayland-shell-surface.h
new file mode 100644
index 000000000..72b0828b5
--- /dev/null
+++ b/src/wayland/meta-wayland-shell-surface.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012,2013 Intel Corporation
+ * Copyright (C) 2013-2017 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_WAYLAND_SHELL_SURFACE_H
+#define META_WAYLAND_SHELL_SURFACE_H
+
+#include "wayland/meta-wayland-actor-surface.h"
+
+#define META_TYPE_WAYLAND_SHELL_SURFACE (meta_wayland_shell_surface_get_type ())
+G_DECLARE_DERIVABLE_TYPE (MetaWaylandShellSurface,
+ meta_wayland_shell_surface,
+ META, WAYLAND_SHELL_SURFACE,
+ MetaWaylandActorSurface)
+
+struct _MetaWaylandShellSurfaceClass
+{
+ MetaWaylandActorSurfaceClass parent_class;
+
+ void (*configure) (MetaWaylandShellSurface *shell_surface,
+ int new_x,
+ int new_y,
+ int new_width,
+ int new_height,
+ MetaWaylandSerial *sent_serial);
+ void (*managed) (MetaWaylandShellSurface *shell_surface,
+ MetaWindow *window);
+ void (*ping) (MetaWaylandShellSurface *shell_surface,
+ uint32_t serial);
+ void (*close) (MetaWaylandShellSurface *shell_surface);
+};
+
+void meta_wayland_shell_surface_configure (MetaWaylandShellSurface *shell_surface,
+ int new_x,
+ int new_y,
+ int new_width,
+ int new_height,
+ MetaWaylandSerial *sent_serial);
+
+void meta_wayland_shell_surface_ping (MetaWaylandShellSurface *shell_surface,
+ uint32_t serial);
+
+void meta_wayland_shell_surface_close (MetaWaylandShellSurface *shell_surface);
+
+void meta_wayland_shell_surface_managed (MetaWaylandShellSurface *shell_surface,
+ MetaWindow *window);
+
+#endif /* META_WAYLAND_SHELL_SURFACE_H */
diff --git a/src/wayland/meta-wayland-subsurface.c b/src/wayland/meta-wayland-subsurface.c
new file mode 100644
index 000000000..1e630fa98
--- /dev/null
+++ b/src/wayland/meta-wayland-subsurface.c
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2012,2013 Intel Corporation
+ * Copyright (C) 2013-2017 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "wayland/meta-wayland-subsurface.h"
+
+#include "compositor/meta-surface-actor-wayland.h"
+#include "wayland/meta-wayland.h"
+#include "wayland/meta-wayland-surface.h"
+
+typedef enum
+{
+ META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE,
+ META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW
+} MetaWaylandSubsurfacePlacement;
+
+typedef struct
+{
+ MetaWaylandSubsurfacePlacement placement;
+ MetaWaylandSurface *sibling;
+ struct wl_listener sibling_destroy_listener;
+} MetaWaylandSubsurfacePlacementOp;
+
+struct _MetaWaylandSubsurface
+{
+ MetaWaylandActorSurface parent;
+};
+
+G_DEFINE_TYPE (MetaWaylandSubsurface,
+ meta_wayland_subsurface,
+ META_TYPE_WAYLAND_ACTOR_SURFACE)
+
+void
+meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
+{
+ MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (subsurface);
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+
+ if (surface->sub.pending_pos)
+ {
+ surface->sub.x = surface->sub.pending_x;
+ surface->sub.y = surface->sub.pending_y;
+ surface->sub.pending_pos = FALSE;
+ }
+
+ if (surface->sub.pending_placement_ops)
+ {
+ GSList *it;
+ MetaWaylandSurface *parent = surface->sub.parent;
+ ClutterActor *parent_actor =
+ clutter_actor_get_parent (CLUTTER_ACTOR (parent->surface_actor));
+ ClutterActor *surface_actor = CLUTTER_ACTOR (surface->surface_actor);
+
+ for (it = surface->sub.pending_placement_ops; it; it = it->next)
+ {
+ MetaWaylandSubsurfacePlacementOp *op = it->data;
+ ClutterActor *sibling_actor;
+
+ if (!op->sibling)
+ {
+ g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
+ continue;
+ }
+
+ sibling_actor = CLUTTER_ACTOR (op->sibling->surface_actor);
+
+ switch (op->placement)
+ {
+ case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
+ clutter_actor_set_child_above_sibling (parent_actor,
+ surface_actor,
+ sibling_actor);
+ break;
+ case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
+ clutter_actor_set_child_below_sibling (parent_actor,
+ surface_actor,
+ sibling_actor);
+ break;
+ }
+
+ wl_list_remove (&op->sibling_destroy_listener.link);
+ g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
+ }
+
+ g_slist_free (surface->sub.pending_placement_ops);
+ surface->sub.pending_placement_ops = NULL;
+ }
+
+ if (meta_wayland_surface_is_effectively_synchronized (surface))
+ meta_wayland_surface_apply_pending_state (surface, surface->sub.pending);
+
+ meta_surface_actor_wayland_sync_subsurface_state (
+ META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
+}
+
+static void
+meta_wayland_subsurface_commit (MetaWaylandSurfaceRole *surface_role,
+ MetaWaylandPendingState *pending)
+{
+ MetaWaylandSurfaceRoleClass *surface_role_class;
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+ ClutterActor *actor = CLUTTER_ACTOR (surface->surface_actor);
+
+ surface_role_class =
+ META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_subsurface_parent_class);
+ surface_role_class->commit (surface_role, pending);
+
+ if (surface->buffer_ref.buffer != NULL)
+ clutter_actor_show (actor);
+ else
+ clutter_actor_hide (actor);
+}
+
+static MetaWaylandSurface *
+meta_wayland_subsurface_get_toplevel (MetaWaylandSurfaceRole *surface_role)
+{
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+ MetaWaylandSurface *parent = surface->sub.parent;
+
+ if (parent)
+ return meta_wayland_surface_get_toplevel (parent);
+ else
+ return NULL;
+}
+
+static void
+meta_wayland_subsurface_init (MetaWaylandSubsurface *role)
+{
+}
+
+static void
+meta_wayland_subsurface_class_init (MetaWaylandSubsurfaceClass *klass)
+{
+ MetaWaylandSurfaceRoleClass *surface_role_class =
+ META_WAYLAND_SURFACE_ROLE_CLASS (klass);
+
+ surface_role_class->commit = meta_wayland_subsurface_commit;
+ surface_role_class->get_toplevel = meta_wayland_subsurface_get_toplevel;
+}
+
+static void
+unparent_actor (MetaWaylandSurface *surface)
+{
+ ClutterActor *actor = CLUTTER_ACTOR (surface->surface_actor);
+ ClutterActor *parent_actor;
+
+ parent_actor = clutter_actor_get_parent (actor);
+ clutter_actor_remove_child (parent_actor, actor);
+}
+
+static void
+wl_subsurface_destructor (struct wl_resource *resource)
+{
+ MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
+
+ meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
+ surface);
+ if (surface->sub.parent)
+ {
+ wl_list_remove (&surface->sub.parent_destroy_listener.link);
+ surface->sub.parent->subsurfaces =
+ g_list_remove (surface->sub.parent->subsurfaces, surface);
+ unparent_actor (surface);
+ surface->sub.parent = NULL;
+ }
+
+ g_clear_object (&surface->sub.pending);
+ surface->wl_subsurface = NULL;
+}
+
+static void
+wl_subsurface_destroy (struct wl_client *client,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy (resource);
+}
+
+static void
+wl_subsurface_set_position (struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y)
+{
+ MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
+
+ surface->sub.pending_x = x;
+ surface->sub.pending_y = y;
+ surface->sub.pending_pos = TRUE;
+}
+
+static gboolean
+is_valid_sibling (MetaWaylandSurface *surface,
+ MetaWaylandSurface *sibling)
+{
+ if (surface->sub.parent == sibling)
+ return TRUE;
+ if (surface->sub.parent == sibling->sub.parent)
+ return TRUE;
+ return FALSE;
+}
+
+static void
+subsurface_handle_pending_sibling_destroyed (struct wl_listener *listener,
+ void *data)
+{
+ MetaWaylandSubsurfacePlacementOp *op =
+ wl_container_of (listener, op, sibling_destroy_listener);
+
+ op->sibling = NULL;
+}
+
+static void
+queue_subsurface_placement (MetaWaylandSurface *surface,
+ MetaWaylandSurface *sibling,
+ MetaWaylandSubsurfacePlacement placement)
+{
+ MetaWaylandSubsurfacePlacementOp *op =
+ g_slice_new (MetaWaylandSubsurfacePlacementOp);
+
+ op->placement = placement;
+ op->sibling = sibling;
+ op->sibling_destroy_listener.notify =
+ subsurface_handle_pending_sibling_destroyed;
+ wl_resource_add_destroy_listener (sibling->resource,
+ &op->sibling_destroy_listener);
+
+ surface->sub.pending_placement_ops =
+ g_slist_append (surface->sub.pending_placement_ops, op);
+}
+
+static void
+wl_subsurface_place_above (struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *sibling_resource)
+{
+ MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
+ MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
+
+ if (!is_valid_sibling (surface, sibling))
+ {
+ wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
+ "wl_subsurface::place_above: wl_surface@%d is "
+ "not a valid parent or sibling",
+ wl_resource_get_id (sibling->resource));
+ return;
+ }
+
+ queue_subsurface_placement (surface,
+ sibling,
+ META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE);
+}
+
+static void
+wl_subsurface_place_below (struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *sibling_resource)
+{
+ MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
+ MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
+
+ if (!is_valid_sibling (surface, sibling))
+ {
+ wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
+ "wl_subsurface::place_below: wl_surface@%d is "
+ "not a valid parent or sibling",
+ wl_resource_get_id (sibling->resource));
+ return;
+ }
+
+ queue_subsurface_placement (surface,
+ sibling,
+ META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW);
+}
+
+static void
+wl_subsurface_set_sync (struct wl_client *client,
+ struct wl_resource *resource)
+{
+ MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
+
+ surface->sub.synchronous = TRUE;
+}
+
+static void
+wl_subsurface_set_desync (struct wl_client *client,
+ struct wl_resource *resource)
+{
+ MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
+ gboolean was_effectively_synchronized;
+
+ was_effectively_synchronized =
+ meta_wayland_surface_is_effectively_synchronized (surface);
+ surface->sub.synchronous = FALSE;
+
+ if (was_effectively_synchronized &&
+ !meta_wayland_surface_is_effectively_synchronized (surface))
+ meta_wayland_surface_apply_pending_state (surface, surface->sub.pending);
+}
+
+static const struct wl_subsurface_interface meta_wayland_wl_subsurface_interface = {
+ wl_subsurface_destroy,
+ wl_subsurface_set_position,
+ wl_subsurface_place_above,
+ wl_subsurface_place_below,
+ wl_subsurface_set_sync,
+ wl_subsurface_set_desync,
+};
+
+static void
+wl_subcompositor_destroy (struct wl_client *client,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy (resource);
+}
+
+static void
+surface_handle_parent_surface_destroyed (struct wl_listener *listener,
+ void *data)
+{
+ MetaWaylandSurface *surface = wl_container_of (listener,
+ surface,
+ sub.parent_destroy_listener);
+
+ surface->sub.parent = NULL;
+ unparent_actor (surface);
+}
+
+static void
+wl_subcompositor_get_subsurface (struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id,
+ struct wl_resource *surface_resource,
+ struct wl_resource *parent_resource)
+{
+ MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
+ MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource);
+
+ if (surface->wl_subsurface)
+ {
+ wl_resource_post_error (surface_resource,
+ WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "wl_subcompositor::get_subsurface already requested");
+ return;
+ }
+
+ if (!meta_wayland_surface_assign_role (surface,
+ META_TYPE_WAYLAND_SUBSURFACE,
+ NULL))
+ {
+ wl_resource_post_error (resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
+ "wl_surface@%d already has a different role",
+ wl_resource_get_id (surface->resource));
+ return;
+ }
+
+ surface->wl_subsurface =
+ wl_resource_create (client,
+ &wl_subsurface_interface,
+ wl_resource_get_version (resource),
+ id);
+ wl_resource_set_implementation (surface->wl_subsurface,
+ &meta_wayland_wl_subsurface_interface,
+ surface,
+ wl_subsurface_destructor);
+
+ surface->sub.pending = g_object_new (META_TYPE_WAYLAND_PENDING_STATE, NULL);
+ surface->sub.synchronous = TRUE;
+ surface->sub.parent = parent;
+ surface->sub.parent_destroy_listener.notify =
+ surface_handle_parent_surface_destroyed;
+ wl_resource_add_destroy_listener (parent->resource,
+ &surface->sub.parent_destroy_listener);
+ parent->subsurfaces = g_list_append (parent->subsurfaces, surface);
+
+ clutter_actor_add_child (CLUTTER_ACTOR (parent->surface_actor),
+ CLUTTER_ACTOR (surface->surface_actor));
+
+ clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE);
+}
+
+static const struct wl_subcompositor_interface meta_wayland_subcompositor_interface = {
+ wl_subcompositor_destroy,
+ wl_subcompositor_get_subsurface,
+};
+
+static void
+bind_subcompositor (struct wl_client *client,
+ void *data,
+ uint32_t version,
+ uint32_t id)
+{
+ struct wl_resource *resource;
+
+ resource = wl_resource_create (client, &wl_subcompositor_interface,
+ version, id);
+ wl_resource_set_implementation (resource, &meta_wayland_subcompositor_interface,
+ data, NULL);
+}
+
+void
+meta_wayland_subsurfaces_init (MetaWaylandCompositor *compositor)
+{
+ if (wl_global_create (compositor->wayland_display,
+ &wl_subcompositor_interface,
+ META_WL_SUBCOMPOSITOR_VERSION,
+ compositor, bind_subcompositor) == NULL)
+ g_error ("Failed to register a global wl-subcompositor object");
+}
diff --git a/src/wayland/meta-wayland-subsurface.h b/src/wayland/meta-wayland-subsurface.h
new file mode 100644
index 000000000..eac3c6c7b
--- /dev/null
+++ b/src/wayland/meta-wayland-subsurface.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012,2013 Intel Corporation
+ * Copyright (C) 2013-2017 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_WAYLAND_SUBSURFACE_H
+#define META_WAYLAND_SUBSURFACE_H
+
+#include "wayland/meta-wayland-actor-surface.h"
+
+#define META_TYPE_WAYLAND_SUBSURFACE (meta_wayland_subsurface_get_type ())
+G_DECLARE_FINAL_TYPE (MetaWaylandSubsurface,
+ meta_wayland_subsurface,
+ META, WAYLAND_SUBSURFACE,
+ MetaWaylandActorSurface)
+
+void meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface);
+
+void meta_wayland_subsurfaces_init (MetaWaylandCompositor *compositor);
+
+#endif /* META_WAYLAND_SUBSURFACE_H */
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 7731d9926..301992627 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -2,7 +2,7 @@
* Wayland Support
*
* Copyright (C) 2012,2013 Intel Corporation
- * 2013 Red Hat, Inc.
+ * Copyright (C) 2013-2017 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -36,6 +36,7 @@
#include "meta-xwayland-private.h"
#include "meta-wayland-buffer.h"
#include "meta-wayland-region.h"
+#include "meta-wayland-subsurface.h"
#include "meta-wayland-seat.h"
#include "meta-wayland-keyboard.h"
#include "meta-wayland-pointer.h"
@@ -77,46 +78,16 @@ typedef struct _MetaWaylandSurfaceRolePrivate
MetaWaylandSurface *surface;
} MetaWaylandSurfaceRolePrivate;
-typedef enum
-{
- META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE,
- META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW
-} MetaWaylandSubsurfacePlacement;
-
-typedef struct
-{
- MetaWaylandSubsurfacePlacement placement;
- MetaWaylandSurface *sibling;
- struct wl_listener sibling_destroy_listener;
-} MetaWaylandSubsurfacePlacementOp;
-
G_DEFINE_TYPE (MetaWaylandSurface, meta_wayland_surface, G_TYPE_OBJECT);
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRole,
meta_wayland_surface_role,
G_TYPE_OBJECT);
-G_DEFINE_TYPE (MetaWaylandSurfaceRoleActorSurface,
- meta_wayland_surface_role_actor_surface,
- META_TYPE_WAYLAND_SURFACE_ROLE);
-
-G_DEFINE_TYPE (MetaWaylandShellSurface,
- meta_wayland_shell_surface,
- META_TYPE_WAYLAND_SURFACE_ROLE_ACTOR_SURFACE);
-
G_DEFINE_TYPE (MetaWaylandPendingState,
meta_wayland_pending_state,
G_TYPE_OBJECT);
-struct _MetaWaylandSurfaceRoleSubsurface
-{
- MetaWaylandSurfaceRoleActorSurface parent;
-};
-
-G_DEFINE_TYPE (MetaWaylandSurfaceRoleSubsurface,
- meta_wayland_surface_role_subsurface,
- META_TYPE_WAYLAND_SURFACE_ROLE_ACTOR_SURFACE);
-
struct _MetaWaylandSurfaceRoleDND
{
MetaWaylandSurfaceRole parent;
@@ -156,25 +127,6 @@ static MetaWaylandSurface *
meta_wayland_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role);
static void
-meta_wayland_shell_surface_configure (MetaWaylandShellSurface *shell_surface,
- int new_x,
- int new_y,
- int new_width,
- int new_height,
- MetaWaylandSerial *sent_serial);
-
-static void
-meta_wayland_shell_surface_ping (MetaWaylandShellSurface *shell_surface,
- uint32_t serial);
-
-static void
-meta_wayland_shell_surface_close (MetaWaylandShellSurface *shell_surface);
-
-static void
-meta_wayland_shell_surface_managed (MetaWaylandShellSurface *shell_surface,
- MetaWindow *window);
-
-static void
surface_actor_mapped_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface);
@@ -466,18 +418,6 @@ meta_wayland_surface_unref_buffer_use_count (MetaWaylandSurface *surface)
}
static void
-queue_surface_actor_frame_callbacks (MetaWaylandSurface *surface,
- MetaWaylandPendingState *pending)
-{
- MetaSurfaceActorWayland *surface_actor =
- META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
-
- meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
- &pending->frame_callback_list);
- wl_list_init (&pending->frame_callback_list);
-}
-
-static void
pending_buffer_resource_destroyed (MetaWaylandBuffer *buffer,
MetaWaylandPendingState *pending)
{
@@ -605,45 +545,12 @@ meta_wayland_pending_state_class_init (MetaWaylandPendingStateClass *klass)
G_TYPE_NONE, 0);
}
-static void
-subsurface_role_commit (MetaWaylandSurfaceRole *surface_role,
- MetaWaylandPendingState *pending)
-{
- MetaWaylandSurfaceRoleClass *surface_role_class;
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (surface_role);
- MetaSurfaceActorWayland *surface_actor =
- META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
-
- surface_role_class =
- META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_surface_role_subsurface_parent_class);
- surface_role_class->commit (surface_role, pending);
-
- if (surface->buffer_ref.buffer != NULL)
- clutter_actor_show (CLUTTER_ACTOR (surface_actor));
- else
- clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
-}
-
-static MetaWaylandSurface *
-subsurface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role)
-{
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (surface_role);
- MetaWaylandSurface *parent = surface->sub.parent;
-
- if (parent && parent->role)
- return meta_wayland_surface_role_get_toplevel (parent->role);
- else
- return NULL;
-}
-
/* A non-subsurface is always desynchronized.
*
* A subsurface is effectively synchronized if either its parent is
* synchronized or itself is in synchronized mode. */
-static gboolean
-is_surface_effectively_synchronized (MetaWaylandSurface *surface)
+gboolean
+meta_wayland_surface_is_effectively_synchronized (MetaWaylandSurface *surface)
{
if (surface->wl_subsurface == NULL)
{
@@ -652,81 +559,31 @@ is_surface_effectively_synchronized (MetaWaylandSurface *surface)
else
{
if (surface->sub.synchronous)
- return TRUE;
+ {
+ return TRUE;
+ }
else
- return is_surface_effectively_synchronized (surface->sub.parent);
+ {
+ MetaWaylandSurface *parent = surface->sub.parent;
+
+ return meta_wayland_surface_is_effectively_synchronized (parent);
+ }
}
}
static void
-apply_pending_state (MetaWaylandSurface *surface,
- MetaWaylandPendingState *pending);
-
-static void
-parent_surface_state_applied (gpointer data, gpointer user_data)
+parent_surface_state_applied (gpointer data,
+ gpointer user_data)
{
MetaWaylandSurface *surface = data;
+ MetaWaylandSubsurface *subsurface = META_WAYLAND_SUBSURFACE (surface->role);
- if (surface->sub.pending_pos)
- {
- surface->sub.x = surface->sub.pending_x;
- surface->sub.y = surface->sub.pending_y;
- surface->sub.pending_pos = FALSE;
- }
-
- if (surface->sub.pending_placement_ops)
- {
- GSList *it;
- MetaWaylandSurface *parent = surface->sub.parent;
- ClutterActor *parent_actor =
- clutter_actor_get_parent (CLUTTER_ACTOR (parent->surface_actor));
- ClutterActor *surface_actor = CLUTTER_ACTOR (surface->surface_actor);
-
- for (it = surface->sub.pending_placement_ops; it; it = it->next)
- {
- MetaWaylandSubsurfacePlacementOp *op = it->data;
- ClutterActor *sibling_actor;
-
- if (!op->sibling)
- {
- g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
- continue;
- }
-
- sibling_actor = CLUTTER_ACTOR (op->sibling->surface_actor);
-
- switch (op->placement)
- {
- case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
- clutter_actor_set_child_above_sibling (parent_actor,
- surface_actor,
- sibling_actor);
- break;
- case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
- clutter_actor_set_child_below_sibling (parent_actor,
- surface_actor,
- sibling_actor);
- break;
- }
-
- wl_list_remove (&op->sibling_destroy_listener.link);
- g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
- }
-
- g_slist_free (surface->sub.pending_placement_ops);
- surface->sub.pending_placement_ops = NULL;
- }
-
- if (is_surface_effectively_synchronized (surface))
- apply_pending_state (surface, surface->sub.pending);
-
- meta_surface_actor_wayland_sync_subsurface_state (
- META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
+ meta_wayland_subsurface_parent_state_applied (subsurface);
}
-static void
-apply_pending_state (MetaWaylandSurface *surface,
- MetaWaylandPendingState *pending)
+void
+meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
+ MetaWaylandPendingState *pending)
{
if (surface->role)
{
@@ -892,10 +749,10 @@ meta_wayland_surface_commit (MetaWaylandSurface *surface)
* 2) Its mode changes from synchronized to desynchronized and its parent
* surface is in effective desynchronized mode.
*/
- if (is_surface_effectively_synchronized (surface))
+ if (meta_wayland_surface_is_effectively_synchronized (surface))
move_pending_state (surface->pending, surface->sub.pending);
else
- apply_pending_state (surface, surface->pending);
+ meta_wayland_surface_apply_pending_state (surface, surface->pending);
}
static void
@@ -1110,27 +967,6 @@ static const struct wl_surface_interface meta_wayland_wl_surface_interface = {
wl_surface_damage_buffer,
};
-static gboolean
-surface_should_be_reactive (MetaWaylandSurface *surface)
-{
- /* If we have a toplevel window, we should be reactive */
- if (surface->window)
- return TRUE;
-
- /* If we're a subsurface, we should be reactive */
- if (surface->wl_subsurface)
- return TRUE;
-
- return FALSE;
-}
-
-static void
-sync_reactive (MetaWaylandSurface *surface)
-{
- clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor),
- surface_should_be_reactive (surface));
-}
-
static void
sync_drag_dest_funcs (MetaWaylandSurface *surface)
{
@@ -1220,18 +1056,6 @@ set_surface_is_on_output (MetaWaylandSurface *surface,
}
}
-static gboolean
-actor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role,
- MetaLogicalMonitor *logical_monitor)
-{
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (surface_role);
- MetaSurfaceActorWayland *actor =
- META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
-
- return meta_surface_actor_wayland_is_on_monitor (actor, logical_monitor);
-}
-
static void
update_surface_output_state (gpointer key, gpointer value, gpointer user_data)
{
@@ -1300,7 +1124,8 @@ meta_wayland_surface_set_window (MetaWaylandSurface *surface,
}
surface->window = window;
- sync_reactive (surface);
+
+ clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), !!window);
sync_drag_dest_funcs (surface);
if (was_unmapped)
@@ -1479,263 +1304,12 @@ meta_wayland_surface_begin_grab_op (MetaWaylandSurface *surface,
x, y);
}
-static void
-unparent_actor (MetaWaylandSurface *surface)
-{
- ClutterActor *parent_actor;
- parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
- clutter_actor_remove_child (parent_actor, CLUTTER_ACTOR (surface->surface_actor));
-}
-
-static void
-wl_subsurface_destructor (struct wl_resource *resource)
-{
- MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
-
- meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
- surface);
- if (surface->sub.parent)
- {
- wl_list_remove (&surface->sub.parent_destroy_listener.link);
- surface->sub.parent->subsurfaces =
- g_list_remove (surface->sub.parent->subsurfaces, surface);
- unparent_actor (surface);
- surface->sub.parent = NULL;
- }
-
- g_clear_object (&surface->sub.pending);
- surface->wl_subsurface = NULL;
-}
-
-static void
-wl_subsurface_destroy (struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy (resource);
-}
-
-static void
-wl_subsurface_set_position (struct wl_client *client,
- struct wl_resource *resource,
- int32_t x,
- int32_t y)
-{
- MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
-
- surface->sub.pending_x = x;
- surface->sub.pending_y = y;
- surface->sub.pending_pos = TRUE;
-}
-
-static gboolean
-is_valid_sibling (MetaWaylandSurface *surface, MetaWaylandSurface *sibling)
-{
- if (surface->sub.parent == sibling)
- return TRUE;
- if (surface->sub.parent == sibling->sub.parent)
- return TRUE;
- return FALSE;
-}
-
-static void
-subsurface_handle_pending_sibling_destroyed (struct wl_listener *listener, void *data)
-{
- MetaWaylandSubsurfacePlacementOp *op =
- wl_container_of (listener, op, sibling_destroy_listener);
-
- op->sibling = NULL;
-}
-
-static void
-queue_subsurface_placement (MetaWaylandSurface *surface,
- MetaWaylandSurface *sibling,
- MetaWaylandSubsurfacePlacement placement)
-{
- MetaWaylandSubsurfacePlacementOp *op =
- g_slice_new (MetaWaylandSubsurfacePlacementOp);
-
- op->placement = placement;
- op->sibling = sibling;
- op->sibling_destroy_listener.notify =
- subsurface_handle_pending_sibling_destroyed;
- wl_resource_add_destroy_listener (sibling->resource,
- &op->sibling_destroy_listener);
-
- surface->sub.pending_placement_ops =
- g_slist_append (surface->sub.pending_placement_ops, op);
-}
-
-static void
-wl_subsurface_place_above (struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *sibling_resource)
-{
- MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
- MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
-
- if (!is_valid_sibling (surface, sibling))
- {
- wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
- "wl_subsurface::place_above: wl_surface@%d is "
- "not a valid parent or sibling",
- wl_resource_get_id (sibling->resource));
- return;
- }
-
- queue_subsurface_placement (surface,
- sibling,
- META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE);
-}
-
-static void
-wl_subsurface_place_below (struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *sibling_resource)
-{
- MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
- MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
-
- if (!is_valid_sibling (surface, sibling))
- {
- wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE,
- "wl_subsurface::place_below: wl_surface@%d is "
- "not a valid parent or sibling",
- wl_resource_get_id (sibling->resource));
- return;
- }
-
- queue_subsurface_placement (surface,
- sibling,
- META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW);
-}
-
-static void
-wl_subsurface_set_sync (struct wl_client *client,
- struct wl_resource *resource)
-{
- MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
-
- surface->sub.synchronous = TRUE;
-}
-
-static void
-wl_subsurface_set_desync (struct wl_client *client,
- struct wl_resource *resource)
-{
- MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
- gboolean was_effectively_synchronized;
-
- was_effectively_synchronized = is_surface_effectively_synchronized (surface);
- surface->sub.synchronous = FALSE;
- if (was_effectively_synchronized &&
- !is_surface_effectively_synchronized (surface))
- apply_pending_state (surface, surface->sub.pending);
-}
-
-static const struct wl_subsurface_interface meta_wayland_wl_subsurface_interface = {
- wl_subsurface_destroy,
- wl_subsurface_set_position,
- wl_subsurface_place_above,
- wl_subsurface_place_below,
- wl_subsurface_set_sync,
- wl_subsurface_set_desync,
-};
-
-static void
-wl_subcompositor_destroy (struct wl_client *client,
- struct wl_resource *resource)
-{
- wl_resource_destroy (resource);
-}
-
-static void
-surface_handle_parent_surface_destroyed (struct wl_listener *listener,
- void *data)
-{
- MetaWaylandSurface *surface = wl_container_of (listener,
- surface,
- sub.parent_destroy_listener);
-
- surface->sub.parent = NULL;
- unparent_actor (surface);
-}
-
-static void
-wl_subcompositor_get_subsurface (struct wl_client *client,
- struct wl_resource *resource,
- guint32 id,
- struct wl_resource *surface_resource,
- struct wl_resource *parent_resource)
-{
- MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
- MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource);
-
- if (surface->wl_subsurface != NULL)
- {
- wl_resource_post_error (surface_resource,
- WL_DISPLAY_ERROR_INVALID_OBJECT,
- "wl_subcompositor::get_subsurface already requested");
- return;
- }
-
- if (!meta_wayland_surface_assign_role (surface,
- META_TYPE_WAYLAND_SURFACE_ROLE_SUBSURFACE,
- NULL))
- {
- /* FIXME: There is no subcompositor "role" error yet, so lets just use something
- * similar until there is.
- */
- wl_resource_post_error (resource, WL_SHELL_ERROR_ROLE,
- "wl_surface@%d already has a different role",
- wl_resource_get_id (surface->resource));
- return;
- }
-
- surface->wl_subsurface = wl_resource_create (client, &wl_subsurface_interface, wl_resource_get_version (resource), id);
- wl_resource_set_implementation (surface->wl_subsurface, &meta_wayland_wl_subsurface_interface, surface, wl_subsurface_destructor);
-
- surface->sub.pending = g_object_new (META_TYPE_WAYLAND_PENDING_STATE, NULL);
- surface->sub.synchronous = TRUE;
- surface->sub.parent = parent;
- surface->sub.parent_destroy_listener.notify = surface_handle_parent_surface_destroyed;
- wl_resource_add_destroy_listener (parent->resource, &surface->sub.parent_destroy_listener);
- parent->subsurfaces = g_list_append (parent->subsurfaces, surface);
-
- clutter_actor_add_child (CLUTTER_ACTOR (parent->surface_actor),
- CLUTTER_ACTOR (surface->surface_actor));
-
- sync_reactive (surface);
-}
-
-static const struct wl_subcompositor_interface meta_wayland_subcompositor_interface = {
- wl_subcompositor_destroy,
- wl_subcompositor_get_subsurface,
-};
-
-static void
-bind_subcompositor (struct wl_client *client,
- void *data,
- guint32 version,
- guint32 id)
-{
- struct wl_resource *resource;
-
- resource = wl_resource_create (client, &wl_subcompositor_interface, version, id);
- wl_resource_set_implementation (resource, &meta_wayland_subcompositor_interface, data, NULL);
-}
-
void
meta_wayland_shell_init (MetaWaylandCompositor *compositor)
{
meta_wayland_xdg_shell_init (compositor);
meta_wayland_wl_shell_init (compositor);
meta_wayland_gtk_shell_init (compositor);
-
- if (wl_global_create (compositor->wayland_display,
- &wl_subcompositor_interface,
- META_WL_SUBCOMPOSITOR_VERSION,
- compositor, bind_subcompositor) == NULL)
- g_error ("Failed to register a global wl-subcompositor object");
}
void
@@ -2087,54 +1661,6 @@ meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role)
return priv->surface;
}
-static void
-meta_wayland_shell_surface_configure (MetaWaylandShellSurface *shell_surface,
- int new_x,
- int new_y,
- int new_width,
- int new_height,
- MetaWaylandSerial *sent_serial)
-{
- MetaWaylandShellSurfaceClass *shell_surface_class =
- META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
-
- shell_surface_class->configure (shell_surface,
- new_x,
- new_y,
- new_width,
- new_height,
- sent_serial);
-}
-
-static void
-meta_wayland_shell_surface_ping (MetaWaylandShellSurface *shell_surface,
- uint32_t serial)
-{
- MetaWaylandShellSurfaceClass *shell_surface_class =
- META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
-
- shell_surface_class->ping (shell_surface, serial);
-}
-
-static void
-meta_wayland_shell_surface_close (MetaWaylandShellSurface *shell_surface)
-{
- MetaWaylandShellSurfaceClass *shell_surface_class =
- META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
-
- shell_surface_class->close (shell_surface);
-}
-
-static void
-meta_wayland_shell_surface_managed (MetaWaylandShellSurface *shell_surface,
- MetaWindow *window)
-{
- MetaWaylandShellSurfaceClass *shell_surface_class =
- META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface);
-
- shell_surface_class->managed (shell_surface, window);
-}
-
void
meta_wayland_surface_queue_pending_frame_callbacks (MetaWaylandSurface *surface)
{
@@ -2153,100 +1679,6 @@ default_role_assigned (MetaWaylandSurfaceRole *surface_role)
}
static void
-actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
-{
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (surface_role);
- MetaSurfaceActorWayland *surface_actor =
- META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
-
- meta_surface_actor_wayland_add_frame_callbacks (surface_actor,
- &surface->pending_frame_callback_list);
- wl_list_init (&surface->pending_frame_callback_list);
-}
-
-static void
-actor_surface_commit (MetaWaylandSurfaceRole *surface_role,
- MetaWaylandPendingState *pending)
-{
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (surface_role);
- MetaWaylandSurface *toplevel_surface;
-
- queue_surface_actor_frame_callbacks (surface, pending);
-
- toplevel_surface = meta_wayland_surface_get_toplevel (surface);
- if (!toplevel_surface || !toplevel_surface->window)
- return;
-
- meta_surface_actor_wayland_sync_state (
- META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
-}
-
-static void
-meta_wayland_surface_role_actor_surface_init (MetaWaylandSurfaceRoleActorSurface *role)
-{
-}
-
-static void
-meta_wayland_surface_role_actor_surface_class_init (MetaWaylandSurfaceRoleActorSurfaceClass *klass)
-{
- MetaWaylandSurfaceRoleClass *surface_role_class =
- META_WAYLAND_SURFACE_ROLE_CLASS (klass);
-
- surface_role_class->assigned = actor_surface_assigned;
- surface_role_class->commit = actor_surface_commit;
- surface_role_class->is_on_logical_monitor = actor_surface_is_on_logical_monitor;
-}
-
-static void
-meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role,
- MetaWaylandPendingState *pending)
-{
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (surface_role);
- MetaWaylandSurfaceRoleClass *surface_role_class;
- MetaWindow *window;
- MetaWaylandBuffer *buffer;
- CoglTexture *texture;
- MetaSurfaceActorWayland *actor;
- double scale;
-
- surface_role_class =
- META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_shell_surface_parent_class);
- surface_role_class->commit (surface_role, pending);
-
- buffer = surface->buffer_ref.buffer;
- if (!buffer)
- return;
-
- window = surface->window;
- if (!window)
- return;
-
- actor = META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
- scale = meta_surface_actor_wayland_get_scale (actor);
- texture = buffer->texture;
-
- window->buffer_rect.width = cogl_texture_get_width (texture) * scale;
- window->buffer_rect.height = cogl_texture_get_height (texture) * scale;
-}
-
-static void
-meta_wayland_shell_surface_init (MetaWaylandShellSurface *role)
-{
-}
-
-static void
-meta_wayland_shell_surface_class_init (MetaWaylandShellSurfaceClass *klass)
-{
- MetaWaylandSurfaceRoleClass *surface_role_class =
- META_WAYLAND_SURFACE_ROLE_CLASS (klass);
-
- surface_role_class->commit = meta_wayland_shell_surface_surface_commit;
-}
-
-static void
meta_wayland_surface_role_dnd_init (MetaWaylandSurfaceRoleDND *role)
{
}
@@ -2261,21 +1693,6 @@ meta_wayland_surface_role_dnd_class_init (MetaWaylandSurfaceRoleDNDClass *klass)
surface_role_class->commit = dnd_surface_commit;
}
-static void
-meta_wayland_surface_role_subsurface_init (MetaWaylandSurfaceRoleSubsurface *role)
-{
-}
-
-static void
-meta_wayland_surface_role_subsurface_class_init (MetaWaylandSurfaceRoleSubsurfaceClass *klass)
-{
- MetaWaylandSurfaceRoleClass *surface_role_class =
- META_WAYLAND_SURFACE_ROLE_CLASS (klass);
-
- surface_role_class->commit = subsurface_role_commit;
- surface_role_class->get_toplevel = subsurface_role_get_toplevel;
-}
-
cairo_region_t *
meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface)
{
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 026aeb2a0..92e385030 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -70,46 +70,6 @@ struct _MetaWaylandSerial {
uint32_t value;
};
-#define META_TYPE_WAYLAND_SURFACE_ROLE_ACTOR_SURFACE (meta_wayland_surface_role_actor_surface_get_type ())
-G_DECLARE_DERIVABLE_TYPE (MetaWaylandSurfaceRoleActorSurface,
- meta_wayland_surface_role_actor_surface,
- META, WAYLAND_SURFACE_ROLE_ACTOR_SURFACE,
- MetaWaylandSurfaceRole);
-
-struct _MetaWaylandSurfaceRoleActorSurfaceClass
-{
- MetaWaylandSurfaceRoleClass parent_class;
-};
-
-#define META_TYPE_WAYLAND_SHELL_SURFACE (meta_wayland_shell_surface_get_type ())
-G_DECLARE_DERIVABLE_TYPE (MetaWaylandShellSurface,
- meta_wayland_shell_surface,
- META, WAYLAND_SHELL_SURFACE,
- MetaWaylandSurfaceRoleActorSurface);
-
-struct _MetaWaylandShellSurfaceClass
-{
- MetaWaylandSurfaceRoleActorSurfaceClass parent_class;
-
- void (*configure) (MetaWaylandShellSurface *shell_surface,
- int new_x,
- int new_y,
- int new_width,
- int new_height,
- MetaWaylandSerial *sent_serial);
- void (*managed) (MetaWaylandShellSurface *shell_surface,
- MetaWindow *window);
- void (*ping) (MetaWaylandShellSurface *shell_surface,
- uint32_t serial);
- void (*close) (MetaWaylandShellSurface *shell_surface);
-};
-
-#define META_TYPE_WAYLAND_SURFACE_ROLE_SUBSURFACE (meta_wayland_surface_role_subsurface_get_type ())
-G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleSubsurface,
- meta_wayland_surface_role_subsurface,
- META, WAYLAND_SURFACE_ROLE_SUBSURFACE,
- MetaWaylandSurfaceRoleActorSurface);
-
#define META_TYPE_WAYLAND_SURFACE_ROLE_DND (meta_wayland_surface_role_dnd_get_type ())
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleDND,
meta_wayland_surface_role_dnd,
@@ -252,6 +212,11 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit
struct wl_resource *compositor_resource,
guint32 id);
+void meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
+ MetaWaylandPendingState *pending);
+
+gboolean meta_wayland_surface_is_effectively_synchronized (MetaWaylandSurface *surface);
+
gboolean meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
GType role_type,
const char *first_property_name,
diff --git a/src/wayland/meta-wayland-wl-shell.h b/src/wayland/meta-wayland-wl-shell.h
index fab997285..4a62d8a72 100644
--- a/src/wayland/meta-wayland-wl-shell.h
+++ b/src/wayland/meta-wayland-wl-shell.h
@@ -20,7 +20,7 @@
#ifndef META_WAYLAND_WL_SHELL_H
#define META_WAYLAND_WL_SHELL_H
-#include "wayland/meta-wayland-surface.h"
+#include "wayland/meta-wayland-shell-surface.h"
#define META_TYPE_WAYLAND_WL_SHELL_SURFACE (meta_wayland_wl_shell_surface_get_type ())
G_DECLARE_FINAL_TYPE (MetaWaylandWlShellSurface,
diff --git a/src/wayland/meta-wayland-xdg-shell.h b/src/wayland/meta-wayland-xdg-shell.h
index 4d56eb24a..aa36a94c2 100644
--- a/src/wayland/meta-wayland-xdg-shell.h
+++ b/src/wayland/meta-wayland-xdg-shell.h
@@ -20,7 +20,7 @@
#ifndef META_WAYLAND_XDG_SHELL_H
#define META_WAYLAND_XDG_SHELL_H
-#include "wayland/meta-wayland-surface.h"
+#include "wayland/meta-wayland-shell-surface.h"
#define META_TYPE_WAYLAND_XDG_SURFACE (meta_wayland_xdg_surface_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaWaylandXdgSurface,
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 6cd7d3c7c..bab6b4ac4 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -39,6 +39,7 @@
#include "meta-wayland-seat.h"
#include "meta-wayland-outputs.h"
#include "meta-wayland-data-device.h"
+#include "meta-wayland-subsurface.h"
#include "meta-wayland-tablet-manager.h"
#include "meta-wayland-xdg-foreign.h"
#include "meta-wayland-dma-buf.h"
@@ -374,6 +375,7 @@ meta_wayland_init (void)
meta_wayland_outputs_init (compositor);
meta_wayland_data_device_manager_init (compositor);
+ meta_wayland_subsurfaces_init (compositor);
meta_wayland_shell_init (compositor);
meta_wayland_pointer_gestures_init (compositor);
meta_wayland_tablet_manager_init (compositor);