[mutter/wip/surface-two: 3/4] wayland-surface: Rework construction / destruction yet again
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/surface-two: 3/4] wayland-surface: Rework construction / destruction yet again
- Date: Mon, 24 Feb 2014 19:47:14 +0000 (UTC)
commit f0cd9b0687789f92e01d629980bbea95774f1b66
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Mon Feb 24 13:32:17 2014 -0500
wayland-surface: Rework construction / destruction yet again
This time, to make way for MetaSurfaceActorEmpty. This also fixes
destroy effects as a side effect. It still has issues if we try
to re-assign an actor that's already toplevel (e.g. somebody
re-popping up a menu that's already being destroyed), but this
will be fixed soon.
The idea here is that MetaWindowActor will do the unparenting of
the surface actor when it itself is destroyed. To prevent bad issues
with picking, we only make the surface actor reactive when it's
toplevel.
src/compositor/meta-window-actor.c | 74 ++++++++++++++++++++++++++---------
src/wayland/meta-wayland-surface.c | 27 +++++++------
src/wayland/meta-wayland-surface.h | 1 +
src/wayland/meta-xwayland.c | 2 +
4 files changed, 72 insertions(+), 32 deletions(-)
---
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 0817fbe..d2c16b1 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -68,6 +68,9 @@ struct _MetaWindowActorPrivate
guint send_frame_messages_timer;
gint64 frame_drawn_time;
+ guint repaint_scheduled_id;
+ guint allocation_changed_id;
+
/*
* These need to be counters rather than flags, since more plugins
* can implement same effect; the practicality of stacking effects
@@ -295,30 +298,66 @@ meta_window_actor_thaw (MetaWindowActor *self)
}
static void
-meta_window_actor_constructed (GObject *object)
+set_surface (MetaWindowActor *self,
+ MetaSurfaceActor *surface)
{
- MetaWindowActor *self = META_WINDOW_ACTOR (object);
- MetaWindowActorPrivate *priv = self->priv;
- MetaWindow *window = priv->window;
+ MetaWindowActorPrivate *priv = self->priv;
- priv->screen = window->screen;
+ if (priv->surface)
+ {
+ g_signal_handler_disconnect (priv->surface, priv->repaint_scheduled_id);
+ priv->repaint_scheduled_id = 0;
+ g_signal_handler_disconnect (priv->surface, priv->allocation_changed_id);
+ priv->allocation_changed_id = 0;
+ clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
+ g_object_unref (priv->surface);
+ }
- if (!priv->surface)
+ priv->surface = surface;
+
+ if (priv->surface)
{
- if (window->surface)
- priv->surface = window->surface->surface_actor;
- else
- priv->surface = meta_surface_actor_x11_new (window);
g_object_ref_sink (priv->surface);
-
+ priv->repaint_scheduled_id = g_signal_connect (priv->surface, "repaint-scheduled",
+ G_CALLBACK (surface_repaint_scheduled), self);
+ priv->allocation_changed_id = g_signal_connect (priv->surface, "allocation-changed",
+ G_CALLBACK (surface_allocation_changed_notify), self);
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
- g_signal_connect_object (priv->surface, "repaint-scheduled",
- G_CALLBACK (surface_repaint_scheduled), self, 0);
- g_signal_connect_object (priv->surface, "allocation-changed",
- G_CALLBACK (surface_allocation_changed_notify), self, 0);
+ /* If the previous surface actor was frozen, start out
+ * frozen as well... */
+ if (priv->updates_frozen)
+ meta_surface_actor_freeze (priv->surface);
+
meta_window_actor_update_shape (self);
}
+}
+
+static void
+meta_window_actor_update_surface (MetaWindowActor *self)
+{
+ MetaWindowActorPrivate *priv = self->priv;
+ MetaWindow *window = priv->window;
+ MetaSurfaceActor *surface_actor;
+
+ if (window->surface)
+ surface_actor = window->surface->surface_actor;
+ else
+ surface_actor = meta_surface_actor_x11_new (window);
+
+ set_surface (self, surface_actor);
+}
+
+static void
+meta_window_actor_constructed (GObject *object)
+{
+ MetaWindowActor *self = META_WINDOW_ACTOR (object);
+ MetaWindowActorPrivate *priv = self->priv;
+ MetaWindow *window = priv->window;
+
+ priv->screen = window->screen;
+
+ meta_window_actor_update_surface (self);
meta_window_actor_update_opacity (self);
@@ -361,10 +400,7 @@ meta_window_actor_dispose (GObject *object)
g_clear_object (&priv->window);
- /*
- * Release the extra reference we took on the actor.
- */
- g_clear_object (&priv->surface);
+ set_surface (self, NULL);
G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object);
}
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 0783316..a7bf050 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -574,23 +574,16 @@ const struct wl_surface_interface meta_wayland_surface_interface = {
meta_wayland_surface_set_buffer_scale
};
-static void
-unparent_actor (MetaWaylandSurface *surface)
+void
+meta_wayland_surface_make_toplevel (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));
+ clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE);
}
void
meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface)
{
- /* The window is being unmanaged. Unparent our surface actor
- * before the window actor is destroyed, as we need to hold
- * onto it... */
- unparent_actor (surface);
-
+ clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), FALSE);
surface->window = NULL;
}
@@ -649,10 +642,8 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface));
- clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE);
double_buffered_state_init (&surface->pending);
-
return surface;
}
@@ -980,6 +971,7 @@ xdg_shell_get_xdg_surface (struct wl_client *client,
return;
}
+ meta_wayland_surface_make_toplevel (surface);
surface->window = meta_window_wayland_new (meta_get_display (), surface);
}
@@ -1035,6 +1027,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
return;
}
+ meta_wayland_surface_make_toplevel (surface);
surface->window = meta_window_wayland_new (meta_get_display (), surface);
surface->window->rect.x = parent_surf->window->rect.x + x;
surface->window->rect.y = parent_surf->window->rect.y + y;
@@ -1250,6 +1243,14 @@ subsurface_parent_surface_committed (MetaWaylandSurface *surface)
}
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)
{
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 1430569..9e12451 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -118,6 +118,7 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit
guint32 id,
guint32 version);
+void meta_wayland_surface_make_toplevel (MetaWaylandSurface *surface);
void meta_wayland_surface_window_unmanaged (MetaWaylandSurface *surface);
void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 36b538b..76ca5cb 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -47,6 +47,8 @@ xserver_set_window_id (struct wl_client *client,
if (!window)
return;
+ meta_wayland_surface_make_toplevel (surface);
+
surface->window = window;
window->surface = surface;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]