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

View File

@ -54,6 +54,11 @@ void meta_stage_update_cursor_overlay (MetaStage *stage,
CoglTexture *texture, CoglTexture *texture,
graphene_rect_t *rect); 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, void meta_stage_set_active (MetaStage *stage,
gboolean is_active); gboolean is_active);

View File

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

View File

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