summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasper St. Pierre <jstpierre@mecheye.net>2014-02-18 21:27:20 -0500
committerJasper St. Pierre <jstpierre@mecheye.net>2014-02-18 21:29:23 -0500
commit1e6b3faa83323943cb45f4ef1b910f87b2c30d88 (patch)
treef40454716a0df8b6446267a3f90ad8a3e1341b51
parente62fe956fdd450fed6d39fef443958cc57133cd5 (diff)
downloadmutter-1e6b3faa83323943cb45f4ef1b910f87b2c30d88.tar.gz
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.
-rw-r--r--src/compositor/meta-shaped-texture.c105
-rw-r--r--src/compositor/meta-surface-actor.c97
-rw-r--r--src/compositor/meta-surface-actor.h4
-rw-r--r--src/compositor/meta-window-actor.c5
-rw-r--r--src/core/display.c8
-rw-r--r--src/meta/meta-shaped-texture.h3
-rw-r--r--src/wayland/meta-wayland-seat.c9
-rw-r--r--src/wayland/meta-wayland-surface.c3
8 files changed, 108 insertions, 126 deletions
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index ae46b34d2..30697ee6a 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -42,8 +42,6 @@
static void meta_shaped_texture_dispose (GObject *object);
static void meta_shaped_texture_paint (ClutterActor *actor);
-static void meta_shaped_texture_pick (ClutterActor *actor,
- const ClutterColor *color);
static void meta_shaped_texture_get_preferred_width (ClutterActor *self,
gfloat for_height,
@@ -73,8 +71,6 @@ struct _MetaShapedTexturePrivate
CoglTexture *texture;
CoglTexture *mask_texture;
- cairo_region_t *input_shape_region;
-
/* The region containing only fully opaque pixels */
cairo_region_t *opaque_region;
@@ -98,7 +94,6 @@ meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
actor_class->get_preferred_width = meta_shaped_texture_get_preferred_width;
actor_class->get_preferred_height = meta_shaped_texture_get_preferred_height;
actor_class->paint = meta_shaped_texture_paint;
- actor_class->pick = meta_shaped_texture_pick;
actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume;
g_type_class_add_private (klass, sizeof (MetaShapedTexturePrivate));
@@ -464,71 +459,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
}
static void
-meta_shaped_texture_pick (ClutterActor *actor,
- const ClutterColor *color)
-{
- MetaShapedTexture *stex = (MetaShapedTexture *) actor;
- MetaShapedTexturePrivate *priv = stex->priv;
-
- if (!clutter_actor_should_pick_paint (actor) ||
- (priv->clip_region && cairo_region_is_empty (priv->clip_region)))
- return;
-
- /* If there is no region then use the regular pick */
- if (priv->input_shape_region == NULL)
- CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)->pick (actor, color);
- else
- {
- int n_rects;
- float *rectangles;
- int i;
- CoglPipeline *pipeline;
- CoglContext *ctx;
- CoglFramebuffer *fb;
- CoglColor cogl_color;
-
- /* Note: We don't bother trying to intersect the pick and clip regions
- * since needing to copy the region, do the intersection, and probably
- * increase the number of rectangles seems more likely to have a negative
- * effect.
- *
- * NB: Most of the time when just using rectangles for picking then
- * picking shouldn't involve any rendering, and minimizing the number of
- * rectangles has more benefit than reducing the area of the pick
- * region.
- */
-
- n_rects = cairo_region_num_rectangles (priv->input_shape_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_shape_region, i, &rect);
-
- rectangles[pos] = 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_shaped_texture_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
@@ -765,41 +695,6 @@ meta_shaped_texture_get_texture (MetaShapedTexture *stex)
}
/**
- * meta_shaped_texture_set_input_shape_region:
- * @stex: a #MetaShapedTexture
- * @shape_region: the region of the texture that should respond to
- * input.
- *
- * Determines what region of the texture should accept input. For
- * X based windows this is defined by the ShapeInput region of the
- * window.
- */
-void
-meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
- cairo_region_t *shape_region)
-{
- MetaShapedTexturePrivate *priv;
-
- g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
- priv = stex->priv;
-
- if (priv->input_shape_region != NULL)
- {
- cairo_region_destroy (priv->input_shape_region);
- priv->input_shape_region = NULL;
- }
-
- if (shape_region != NULL)
- {
- cairo_region_reference (shape_region);
- priv->input_shape_region = shape_region;
- }
-
- clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
-}
-
-/**
* meta_shaped_texture_set_opaque_region:
* @stex: a #MetaShapedTexture
* @opaque_region: (transfer full): the region of the texture that
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index 541094cff..5afa4d70f 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -22,8 +22,12 @@
struct _MetaSurfaceActorPrivate
{
+ MetaWaylandSurface *surface;
+
MetaShapedTexture *texture;
MetaWaylandBuffer *buffer;
+
+ cairo_region_t *input_region;
};
static void cullable_iface_init (MetaCullableInterface *iface);
@@ -40,8 +44,76 @@ meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
}
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);
}
+MetaWaylandSurface *
+meta_surface_actor_get_surface (MetaSurfaceActor *self)
+{
+ MetaSurfaceActorPrivate *priv = self->priv;
+ return priv->surface;
+}
+
MetaSurfaceActor *
-meta_surface_actor_new (void)
+meta_surface_actor_new (MetaWaylandSurface *surface)
{
- return g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
+ MetaSurfaceActor *self = g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
+ MetaSurfaceActorPrivate *priv = self->priv;
+
+ priv->surface = surface;
+
+ return self;
}
diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h
index fa7f0c307..e42deb42f 100644
--- a/src/compositor/meta-surface-actor.h
+++ b/src/compositor/meta-surface-actor.h
@@ -36,7 +36,7 @@ struct _MetaSurfaceActor
GType meta_surface_actor_get_type (void);
-MetaSurfaceActor *meta_surface_actor_new (void);
+MetaSurfaceActor *meta_surface_actor_new (MetaWaylandSurface *surface);
cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self,
cairo_rectangle_int_t *clip);
@@ -63,6 +63,8 @@ void meta_surface_actor_set_input_region (MetaSurfaceActor *self,
void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
cairo_region_t *region);
+MetaWaylandSurface *meta_surface_actor_get_surface (MetaSurfaceActor *surface);
+
G_END_DECLS
#endif /* META_SURFACE_ACTOR_PRIVATE_H */
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index f9568f393..c6071979c 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -353,7 +353,7 @@ meta_window_actor_constructed (GObject *object)
if (window->surface)
priv->surface = window->surface->surface_actor;
else
- priv->surface = meta_surface_actor_new ();
+ priv->surface = meta_surface_actor_new (NULL);
g_object_ref_sink (priv->surface);
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
@@ -1424,7 +1424,6 @@ meta_window_actor_hide (MetaWindowActor *self,
g_return_if_fail (priv->visible);
priv->visible = FALSE;
- clutter_actor_set_reactive (CLUTTER_ACTOR (self), FALSE);
/* If a plugin is animating a workspace transition, we have to
* hold off on hiding the window, and do it after the workspace
@@ -1557,8 +1556,6 @@ meta_window_actor_new (MetaWindow *window)
clutter_actor_hide (CLUTTER_ACTOR (self));
- clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
-
/* Initial position in the stack is arbitrary; stacking will be synced
* before we first paint.
*/
diff --git a/src/core/display.c b/src/core/display.c
index 749938fd8..907f1a597 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1682,8 +1682,12 @@ get_window_for_event (MetaDisplay *display,
return display->grab_window;
source = clutter_event_get_source (event);
- if (META_IS_WINDOW_ACTOR (source))
- return meta_window_actor_get_meta_window (META_WINDOW_ACTOR (source));
+ if (META_IS_SURFACE_ACTOR (source))
+ {
+ MetaWaylandSurface *surface = meta_surface_actor_get_surface (META_SURFACE_ACTOR (source));
+ g_assert (surface != NULL);
+ return surface->window;
+ }
return NULL;
}
diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h
index b0870bf95..80b23f2ea 100644
--- a/src/meta/meta-shaped-texture.h
+++ b/src/meta/meta-shaped-texture.h
@@ -75,9 +75,6 @@ CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
CoglTexture *mask_texture);
-void meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
- cairo_region_t *shape_region);
-
void meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex,
cairo_region_t *opaque_region);
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index ff6f57de6..df8e7814f 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -420,13 +420,8 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
else
seat->current_stage = NULL;
- if (META_IS_WINDOW_ACTOR (actor))
- {
- MetaWindow *window =
- meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor));
-
- surface = window->surface;
- }
+ if (META_IS_SURFACE_ACTOR (actor))
+ surface = meta_surface_actor_get_surface (META_SURFACE_ACTOR (actor));
pointer->current = surface;
if (surface != pointer->focus_surface)
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 2ae212d9c..10767cfff 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -645,7 +645,8 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface, wl_surface_destructor);
surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
- surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ());
+ surface->surface_actor = g_object_ref_sink (meta_surface_actor_new (surface));
+ clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE);
double_buffered_state_init (&surface->pending);