MetaWindowActor: survive having no MetaSurfaceActor

We need a MetaWaylandSurface to build a MetaSurfaceActor, but
we don't have one until we get the set_window_xid() call from
XWayland. On the other hand, plugins expect to see the window
actor right from when the window is created, so we need this
empty state.

Based on a patch by Jasper St. Pierre.
This commit is contained in:
Giovanni Campagna 2014-02-25 01:22:56 +01:00
parent 153f843ea6
commit 45624f2edf
5 changed files with 73 additions and 22 deletions

View File

@ -940,6 +940,18 @@ 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);
}
/* Clutter makes the assumption that there is only one X window
* per stage, which is a valid assumption to make for a generic
* application toolkit. As such, it will ignore any events sent

View File

@ -63,5 +63,6 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor,
gulong event);
MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
void meta_window_actor_update_surface (MetaWindowActor *self);
#endif /* META_WINDOW_ACTOR_PRIVATE_H */

View File

@ -254,7 +254,15 @@ static gboolean
is_argb32 (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
/* assume we're argb until we get the window (because
in practice we're drawing nothing, so we're fully
transparent)
*/
if (priv->surface)
return meta_surface_actor_is_argb32 (priv->surface);
else
return TRUE;
}
static gboolean
@ -271,7 +279,7 @@ is_frozen (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
return priv->freeze_count > 0;
return priv->surface == NULL || priv->freeze_count > 0;
}
static void
@ -279,7 +287,7 @@ meta_window_actor_freeze (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
if (priv->freeze_count == 0)
if (priv->freeze_count == 0 && priv->surface)
meta_surface_actor_set_frozen (priv->surface, TRUE);
priv->freeze_count ++;
@ -297,6 +305,7 @@ meta_window_actor_thaw (MetaWindowActor *self)
if (priv->freeze_count > 0)
return;
if (priv->surface)
meta_surface_actor_set_frozen (priv->surface, FALSE);
/* We sometimes ignore moves and resizes on frozen windows */
@ -342,7 +351,7 @@ set_surface (MetaWindowActor *self,
}
}
static void
void
meta_window_actor_update_surface (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
@ -351,8 +360,10 @@ meta_window_actor_update_surface (MetaWindowActor *self)
if (window->surface)
surface_actor = window->surface->surface_actor;
else
else if (!meta_is_wayland_compositor ())
surface_actor = meta_surface_actor_x11_new (window);
else
surface_actor = NULL;
set_surface (self, surface_actor);
}
@ -659,8 +670,11 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
meta_window_actor_get_shape_bounds (self, &bounds);
if (priv->surface)
{
if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds))
gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
}
if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow)
{
@ -771,21 +785,26 @@ meta_window_actor_get_meta_window (MetaWindowActor *self)
* meta_window_actor_get_texture:
* @self: a #MetaWindowActor
*
* Gets the ClutterActor that is used to display the contents of the window
* Gets the ClutterActor that is used to display the contents of the window,
* or NULL if no texture is shown yet, because the window is not mapped.
*
* Return value: (transfer none): the #ClutterActor for the contents
*/
ClutterActor *
meta_window_actor_get_texture (MetaWindowActor *self)
{
if (self->priv->surface)
return CLUTTER_ACTOR (meta_surface_actor_get_texture (self->priv->surface));
else
return NULL;
}
/**
* meta_window_actor_get_surface:
* @self: a #MetaWindowActor
*
* Gets the MetaSurfaceActor that draws the content of this window
* Gets the MetaSurfaceActor that draws the content of this window,
* or NULL if there is no surface yet associated with this window.
*
* Return value: (transfer none): the #MetaSurfaceActor for the contents
*/
@ -884,7 +903,12 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
if (!priv->repaint_scheduled)
{
gboolean is_obscured = meta_surface_actor_is_obscured (priv->surface);
gboolean is_obscured;
if (priv->surface)
is_obscured = meta_surface_actor_is_obscured (priv->surface);
else
is_obscured = FALSE;
/* A frame was marked by the client without actually doing any
* damage or any unobscured, or while we had the window frozen
@ -899,12 +923,15 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
queue_send_frame_messages_timeout (self);
}
else
{
if (priv->surface)
{
const cairo_rectangle_int_t clip = { 0, 0, 1, 1 };
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip);
priv->repaint_scheduled = TRUE;
}
}
}
}
gboolean
@ -1075,7 +1102,10 @@ gboolean
meta_window_actor_should_unredirect (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
if (priv->surface)
return meta_surface_actor_should_unredirect (priv->surface);
else
return FALSE;
}
void
@ -1083,6 +1113,8 @@ meta_window_actor_set_unredirected (MetaWindowActor *self,
gboolean unredirected)
{
MetaWindowActorPrivate *priv = self->priv;
g_assert(priv->surface); /* because otherwise should_unredirect() is FALSE */
meta_surface_actor_set_unredirected (priv->surface, unredirected);
}
@ -1528,6 +1560,7 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self,
{
MetaWindowActorPrivate *priv = self->priv;
if (priv->surface)
meta_surface_actor_process_damage (priv->surface,
event->area.x,
event->area.y,
@ -2035,7 +2068,8 @@ meta_window_actor_update_opacity (MetaWindowActor *self)
MetaWindowActorPrivate *priv = self->priv;
MetaWindow *window = priv->window;
clutter_actor_set_opacity (CLUTTER_ACTOR (self->priv->surface), window->opacity);
if (priv->surface)
clutter_actor_set_opacity (CLUTTER_ACTOR (priv->surface), window->opacity);
}
void

View File

@ -66,6 +66,8 @@ void meta_compositor_window_shape_changed (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_window_opacity_changed (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_window_surface_changed (MetaCompositor *compositor,
MetaWindow *window);
gboolean meta_compositor_process_event (MetaCompositor *compositor,
XEvent *event,

View File

@ -51,6 +51,8 @@ xserver_set_window_id (struct wl_client *client,
surface->window = window;
window->surface = surface;
meta_compositor_window_surface_changed (display->compositor, window);
}
static const struct xserver_interface xserver_implementation = {