window-actor: Move shapes, shadows and unredirection to X11 sub types

Move out updating of various shapes (input, opaque, shape) indirectly
from X11 to the corresponding X11 sub types of MetaWindowActor and
MetaSurfaceActor.

Also move fullscreen window unredirection code with it. We want to
effectively do something similar for MetaCompositorServer, but it will
work differently enough not to share too much logic.

While it would have been nice to move things piece by piece, things were
too intertwined to make it feasible.

This has the side effect fixing accidentally and arbitrarily adding
server side shadow to Wayland surfaces.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/727

https://gitlab.gnome.org/GNOME/mutter/merge_requests/734
This commit is contained in:
Jonas Ådahl 2019-08-17 10:00:46 +02:00
parent 9ac52f0340
commit f7315c9a36
14 changed files with 1113 additions and 1039 deletions

View File

@ -677,7 +677,7 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor,
if (!window_actor)
return;
meta_window_actor_update_shape (window_actor);
meta_window_actor_x11_update_shape (META_WINDOW_ACTOR_X11 (window_actor));
}
void
@ -1149,18 +1149,6 @@ meta_post_paint_func (gpointer data)
return TRUE;
}
static void
on_shadow_factory_changed (MetaShadowFactory *factory,
MetaCompositor *compositor)
{
MetaCompositorPrivate *priv =
meta_compositor_get_instance_private (compositor);
GList *l;
for (l = priv->windows; l; l = l->next)
meta_window_actor_invalidate_shadow (l->data);
}
static void
meta_compositor_set_property (GObject *object,
guint prop_id,
@ -1211,11 +1199,6 @@ meta_compositor_init (MetaCompositor *compositor)
priv->context = clutter_backend->cogl_context;
g_signal_connect (meta_shadow_factory_get_default (),
"changed",
G_CALLBACK (on_shadow_factory_changed),
compositor);
priv->pre_paint_func_id =
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT,
meta_pre_paint_func,

View File

@ -29,6 +29,7 @@
#include "backends/x11/meta-event-x11.h"
#include "clutter/x11/clutter-x11.h"
#include "compositor/meta-sync-ring.h"
#include "compositor/meta-window-actor-x11.h"
#include "core/display-private.h"
#include "x11/meta-x11-display-private.h"
@ -52,8 +53,9 @@ process_damage (MetaCompositorX11 *compositor_x11,
MetaWindow *window)
{
MetaWindowActor *window_actor = meta_window_actor_from_window (window);
MetaWindowActorX11 *window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor);
meta_window_actor_process_x11_damage (window_actor, damage_xevent);
meta_window_actor_x11_process_damage (window_actor_x11, damage_xevent);
compositor_x11->frame_has_updated_xsurfaces = TRUE;
}
@ -212,9 +214,11 @@ set_unredirected_window (MetaCompositorX11 *compositor_x11,
if (prev_unredirected_window)
{
MetaWindowActor *window_actor;
MetaWindowActorX11 *window_actor_x11;
window_actor = meta_window_actor_from_window (prev_unredirected_window);
meta_window_actor_set_unredirected (window_actor, FALSE);
window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor);
meta_window_actor_x11_set_unredirected (window_actor_x11, FALSE);
}
shape_cow_for_window (compositor_x11, window);
@ -223,9 +227,11 @@ set_unredirected_window (MetaCompositorX11 *compositor_x11,
if (window)
{
MetaWindowActor *window_actor;
MetaWindowActorX11 *window_actor_x11;
window_actor = meta_window_actor_from_window (window);
meta_window_actor_set_unredirected (window_actor, TRUE);
window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor);
meta_window_actor_x11_set_unredirected (window_actor_x11, TRUE);
}
}
@ -235,6 +241,7 @@ maybe_unredirect_top_window (MetaCompositorX11 *compositor_x11)
MetaCompositor *compositor = META_COMPOSITOR (compositor_x11);
MetaWindow *window_to_unredirect = NULL;
MetaWindowActor *window_actor;
MetaWindowActorX11 *window_actor_x11;
if (meta_compositor_is_unredirect_inhibited (compositor))
goto out;
@ -243,7 +250,8 @@ maybe_unredirect_top_window (MetaCompositorX11 *compositor_x11)
if (!window_actor)
goto out;
if (!meta_window_actor_should_unredirect (window_actor))
window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor);
if (!meta_window_actor_x11_should_unredirect (window_actor_x11))
goto out;
window_to_unredirect = meta_window_actor_get_meta_window (window_actor);

View File

