From 704b73b04125a11e5bb004b1857975f252dc029c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 20 Dec 2017 17:40:22 +0800 Subject: [PATCH] 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 --- src/Makefile.am | 6 + src/wayland/meta-wayland-actor-surface.c | 103 ++++ src/wayland/meta-wayland-actor-surface.h | 37 ++ src/wayland/meta-wayland-shell-surface.c | 127 +++++ src/wayland/meta-wayland-shell-surface.h | 64 +++ src/wayland/meta-wayland-subsurface.c | 429 ++++++++++++++++ src/wayland/meta-wayland-subsurface.h | 36 ++ src/wayland/meta-wayland-surface.c | 629 +---------------------- src/wayland/meta-wayland-surface.h | 45 +- src/wayland/meta-wayland-wl-shell.h | 2 +- src/wayland/meta-wayland-xdg-shell.h | 2 +- src/wayland/meta-wayland.c | 2 + 12 files changed, 834 insertions(+), 648 deletions(-) create mode 100644 src/wayland/meta-wayland-actor-surface.c create mode 100644 src/wayland/meta-wayland-actor-surface.h create mode 100644 src/wayland/meta-wayland-shell-surface.c create mode 100644 src/wayland/meta-wayland-shell-surface.h create mode 100644 src/wayland/meta-wayland-subsurface.c create mode 100644 src/wayland/meta-wayland-subsurface.h 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; @@ -155,25 +126,6 @@ meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface 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, @@ -465,18 +417,6 @@ meta_wayland_surface_unref_buffer_use_count (MetaWaylandSurface *surface) wl_buffer_send_release (buffer->resource); } -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) { @@ -2152,100 +1678,6 @@ default_role_assigned (MetaWaylandSurfaceRole *surface_role) meta_wayland_surface_queue_pending_frame_callbacks (surface); } -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);