cursor-renderer: Always keep the cursor overlay on the stage

Only when the cursor isn't handled by the backend is the overlay made
visible. This is intended to be used when painting the stage to an
offscreen using clutter_stage_paint_to_(frame)buffer() in a way where
the cursor is always included.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1391
This commit is contained in:
Jonas Ådahl 2020-07-29 10:32:58 +02:00
parent d8be2a8b85
commit fcf7c4d0c7
4 changed files with 44 additions and 31 deletions

View File

@ -124,8 +124,8 @@ align_cursor_position (MetaCursorRenderer *renderer,
}
static void
queue_redraw (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
update_stage_overlay (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
ClutterActor *stage = meta_backend_get_stage (priv->backend);
@ -145,11 +145,12 @@ queue_redraw (MetaCursorRenderer *renderer,
if (!priv->stage_overlay)
priv->stage_overlay = meta_stage_create_cursor_overlay (META_STAGE (stage));
if (cursor_sprite && !priv->handled_by_backend)
if (cursor_sprite)
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
else
texture = NULL;
meta_overlay_set_visible (priv->stage_overlay, !priv->handled_by_backend);
meta_stage_update_cursor_overlay (META_STAGE (stage), priv->stage_overlay,
texture, &rect);
}
@ -334,7 +335,6 @@ meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
gboolean handled_by_backend;
gboolean should_redraw = FALSE;
if (cursor_sprite)
meta_cursor_sprite_prepare_at (cursor_sprite,
@ -345,16 +345,9 @@ meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer,
cursor_sprite);
if (handled_by_backend != priv->handled_by_backend)
{
priv->handled_by_backend = handled_by_backend;
should_redraw = TRUE;
}
priv->handled_by_backend = handled_by_backend;
if (!handled_by_backend)
should_redraw = TRUE;
if (should_redraw)
queue_redraw (renderer, cursor_sprite);
update_stage_overlay (renderer, cursor_sprite);
}
MetaCursorRenderer *

View File

@ -54,6 +54,11 @@ void meta_stage_update_cursor_overlay (MetaStage *stage,
CoglTexture *texture,
graphene_rect_t *rect);
void meta_overlay_set_visible (MetaOverlay *overlay,
gboolean is_visible);
gboolean meta_overlay_is_visible (MetaOverlay *overlay);
void meta_stage_set_active (MetaStage *stage,
gboolean is_active);

View File

@ -50,7 +50,9 @@ struct _MetaStageWatch
struct _MetaOverlay
{
gboolean enabled;
MetaStage *stage;
gboolean is_visible;
CoglPipeline *pipeline;
CoglTexture *texture;
@ -75,12 +77,15 @@ struct _MetaStage
G_DEFINE_TYPE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE);
static MetaOverlay *
meta_overlay_new (void)
meta_overlay_new (MetaStage *stage)
{
ClutterBackend *clutter_backend =
meta_backend_get_clutter_backend (stage->backend);
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_backend);
MetaOverlay *overlay;
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
overlay = g_slice_new0 (MetaOverlay);
overlay->stage = stage;
overlay->pipeline = cogl_pipeline_new (ctx);
return overlay;
@ -105,15 +110,9 @@ meta_overlay_set (MetaOverlay *overlay,
overlay->texture = texture;
if (texture)
{
cogl_pipeline_set_layer_texture (overlay->pipeline, 0, texture);
overlay->enabled = TRUE;
}
cogl_pipeline_set_layer_texture (overlay->pipeline, 0, texture);
else
{
cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL);
overlay->enabled = FALSE;
}
cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL);
}
overlay->current_rect = *rect;
@ -125,10 +124,11 @@ meta_overlay_paint (MetaOverlay *overlay,
{
CoglFramebuffer *framebuffer;
if (!overlay->enabled)
if (!overlay->texture)
return;
g_assert (meta_is_wayland_compositor ());
if (!overlay->is_visible)
return;
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
cogl_framebuffer_draw_rectangle (framebuffer,
@ -345,7 +345,7 @@ queue_redraw_for_overlay (MetaStage *stage,
}
/* Draw the overlay at the new position */
if (overlay->enabled)
if (overlay->is_visible && overlay->texture)
queue_redraw_clutter_rect (stage, overlay, &overlay->current_rect);
}
@ -354,7 +354,7 @@ meta_stage_create_cursor_overlay (MetaStage *stage)
{
MetaOverlay *overlay;
overlay = meta_overlay_new ();
overlay = meta_overlay_new (stage);
stage->overlays = g_list_prepend (stage->overlays, overlay);
return overlay;
@ -380,12 +380,27 @@ meta_stage_update_cursor_overlay (MetaStage *stage,
CoglTexture *texture,
graphene_rect_t *rect)
{
g_assert (meta_is_wayland_compositor () || texture == NULL);
meta_overlay_set (overlay, texture, rect);
queue_redraw_for_overlay (stage, overlay);
}
void
meta_overlay_set_visible (MetaOverlay *overlay,
gboolean is_visible)
{
if (overlay->is_visible == is_visible)
return;
overlay->is_visible = is_visible;
queue_redraw_for_overlay (overlay->stage, overlay);
}
gboolean
meta_overlay_is_visible (MetaOverlay *overlay)
{
return overlay->is_visible;
}
void
meta_stage_set_active (MetaStage *stage,
gboolean is_active)

View File

@ -90,7 +90,7 @@ meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer,
priv->server_cursor_visible = has_server_cursor;
}
if (!priv->server_cursor_visible && cursor_sprite)
if (cursor_sprite)
meta_cursor_sprite_realize_texture (cursor_sprite);
return priv->server_cursor_visible;