@ -42,6 +42,7 @@ void meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
int fallback_height);
cairo_region_t * meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex);
gboolean meta_shaped_texture_is_opaque (MetaShapedTexture *stex);
gboolean meta_shaped_texture_has_alpha (MetaShapedTexture *stex);
void meta_shaped_texture_set_transform (MetaShapedTexture *stex,
MetaMonitorTransform transform);
void meta_shaped_texture_set_viewport_src_rect (MetaShapedTexture *stex,

View File

@ -1019,7 +1019,7 @@ meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex)
return stex->opaque_region;
}
static gboolean
gboolean
meta_shaped_texture_has_alpha (MetaShapedTexture *stex)
{
CoglTexture *texture;

View File

@ -72,23 +72,11 @@ meta_surface_actor_wayland_is_visible (MetaSurfaceActor *actor)
}
static gboolean
meta_surface_actor_wayland_should_unredirect (MetaSurfaceActor *actor)
meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
{
return FALSE;
}
MetaShapedTexture *stex = meta_surface_actor_get_texture (actor);
static void
meta_surface_actor_wayland_set_unredirected (MetaSurfaceActor *actor,
gboolean unredirected)
{
/* Do nothing. In the future, we'll use KMS to set this
* up as a hardware overlay or something. */
}
static gboolean
meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor)
{
return FALSE;
return meta_shaped_texture_is_opaque (stex);
}
void
@ -162,10 +150,7 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
surface_actor_class->is_visible = meta_surface_actor_wayland_is_visible;
surface_actor_class->should_unredirect = meta_surface_actor_wayland_should_unredirect;
surface_actor_class->set_unredirected = meta_surface_actor_wayland_set_unredirected;
surface_actor_class->is_unredirected = meta_surface_actor_wayland_is_unredirected;
surface_actor_class->is_opaque = meta_surface_actor_wayland_is_opaque;
surface_actor_class->get_window = meta_surface_actor_wayland_get_window;

View File

@ -249,33 +249,17 @@ static gboolean
meta_surface_actor_x11_is_opaque (MetaSurfaceActor *actor)
{
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
MetaShapedTexture *stex = meta_surface_actor_get_texture (actor);
/* If we're not ARGB32, then we're opaque. */
if (!meta_surface_actor_is_argb32 (actor))
if (meta_surface_actor_x11_is_unredirected (self))
return TRUE;
cairo_region_t *opaque_region = meta_surface_actor_get_opaque_region (actor);
/* If we have no opaque region, then no pixels are opaque. */
if (!opaque_region)
return FALSE;
MetaWindow *window = self->window;
cairo_rectangle_int_t client_area;
meta_window_get_client_area_rect (window, &client_area);
/* Otherwise, check if our opaque region covers our entire surface. */
if (cairo_region_contains_rectangle (opaque_region, &client_area) == CAIRO_REGION_OVERLAP_IN)
return TRUE;
return FALSE;
return meta_shaped_texture_is_opaque (stex);
}
static gboolean
meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor)
gboolean
meta_surface_actor_x11_should_unredirect (MetaSurfaceActorX11 *self)
{
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
MetaWindow *window = self->window;
if (meta_window_requested_dont_bypass_compositor (window))
@ -293,7 +277,7 @@ meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor)
if (meta_window_requested_bypass_compositor (window))
return TRUE;
if (!meta_surface_actor_x11_is_opaque (actor))
if (!meta_surface_actor_x11_is_opaque (META_SURFACE_ACTOR (self)))
return FALSE;
if (meta_window_is_override_redirect (window))
@ -327,12 +311,10 @@ sync_unredirected (MetaSurfaceActorX11 *self)
meta_x11_error_trap_pop (display->x11_display);
}
static void
meta_surface_actor_x11_set_unredirected (MetaSurfaceActor *actor,
void
meta_surface_actor_x11_set_unredirected (MetaSurfaceActorX11 *self,
gboolean unredirected)
{
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
if (self->unredirected == unredirected)
return;
@ -340,11 +322,9 @@ meta_surface_actor_x11_set_unredirected (MetaSurfaceActor *actor,
sync_unredirected (self);
}
static gboolean
meta_surface_actor_x11_is_unredirected (MetaSurfaceActor *actor)
gboolean
meta_surface_actor_x11_is_unredirected (MetaSurfaceActorX11 *self)
{
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
return self->unredirected;
}
@ -383,10 +363,7 @@ meta_surface_actor_x11_class_init (MetaSurfaceActorX11Class *klass)
surface_actor_class->process_damage = meta_surface_actor_x11_process_damage;
surface_actor_class->pre_paint = meta_surface_actor_x11_pre_paint;
surface_actor_class->is_visible = meta_surface_actor_x11_is_visible;
surface_actor_class->should_unredirect = meta_surface_actor_x11_should_unredirect;
surface_actor_class->set_unredirected = meta_surface_actor_x11_set_unredirected;
surface_actor_class->is_unredirected = meta_surface_actor_x11_is_unredirected;
surface_actor_class->is_opaque = meta_surface_actor_x11_is_opaque;
surface_actor_class->get_window = meta_surface_actor_x11_get_window;
}

View File

@ -46,6 +46,12 @@ MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window);
void meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self,
int width, int height);
gboolean meta_surface_actor_x11_should_unredirect (MetaSurfaceActorX11 *self);
void meta_surface_actor_x11_set_unredirected (MetaSurfaceActorX11 *self,
gboolean unredirected);
gboolean meta_surface_actor_x11_is_unredirected (MetaSurfaceActorX11 *self);
G_END_DECLS

