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
This commit is contained in:
Jonas Ådahl 2019-06-27 19:33:24 +02:00
parent a8f8bc563e
commit f2f4af0d50
6 changed files with 73 additions and 82 deletions

View File

@ -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:

View File

@ -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 */

View File

@ -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;

View File

@ -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);
}

View File

@ -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,

View File

@ -40,6 +40,7 @@
#include <X11/Xauth.h>
#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);