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);