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)); @@ -463,71 +458,6 @@ meta_shaped_texture_paint (ClutterActor *actor) cairo_region_destroy (blended_region); } -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, @@ -764,41 +694,6 @@ meta_shaped_texture_get_texture (MetaShapedTexture *stex) return COGL_TEXTURE (stex->priv->texture); } -/** - * 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 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); @@ -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; } 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);