diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c index 81216440c..556b0177a 100644 --- a/clutter/clutter/clutter-stage-view.c +++ b/clutter/clutter/clutter-stage-view.c @@ -1634,3 +1634,15 @@ clutter_stage_view_invalidate_input_devices (ClutterStageView *view) priv->needs_update_devices = TRUE; } + +ClutterPaintFlag +clutter_stage_view_get_default_paint_flags (ClutterStageView *view) +{ + ClutterStageViewClass *view_class = + CLUTTER_STAGE_VIEW_GET_CLASS (view); + + if (view_class->get_default_paint_flags) + return view_class->get_default_paint_flags (view); + else + return CLUTTER_PAINT_FLAG_NONE; +} diff --git a/clutter/clutter/clutter-stage-view.h b/clutter/clutter/clutter-stage-view.h index a2c5aad15..c17c587a2 100644 --- a/clutter/clutter/clutter-stage-view.h +++ b/clutter/clutter/clutter-stage-view.h @@ -28,6 +28,7 @@ #include "clutter-macros.h" #include "clutter-frame-clock.h" +#include "clutter-types.h" #define CLUTTER_TYPE_STAGE_VIEW (clutter_stage_view_get_type ()) CLUTTER_EXPORT @@ -52,6 +53,8 @@ struct _ClutterStageViewClass cairo_rectangle_int_t *dst_rect); ClutterFrame * (* new_frame) (ClutterStageView *view); + + ClutterPaintFlag (* get_default_paint_flags) (ClutterStageView *view); }; CLUTTER_EXPORT @@ -90,4 +93,7 @@ gboolean clutter_stage_view_has_shadowfb (ClutterStageView *view); CLUTTER_EXPORT void clutter_stage_view_schedule_update_now (ClutterStageView *view); +CLUTTER_EXPORT +ClutterPaintFlag clutter_stage_view_get_default_paint_flags (ClutterStageView *view); + #endif /* __CLUTTER_STAGE_VIEW_H__ */ diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index b879db9c7..92876f11f 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -412,6 +412,7 @@ clutter_stage_do_paint_view (ClutterStage *stage, CoglFramebuffer *fb; ClutterColor bg_color; int n_rectangles; + ClutterPaintFlag paint_flags; n_rectangles = redraw_clip ? cairo_region_num_rectangles (redraw_clip) : 0; if (redraw_clip && n_rectangles < MAX_FRUSTA) @@ -445,10 +446,12 @@ clutter_stage_do_paint_view (ClutterStage *stage, _clutter_stage_paint_volume_stack_free_all (stage); + paint_flags = clutter_stage_view_get_default_paint_flags (view); + paint_context = clutter_paint_context_new_for_view (view, redraw_clip, clip_frusta, - CLUTTER_PAINT_FLAG_NONE); + paint_flags); if (frame) clutter_paint_context_assign_frame (paint_context, frame); diff --git a/clutter/clutter/clutter-types.h b/clutter/clutter/clutter-types.h index 4adb1db24..8c06f12f6 100644 --- a/clutter/clutter/clutter-types.h +++ b/clutter/clutter/clutter-types.h @@ -54,6 +54,7 @@ typedef struct _ClutterLayoutMeta ClutterLayoutMeta; typedef struct _ClutterActorMeta ClutterActorMeta; typedef struct _ClutterLayoutManager ClutterLayoutManager; typedef struct _ClutterActorIter ClutterActorIter; +typedef struct _ClutterPaintContext ClutterPaintContext; typedef struct _ClutterPaintNode ClutterPaintNode; typedef struct _ClutterContent ClutterContent; /* dummy */ typedef struct _ClutterScrollActor ClutterScrollActor; @@ -90,6 +91,8 @@ typedef struct _ClutterInputFocus ClutterInputFocus; typedef union _ClutterEvent ClutterEvent; +typedef enum _ClutterPaintFlag ClutterPaintFlag; + /** * ClutterEventSequence: * diff --git a/src/backends/meta-stage-view-private.h b/src/backends/meta-stage-view-private.h index f98e17c0b..22197e622 100644 --- a/src/backends/meta-stage-view-private.h +++ b/src/backends/meta-stage-view-private.h @@ -28,16 +28,10 @@ #include -#include "clutter/clutter-mutter.h" +#include "backends/meta-stage-view.h" G_BEGIN_DECLS -#define META_TYPE_STAGE_VIEW (meta_stage_view_get_type ()) - -G_DECLARE_DERIVABLE_TYPE (MetaStageView, - meta_stage_view, - META, STAGE_VIEW, - ClutterStageView) struct _MetaStageViewClass { diff --git a/src/backends/meta-stage-view.c b/src/backends/meta-stage-view.c index 473943196..2dae2c78d 100644 --- a/src/backends/meta-stage-view.c +++ b/src/backends/meta-stage-view.c @@ -34,6 +34,8 @@ typedef struct _MetaStageViewPrivate guint notify_presented_handle_id; CoglFrameClosure *frame_cb_closure; + + int inhibit_cursor_overlay_count; } MetaStageViewPrivate; G_DEFINE_TYPE_WITH_PRIVATE (MetaStageView, meta_stage_view, @@ -130,6 +132,19 @@ meta_stage_view_constructed (GObject *object) G_OBJECT_CLASS (meta_stage_view_parent_class)->constructed (object); } +static ClutterPaintFlag +meta_stage_view_get_default_paint_flags (ClutterStageView *clutter_view) +{ + MetaStageView *view = META_STAGE_VIEW (clutter_view); + MetaStageViewPrivate *priv = + meta_stage_view_get_instance_private (view); + + if (priv->inhibit_cursor_overlay_count > 0) + return CLUTTER_PAINT_FLAG_NO_CURSORS; + else + return CLUTTER_PAINT_FLAG_NONE; +} + static void meta_stage_view_init (MetaStageView *view) { @@ -143,9 +158,13 @@ static void meta_stage_view_class_init (MetaStageViewClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_CLASS (klass); object_class->constructed = meta_stage_view_constructed; object_class->dispose = meta_stage_view_dispose; + + view_class->get_default_paint_flags = + meta_stage_view_get_default_paint_flags; } ClutterDamageHistory * @@ -202,3 +221,23 @@ meta_stage_view_perform_fake_swap (MetaStageView *view, notify_presented_idle, closure, g_free); } + +void +meta_stage_view_inhibit_cursor_overlay (MetaStageView *view) +{ + MetaStageViewPrivate *priv = + meta_stage_view_get_instance_private (view); + + priv->inhibit_cursor_overlay_count++; +} + +void +meta_stage_view_uninhibit_cursor_overlay (MetaStageView *view) +{ + MetaStageViewPrivate *priv = + meta_stage_view_get_instance_private (view); + + g_return_if_fail (priv->inhibit_cursor_overlay_count > 0); + + priv->inhibit_cursor_overlay_count--; +} diff --git a/src/backends/meta-stage-view.h b/src/backends/meta-stage-view.h new file mode 100644 index 000000000..40ae6972c --- /dev/null +++ b/src/backends/meta-stage-view.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2022 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef META_STAGE_VIEW_H +#define META_STAGE_VIEW_H + +#include "clutter/clutter-mutter.h" + +#define META_TYPE_STAGE_VIEW (meta_stage_view_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaStageView, + meta_stage_view, + META, STAGE_VIEW, + ClutterStageView) + +void meta_stage_view_inhibit_cursor_overlay (MetaStageView *view); + +void meta_stage_view_uninhibit_cursor_overlay (MetaStageView *view); + +#endif /* META_STAGE_VIEW_H */ diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c index 30151355f..05a11d67d 100644 --- a/src/backends/meta-stage.c +++ b/src/backends/meta-stage.c @@ -379,13 +379,33 @@ queue_redraw_clutter_rect (MetaStage *stage, .width = ceilf (rect->size.width), .height = ceilf (rect->size.height) }; + GList *l; /* Since we're flooring the coordinates, we need to enlarge the clip by the * difference between the actual coordinate and the floored value */ clip.width += ceilf (rect->origin.x - clip.x) * 2; clip.height += ceilf (rect->origin.y - clip.y) * 2; - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip); + for (l = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage)); + l; + l = l->next) + { + ClutterStageView *view = l->data; + cairo_rectangle_int_t view_layout; + cairo_rectangle_int_t view_clip; + + if (clutter_stage_view_get_default_paint_flags (view) & + CLUTTER_PAINT_FLAG_NO_CURSORS) + continue; + + clutter_stage_view_get_layout (view, &view_layout); + + if (meta_rectangle_intersect (&clip, &view_layout, &view_clip)) + { + clutter_stage_view_add_redraw_clip (view, &view_clip); + clutter_stage_view_schedule_update (view); + } + } } static void