View File

@ -221,6 +221,12 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
G_TYPE_NONE, 0);
}
gboolean
meta_surface_actor_is_opaque (MetaSurfaceActor *self)
{
return META_SURFACE_ACTOR_GET_CLASS (self)->is_opaque (self);
}
static void
meta_surface_actor_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
@ -481,38 +487,6 @@ meta_surface_actor_pre_paint (MetaSurfaceActor *self)
META_SURFACE_ACTOR_GET_CLASS (self)->pre_paint (self);
}
gboolean
meta_surface_actor_is_argb32 (MetaSurfaceActor *self)
{
MetaShapedTexture *stex = meta_surface_actor_get_texture (self);
CoglTexture *texture = meta_shaped_texture_get_texture (stex);
/* If we don't have a texture, like during initialization, assume
* that we're ARGB32.
*
* If we are unredirected and we have no texture assume that we are
* not ARGB32 otherwise we wouldn't be unredirected in the first
* place. This prevents us from continually redirecting and
* unredirecting on every paint.
*/
if (!texture)
return !meta_surface_actor_is_unredirected (self);
switch (cogl_texture_get_components (texture))
{
case COGL_TEXTURE_COMPONENTS_A:
case COGL_TEXTURE_COMPONENTS_RGBA:
return TRUE;
case COGL_TEXTURE_COMPONENTS_RG:
case COGL_TEXTURE_COMPONENTS_RGB:
case COGL_TEXTURE_COMPONENTS_DEPTH:
return FALSE;
default:
g_assert_not_reached ();
return FALSE;
}
}
gboolean
meta_surface_actor_is_visible (MetaSurfaceActor *self)
{
@ -546,25 +520,6 @@ meta_surface_actor_set_frozen (MetaSurfaceActor *self,
}
}
gboolean
meta_surface_actor_should_unredirect (MetaSurfaceActor *self)
{
return META_SURFACE_ACTOR_GET_CLASS (self)->should_unredirect (self);
}
void
meta_surface_actor_set_unredirected (MetaSurfaceActor *self,
gboolean unredirected)
{
META_SURFACE_ACTOR_GET_CLASS (self)->set_unredirected (self, unredirected);
}
gboolean
meta_surface_actor_is_unredirected (MetaSurfaceActor *self)
{
return META_SURFACE_ACTOR_GET_CLASS (self)->is_unredirected (self);
}
MetaWindow *
meta_surface_actor_get_window (MetaSurfaceActor *self)
{

View File

@ -26,11 +26,7 @@ struct _MetaSurfaceActorClass
int x, int y, int width, int height);
void (* pre_paint) (MetaSurfaceActor *actor);
gboolean (* is_visible) (MetaSurfaceActor *actor);
gboolean (* should_unredirect) (MetaSurfaceActor *actor);
void (* set_unredirected) (MetaSurfaceActor *actor,
gboolean unredirected);
gboolean (* is_unredirected) (MetaSurfaceActor *actor);
gboolean (* is_opaque) (MetaSurfaceActor *actor);
MetaWindow *(* get_window) (MetaSurfaceActor *actor);
};
@ -52,17 +48,12 @@ cairo_region_t * meta_surface_actor_get_opaque_region (MetaSurfaceActor *self);
void meta_surface_actor_process_damage (MetaSurfaceActor *actor,
int x, int y, int width, int height);
void meta_surface_actor_pre_paint (MetaSurfaceActor *actor);
gboolean meta_surface_actor_is_argb32 (MetaSurfaceActor *actor);
gboolean meta_surface_actor_is_visible (MetaSurfaceActor *actor);
gboolean meta_surface_actor_is_opaque (MetaSurfaceActor *actor);
void meta_surface_actor_set_frozen (MetaSurfaceActor *actor,
gboolean frozen);
gboolean meta_surface_actor_should_unredirect (MetaSurfaceActor *actor);
void meta_surface_actor_set_unredirected (MetaSurfaceActor *actor,
gboolean unredirected);
gboolean meta_surface_actor_is_unredirected (MetaSurfaceActor *actor);
void meta_surface_actor_set_transform (MetaSurfaceActor *self,
MetaMonitorTransform transform);
void meta_surface_actor_set_viewport_src_rect (MetaSurfaceActor *self,

View File

@ -46,30 +46,17 @@ void meta_window_actor_size_change (MetaWindowActor *self,
MetaRectangle *old_frame_rect,
MetaRectangle *old_buffer_rect);
void meta_window_actor_process_x11_damage (MetaWindowActor *self,
XDamageNotifyEvent *event);
void meta_window_actor_pre_paint (MetaWindowActor *self);
void meta_window_actor_post_paint (MetaWindowActor *self);
void meta_window_actor_frame_complete (MetaWindowActor *self,
ClutterFrameInfo *frame_info,
gint64 presentation_time);
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
void meta_window_actor_get_shape_bounds (MetaWindowActor *self,
cairo_rectangle_int_t *bounds);
gboolean meta_window_actor_should_unredirect (MetaWindowActor *self);
void meta_window_actor_set_unredirected (MetaWindowActor *self,
gboolean unredirected);
gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self);
MetaWindowActorChanges meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
gboolean did_placement);
void meta_window_actor_update_shape (MetaWindowActor *self);
void meta_window_actor_update_opacity (MetaWindowActor *self);
void meta_window_actor_mapped (MetaWindowActor *self);
void meta_window_actor_unmapped (MetaWindowActor *self);
@ -95,4 +82,8 @@ int meta_window_actor_get_geometry_scale (MetaWindowActor *window_actor);
void meta_window_actor_notify_damaged (MetaWindowActor *window_actor);
gboolean meta_window_actor_is_frozen (MetaWindowActor *self);
gboolean meta_window_actor_is_opaque (MetaWindowActor *self);
#endif /* META_WINDOW_ACTOR_PRIVATE_H */

