mirror of
https://github.com/brl/mutter.git
synced 2025-07-10 20:47:19 +00:00
Fix the input region not working properly
The input region was set on the shaped texture, but the shaped texture was never picked properly, as it was never set to be reactive. Move the pick implementation and reactivity to the MetaSurfaceActor, and update the code everywhere else to expect a MetaSurfaceActor.
This commit is contained in:
@ -22,8 +22,12 @@
|
||||
|
||||
struct _MetaSurfaceActorPrivate
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
|
||||
MetaShapedTexture *texture;
|
||||
MetaWaylandBuffer *buffer;
|
||||
|
||||
cairo_region_t *input_region;
|
||||
};
|
||||
|
||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
||||
@ -39,9 +43,77 @@ meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
|
||||
return meta_shaped_texture_get_unobscured_bounds (priv->texture, unobscured_bounds);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_pick (ClutterActor *actor,
|
||||
const ClutterColor *color)
|
||||
{
|
||||
MetaSurfaceActor *self = META_SURFACE_ACTOR (actor);
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
|
||||
if (!clutter_actor_should_pick_paint (actor))
|
||||
return;
|
||||
|
||||
/* If there is no region then use the regular pick */
|
||||
if (priv->input_region == NULL)
|
||||
CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->pick (actor, color);
|
||||
else
|
||||
{
|
||||
int n_rects;
|
||||
float *rectangles;
|
||||
int i;
|
||||
CoglPipeline *pipeline;
|
||||
CoglContext *ctx;
|
||||
CoglFramebuffer *fb;
|
||||
CoglColor cogl_color;
|
||||
|
||||
n_rects = cairo_region_num_rectangles (priv->input_region);
|
||||
rectangles = g_alloca (sizeof (float) * 4 * n_rects);
|
||||
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
int pos = i * 4;
|
||||
|
||||
cairo_region_get_rectangle (priv->input_region, i, &rect);
|
||||
|
||||
rectangles[pos + 0] = rect.x;
|
||||
rectangles[pos + 1] = rect.y;
|
||||
rectangles[pos + 2] = rect.x + rect.width;
|
||||
rectangles[pos + 3] = rect.y + rect.height;
|
||||
}
|
||||
|
||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
fb = cogl_get_draw_framebuffer ();
|
||||
|
||||
cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha);
|
||||
|
||||
pipeline = cogl_pipeline_new (ctx);
|
||||
cogl_pipeline_set_color (pipeline, &cogl_color);
|
||||
cogl_framebuffer_draw_rectangles (fb, pipeline, rectangles, n_rects);
|
||||
cogl_object_unref (pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_dispose (GObject *object)
|
||||
{
|
||||
MetaSurfaceActor *self = META_SURFACE_ACTOR (object);
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
|
||||
g_clear_pointer (&priv->input_region, cairo_region_destroy);
|
||||
|
||||
G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_surface_actor_dispose;
|
||||
actor_class->pick = meta_surface_actor_pick;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
|
||||
}
|
||||
|
||||
@ -172,7 +244,14 @@ meta_surface_actor_set_input_region (MetaSurfaceActor *self,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
meta_shaped_texture_set_input_shape_region (priv->texture, region);
|
||||
|
||||
if (priv->input_region)
|
||||
cairo_region_destroy (priv->input_region);
|
||||
|
||||
if (region)
|
||||
priv->input_region = cairo_region_reference (region);
|
||||
else
|
||||
priv->input_region = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -183,8 +262,20 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
|
||||
meta_shaped_texture_set_opaque_region (priv->texture, region);
|
||||
}
|
||||
|
||||
MetaSurfaceActor *
|
||||
meta_surface_actor_new (void)
|
||||
MetaWaylandSurface *
|
||||
meta_surface_actor_get_surface (MetaSurfaceActor *self)
|
||||
{
|
||||
return g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
return priv->surface;
|
||||
}
|
||||
|
||||
MetaSurfaceActor *
|
||||
meta_surface_actor_new (MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaSurfaceActor *self = g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
|
||||
priv->surface = surface;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
Reference in New Issue
Block a user