diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index b20871ad8..da3f99a0b 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -40,6 +40,7 @@ struct _MetaCursorRendererPrivate int current_x, current_y; MetaCursorSprite *displayed_cursor; + MetaOverlay *stage_overlay; gboolean handled_by_backend; }; typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate; @@ -63,12 +64,16 @@ queue_redraw (MetaCursorRenderer *renderer, if (!stage) return; + if (!priv->stage_overlay) + priv->stage_overlay = meta_stage_create_cursor_overlay (META_STAGE (stage)); + if (cursor_sprite && !priv->handled_by_backend) texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); else texture = NULL; - meta_stage_set_cursor (META_STAGE (stage), texture, &rect); + meta_stage_update_cursor_overlay (META_STAGE (stage), priv->stage_overlay, + texture, &rect); } static gboolean @@ -81,9 +86,26 @@ meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer, return FALSE; } +static void +meta_cursor_renderer_finalize (GObject *object) +{ + MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object); + MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); + MetaBackend *backend = meta_get_backend (); + ClutterActor *stage = meta_backend_get_stage (backend); + + if (priv->stage_overlay) + meta_stage_remove_cursor_overlay (META_STAGE (stage), priv->stage_overlay); + + G_OBJECT_CLASS (meta_cursor_renderer_parent_class)->finalize (object); +} + static void meta_cursor_renderer_class_init (MetaCursorRendererClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_cursor_renderer_finalize; klass->update_cursor = meta_cursor_renderer_real_update_cursor; } diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c index eb270f1ba..5ac15d59c 100644 --- a/src/backends/meta-stage.c +++ b/src/backends/meta-stage.c @@ -27,7 +27,7 @@ #include #include -typedef struct { +struct _MetaOverlay { gboolean enabled; CoglPipeline *pipeline; @@ -36,22 +36,26 @@ typedef struct { MetaRectangle current_rect; MetaRectangle previous_rect; gboolean previous_is_valid; -} MetaOverlay; +}; struct _MetaStagePrivate { - MetaOverlay cursor_overlay; + GList *overlays; gboolean is_active; }; typedef struct _MetaStagePrivate MetaStagePrivate; G_DEFINE_TYPE_WITH_PRIVATE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE); -static void -meta_overlay_init (MetaOverlay *overlay) +static MetaOverlay * +meta_overlay_new () { + MetaOverlay *overlay; CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + overlay = g_slice_new0 (MetaOverlay); overlay->pipeline = cogl_pipeline_new (ctx); + + return overlay; } static void @@ -59,6 +63,8 @@ meta_overlay_free (MetaOverlay *overlay) { if (overlay->pipeline) cogl_object_unref (overlay->pipeline); + + g_slice_free (MetaOverlay, overlay); } static void @@ -111,8 +117,15 @@ meta_stage_finalize (GObject *object) { MetaStage *stage = META_STAGE (object); MetaStagePrivate *priv = meta_stage_get_instance_private (stage); + GList *l = priv->overlays; - meta_overlay_free (&priv->cursor_overlay); + while (l) + { + meta_overlay_free (l->data); + l = g_list_delete_link (l, l); + } + + G_OBJECT_CLASS (meta_stage_parent_class)->finalize (object); } static void @@ -120,10 +133,12 @@ meta_stage_paint (ClutterActor *actor) { MetaStage *stage = META_STAGE (actor); MetaStagePrivate *priv = meta_stage_get_instance_private (stage); + GList *l; CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor); - meta_overlay_paint (&priv->cursor_overlay); + for (l = priv->overlays; l; l = l->next) + meta_overlay_paint (l->data); } static void @@ -166,10 +181,6 @@ meta_stage_class_init (MetaStageClass *klass) static void meta_stage_init (MetaStage *stage) { - MetaStagePrivate *priv = meta_stage_get_instance_private (stage); - - meta_overlay_init (&priv->cursor_overlay); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), FALSE); } @@ -209,17 +220,43 @@ queue_redraw_for_overlay (MetaStage *stage, } } -void -meta_stage_set_cursor (MetaStage *stage, - CoglTexture *texture, - MetaRectangle *rect) +MetaOverlay * +meta_stage_create_cursor_overlay (MetaStage *stage) { MetaStagePrivate *priv = meta_stage_get_instance_private (stage); + MetaOverlay *overlay; + overlay = meta_overlay_new (); + priv->overlays = g_list_prepend (priv->overlays, overlay); + + return overlay; +} + +void +meta_stage_remove_cursor_overlay (MetaStage *stage, + MetaOverlay *overlay) +{ + MetaStagePrivate *priv = meta_stage_get_instance_private (stage); + GList *link; + + link = g_list_find (priv->overlays, overlay); + if (!link) + return; + + priv->overlays = g_list_delete_link (priv->overlays, link); + meta_overlay_free (overlay); +} + +void +meta_stage_update_cursor_overlay (MetaStage *stage, + MetaOverlay *overlay, + CoglTexture *texture, + MetaRectangle *rect) +{ g_assert (meta_is_wayland_compositor () || texture == NULL); - meta_overlay_set (&priv->cursor_overlay, texture, rect); - queue_redraw_for_overlay (stage, &priv->cursor_overlay); + meta_overlay_set (overlay, texture, rect); + queue_redraw_for_overlay (stage, overlay); } void diff --git a/src/backends/meta-stage.h b/src/backends/meta-stage.h index 262d68f7e..5376c7a2d 100644 --- a/src/backends/meta-stage.h +++ b/src/backends/meta-stage.h @@ -36,6 +36,7 @@ G_BEGIN_DECLS typedef struct _MetaStage MetaStage; typedef struct _MetaStageClass MetaStageClass; +typedef struct _MetaOverlay MetaOverlay; struct _MetaStageClass { @@ -51,9 +52,14 @@ GType meta_stage_get_type (void) G_GNUC_CONST; ClutterActor *meta_stage_new (void); -void meta_stage_set_cursor (MetaStage *stage, - CoglTexture *texture, - MetaRectangle *rect); +MetaOverlay *meta_stage_create_cursor_overlay (MetaStage *stage); +void meta_stage_remove_cursor_overlay (MetaStage *stage, + MetaOverlay *overlay); + +void meta_stage_update_cursor_overlay (MetaStage *stage, + MetaOverlay *overlay, + CoglTexture *texture, + MetaRectangle *rect); void meta_stage_set_active (MetaStage *stage, gboolean is_active);