View File

@ -109,6 +109,8 @@ meta_window_actor_wayland_assign_surface_actor (MetaWindowActor *actor,
MetaWindowActorClass *parent_class =
META_WINDOW_ACTOR_CLASS (meta_window_actor_wayland_parent_class);
g_warn_if_fail (!meta_window_actor_get_surface (actor));
parent_class->assign_surface_actor (actor, surface_actor);
meta_window_actor_wayland_rebuild_surface_tree (actor);
@ -142,10 +144,36 @@ meta_window_actor_wayland_queue_destroy (MetaWindowActor *actor)
{
}
static gboolean
meta_window_actor_wayland_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
MetaSurfaceActor *surface;
surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor));
if (surface)
{
ClutterActor *surface_actor = CLUTTER_ACTOR (surface);
const ClutterPaintVolume *child_volume;
child_volume = clutter_actor_get_transformed_paint_volume (surface_actor,
actor);
if (!child_volume)
return FALSE;
clutter_paint_volume_union (volume, child_volume);
}
return TRUE;
}
static void
meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
{
MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
actor_class->get_paint_volume = meta_window_actor_wayland_get_paint_volume;
window_actor_class->assign_surface_actor = meta_window_actor_wayland_assign_surface_actor;
window_actor_class->frame_complete = meta_window_actor_wayland_frame_complete;

File diff suppressed because it is too large Load Diff

View File

@ -31,4 +31,17 @@ G_DECLARE_FINAL_TYPE (MetaWindowActorX11,
META, WINDOW_ACTOR_X11,
MetaWindowActor)
void meta_window_actor_x11_process_x11_damage (MetaWindowActorX11 *actor_x11,
XDamageNotifyEvent *event);
gboolean meta_window_actor_x11_should_unredirect (MetaWindowActorX11 *actor_x11);
void meta_window_actor_x11_set_unredirected (MetaWindowActorX11 *actor_x11,
gboolean unredirected);
void meta_window_actor_x11_update_shape (MetaWindowActorX11 *actor_x11);
void meta_window_actor_x11_process_damage (MetaWindowActorX11 *actor_x11,
XDamageNotifyEvent *event);
#endif /* META_WINDOW_ACTOR_X11_H */

File diff suppressed because it is too large Load Diff