From f2f4af0d50ba9f2d36cf225162a30928f55d7bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 27 Jun 2019 19:33:24 +0200 Subject: [PATCH] window-actor: Make it clearer that the surface actor doesn't change The way code was structured made it easy to misunderstand things as the surface actor of a window actor could change over time. So is not the case, however, the intention of the corresponding "update" function was so that a surface actor could be assigned to a window actor as soon as the X11 window was associated with its corresponding wl_surface, if the window in question came from Xwayland. Restructure the code and internal API a bit to make it clear that a window actor only once gets a surface actor assigned to it, and that it after that point never changes. https://gitlab.gnome.org/GNOME/mutter/merge_requests/659 --- src/compositor/compositor.c | 12 ---- src/compositor/meta-window-actor-private.h | 9 ++- src/compositor/meta-window-actor-x11.c | 38 +++++----- src/compositor/meta-window-actor.c | 81 +++++++++++----------- src/meta/compositor.h | 4 -- src/wayland/meta-xwayland.c | 11 ++- 6 files changed, 73 insertions(+), 82 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 1ec31d338..ba05451ad 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -778,18 +778,6 @@ meta_compositor_window_opacity_changed (MetaCompositor *compositor, meta_window_actor_update_opacity (window_actor); } -void -meta_compositor_window_surface_changed (MetaCompositor *compositor, - MetaWindow *window) -{ - MetaWindowActor *window_actor; - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (!window_actor) - return; - - meta_window_actor_update_surface (window_actor); -} - /** * meta_compositor_process_event: (skip) * @compositor: diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 6333f43db..9a97d53e2 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -17,8 +17,8 @@ struct _MetaWindowActorClass ClutterFrameInfo *frame_info, int64_t presentation_time); - void (*set_surface_actor) (MetaWindowActor *actor, - MetaSurfaceActor *surface); + void (*assign_surface_actor) (MetaWindowActor *actor, + MetaSurfaceActor *surface_actor); void (*queue_frame_drawn) (MetaWindowActor *actor, gboolean skip_sync_delay); @@ -73,7 +73,10 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor, MetaPluginEffect event); MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self); -void meta_window_actor_update_surface (MetaWindowActor *self); + +void meta_window_actor_assign_surface_actor (MetaWindowActor *self, + MetaSurfaceActor *surface_actor); + MetaWindowActor *meta_window_actor_from_window (MetaWindow *window); #endif /* META_WINDOW_ACTOR_PRIVATE_H */ diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c index 4dc687530..05045ba4e 100644 --- a/src/compositor/meta-window-actor-x11.c +++ b/src/compositor/meta-window-actor-x11.c @@ -329,32 +329,19 @@ meta_window_actor_x11_frame_complete (MetaWindowActor *actor, } static void -meta_window_actor_x11_set_surface_actor (MetaWindowActor *actor, - MetaSurfaceActor *surface) +meta_window_actor_x11_assign_surface_actor (MetaWindowActor *actor, + MetaSurfaceActor *surface_actor) { MetaWindowActorClass *parent_class = META_WINDOW_ACTOR_CLASS (meta_window_actor_x11_parent_class); MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor); - MetaSurfaceActor *old_surface; - old_surface = meta_window_actor_get_surface (actor); + parent_class->assign_surface_actor (actor, surface_actor); - if (old_surface) - { - g_signal_handler_disconnect (old_surface, - actor_x11->repaint_scheduled_id); - actor_x11->repaint_scheduled_id = 0; - } - - parent_class->set_surface_actor (actor, surface); - - if (surface) - { - actor_x11->repaint_scheduled_id = - g_signal_connect (surface, "repaint-scheduled", - G_CALLBACK (surface_repaint_scheduled), - actor_x11); - } + actor_x11->repaint_scheduled_id = + g_signal_connect (surface_actor, "repaint-scheduled", + G_CALLBACK (surface_repaint_scheduled), + actor_x11); } static void @@ -503,10 +490,19 @@ static void meta_window_actor_x11_dispose (GObject *object) { MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (object); + MetaSurfaceActor *surface_actor; if (actor_x11->send_frame_messages_timer != 0) remove_frame_messages_timer (actor_x11); + surface_actor = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + if (surface_actor) + { + g_signal_handler_disconnect (surface_actor, + actor_x11->repaint_scheduled_id); + actor_x11->repaint_scheduled_id = 0; + } + G_OBJECT_CLASS (meta_window_actor_x11_parent_class)->dispose (object); } @@ -528,7 +524,7 @@ meta_window_actor_x11_class_init (MetaWindowActorX11Class *klass) MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass); window_actor_class->frame_complete = meta_window_actor_x11_frame_complete; - window_actor_class->set_surface_actor = meta_window_actor_x11_set_surface_actor; + window_actor_class->assign_surface_actor = meta_window_actor_x11_assign_surface_actor; window_actor_class->queue_frame_drawn = meta_window_actor_x11_queue_frame_drawn; window_actor_class->pre_paint = meta_window_actor_x11_pre_paint; window_actor_class->post_paint = meta_window_actor_x11_post_paint; diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index c3879cef9..1e049ceb1 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -137,12 +137,13 @@ static void meta_window_actor_get_property (GObject *object, GValue *value, GParamSpec *pspec); +static void meta_window_actor_real_assign_surface_actor (MetaWindowActor *self, + MetaSurfaceActor *surface_actor); + static void meta_window_actor_paint (ClutterActor *actor); static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor, ClutterPaintVolume *volume); -static void set_surface (MetaWindowActor *actor, - MetaSurfaceActor *surface); static gboolean meta_window_actor_has_shadow (MetaWindowActor *self); @@ -159,13 +160,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaWindowActor, meta_window_actor, CLUTTER_TY G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init) G_IMPLEMENT_INTERFACE (META_TYPE_SCREEN_CAST_WINDOW, screen_cast_window_iface_init)); -static void -meta_window_actor_real_set_surface_actor (MetaWindowActor *actor, - MetaSurfaceActor *surface) -{ - set_surface (actor, surface); -} - static void meta_window_actor_class_init (MetaWindowActorClass *klass) { @@ -181,7 +175,7 @@ meta_window_actor_class_init (MetaWindowActorClass *klass) actor_class->paint = meta_window_actor_paint; actor_class->get_paint_volume = meta_window_actor_get_paint_volume; - klass->set_surface_actor = meta_window_actor_real_set_surface_actor; + klass->assign_surface_actor = meta_window_actor_real_assign_surface_actor; /** * MetaWindowActor::first-frame: @@ -365,56 +359,55 @@ meta_window_actor_thaw (MetaWindowActor *self) } static void -set_surface (MetaWindowActor *self, - MetaSurfaceActor *surface) +meta_window_actor_real_assign_surface_actor (MetaWindowActor *self, + MetaSurfaceActor *surface_actor) { MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self); - if (priv->surface) - { - g_signal_handler_disconnect (priv->surface, priv->size_changed_id); - clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); - g_object_unref (priv->surface); - } + g_assert (!priv->surface); - priv->surface = surface; + priv->surface = g_object_ref_sink (surface_actor); + priv->size_changed_id = g_signal_connect (priv->surface, "size-changed", + G_CALLBACK (surface_size_changed), + self); + clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); - if (priv->surface) - { - g_object_ref_sink (priv->surface); - priv->size_changed_id = g_signal_connect (priv->surface, "size-changed", - G_CALLBACK (surface_size_changed), self); - clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface)); + meta_window_actor_update_shape (self); - meta_window_actor_update_shape (self); - - if (is_frozen (self)) - meta_surface_actor_set_frozen (priv->surface, TRUE); - else - meta_window_actor_sync_thawed_state (self); - } + if (is_frozen (self)) + meta_surface_actor_set_frozen (priv->surface, TRUE); + else + meta_window_actor_sync_thawed_state (self); } void -meta_window_actor_update_surface (MetaWindowActor *self) +meta_window_actor_assign_surface_actor (MetaWindowActor *self, + MetaSurfaceActor *surface_actor) +{ + META_WINDOW_ACTOR_GET_CLASS (self)->assign_surface_actor (self, + surface_actor); +} + +static void +init_surface_actor (MetaWindowActor *self) { MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self); MetaWindow *window = priv->window; MetaSurfaceActor *surface_actor; -#ifdef HAVE_WAYLAND - if (window->surface) - surface_actor = meta_wayland_surface_get_actor (window->surface); - else -#endif if (!meta_is_wayland_compositor ()) surface_actor = meta_surface_actor_x11_new (window); +#ifdef HAVE_WAYLAND + else if (window->surface) + surface_actor = meta_wayland_surface_get_actor (window->surface); +#endif else surface_actor = NULL; - META_WINDOW_ACTOR_GET_CLASS (self)->set_surface_actor (self, surface_actor); + if (surface_actor) + meta_window_actor_assign_surface_actor (self, surface_actor); } static void @@ -430,7 +423,7 @@ meta_window_actor_constructed (GObject *object) /* Hang our compositor window state off the MetaWindow for fast retrieval */ meta_window_set_compositor_private (window, object); - meta_window_actor_update_surface (self); + init_surface_actor (self); meta_window_actor_update_opacity (self); @@ -476,7 +469,13 @@ meta_window_actor_dispose (GObject *object) g_clear_object (&priv->window); - META_WINDOW_ACTOR_GET_CLASS (self)->set_surface_actor (self, NULL); + if (priv->surface) + { + g_signal_handler_disconnect (priv->surface, priv->size_changed_id); + clutter_actor_remove_child (CLUTTER_ACTOR (self), + CLUTTER_ACTOR (priv->surface)); + g_clear_object (&priv->surface); + } G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object); } diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 31d14dda3..43dcc2b19 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -82,10 +82,6 @@ META_EXPORT void meta_compositor_window_opacity_changed (MetaCompositor *compositor, MetaWindow *window); -META_EXPORT -void meta_compositor_window_surface_changed (MetaCompositor *compositor, - MetaWindow *window); - META_EXPORT gboolean meta_compositor_process_event (MetaCompositor *compositor, XEvent *event, diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 88a4b4c11..aa2844d33 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -40,6 +40,7 @@ #include #include "compositor/meta-surface-actor-wayland.h" +#include "compositor/meta-window-actor-private.h" #include "meta/main.h" #include "wayland/meta-wayland-actor-surface.h" @@ -74,6 +75,7 @@ meta_xwayland_associate_window_with_surface (MetaWindow *window, MetaWaylandSurface *surface) { MetaDisplay *display = window->display; + MetaWindowActor *window_actor; /* If the window has an existing surface, like if we're * undecorating or decorating the window, then we need @@ -102,7 +104,14 @@ meta_xwayland_associate_window_with_surface (MetaWindow *window, xwayland_surface_signals[XWAYLAND_SURFACE_WINDOW_ASSOCIATED], 0); - meta_compositor_window_surface_changed (display->compositor, window); + window_actor = meta_window_actor_from_window (window); + if (window_actor) + { + MetaSurfaceActor *surface_actor; + + surface_actor = meta_wayland_surface_get_actor (surface); + meta_window_actor_assign_surface_actor (window_actor, surface_actor); + } /* Now that we have a surface check if it should have focus. */ meta_display_sync_wayland_input_focus (display);