st/viewport: Add clip-to-view property

This property controls whether the viewport clips the content to its own
allocation or not. This will be necessary in special modes that we want to
render past the viewport inside a scrollview.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1630>
This commit is contained in:
Carlos Garnacho 2021-02-03 12:03:11 +01:00 committed by Marge Bot
parent 260f5b0b8d
commit 8cb3825d48

View File

@ -55,6 +55,7 @@ static void st_viewport_scrollable_interface_init (StScrollableInterface *iface)
enum { enum {
PROP_0, PROP_0,
PROP_CLIP_TO_VIEW,
PROP_HADJUST, PROP_HADJUST,
PROP_VADJUST PROP_VADJUST
}; };
@ -63,6 +64,7 @@ typedef struct
{ {
StAdjustment *hadjustment; StAdjustment *hadjustment;
StAdjustment *vadjustment; StAdjustment *vadjustment;
gboolean clip_to_view;
} StViewportPrivate; } StViewportPrivate;
G_DEFINE_TYPE_WITH_CODE (StViewport, st_viewport, ST_TYPE_WIDGET, G_DEFINE_TYPE_WITH_CODE (StViewport, st_viewport, ST_TYPE_WIDGET,
@ -163,12 +165,28 @@ st_viewport_scrollable_interface_init (StScrollableInterface *iface)
iface->get_adjustments = scrollable_get_adjustments; iface->get_adjustments = scrollable_get_adjustments;
} }
static void
st_viewport_set_clip_to_view (StViewport *viewport,
gboolean clip_to_view)
{
StViewportPrivate *priv =
st_viewport_get_instance_private (viewport);
if (!!priv->clip_to_view != !!clip_to_view)
{
priv->clip_to_view = clip_to_view;
clutter_actor_queue_redraw (CLUTTER_ACTOR (viewport));
}
}
static void static void
st_viewport_get_property (GObject *object, st_viewport_get_property (GObject *object,
guint property_id, guint property_id,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
StViewportPrivate *priv =
st_viewport_get_instance_private (ST_VIEWPORT (object));
StAdjustment *adjustment; StAdjustment *adjustment;
switch (property_id) switch (property_id)
@ -183,6 +201,10 @@ st_viewport_get_property (GObject *object,
g_value_set_object (value, adjustment); g_value_set_object (value, adjustment);
break; break;
case PROP_CLIP_TO_VIEW:
g_value_set_boolean (value, priv->clip_to_view);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
} }
@ -212,6 +234,10 @@ st_viewport_set_property (GObject *object,
g_value_get_object (value)); g_value_get_object (value));
break; break;
case PROP_CLIP_TO_VIEW:
st_viewport_set_clip_to_view (viewport, g_value_get_boolean (value));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
} }
@ -405,7 +431,7 @@ st_viewport_paint (ClutterActor *actor,
/* The content area forms the viewport into the scrolled contents, while /* The content area forms the viewport into the scrolled contents, while
* the borders and background stay in place; after drawing the borders and * the borders and background stay in place; after drawing the borders and
* background, we clip to the content area */ * background, we clip to the content area */
if (priv->hadjustment || priv->vadjustment) if (priv->clip_to_view && (priv->hadjustment || priv->vadjustment))
{ {
cogl_framebuffer_push_rectangle_clip (fb, cogl_framebuffer_push_rectangle_clip (fb,
(int)content_box.x1, (int)content_box.x1,
@ -419,7 +445,7 @@ st_viewport_paint (ClutterActor *actor,
child = clutter_actor_get_next_sibling (child)) child = clutter_actor_get_next_sibling (child))
clutter_actor_paint (child, paint_context); clutter_actor_paint (child, paint_context);
if (priv->hadjustment || priv->vadjustment) if (priv->clip_to_view && (priv->hadjustment || priv->vadjustment))
cogl_framebuffer_pop_clip (fb); cogl_framebuffer_pop_clip (fb);
} }
@ -478,6 +504,9 @@ st_viewport_get_paint_volume (ClutterActor *actor,
if (!clutter_actor_has_allocation (actor)) if (!clutter_actor_has_allocation (actor))
return FALSE; return FALSE;
if (!priv->clip_to_view)
return CLUTTER_ACTOR_CLASS (st_viewport_parent_class)->get_paint_volume (actor, volume);
/* When have an adjustment we are clipped to the content box, so base /* When have an adjustment we are clipped to the content box, so base
* our paint volume on that. */ * our paint volume on that. */
if (priv->hadjustment || priv->vadjustment) if (priv->hadjustment || priv->vadjustment)
@ -558,6 +587,14 @@ st_viewport_class_init (StViewportClass *klass)
actor_class->get_paint_volume = st_viewport_get_paint_volume; actor_class->get_paint_volume = st_viewport_get_paint_volume;
actor_class->pick = st_viewport_pick; actor_class->pick = st_viewport_pick;
g_object_class_install_property (object_class,
PROP_CLIP_TO_VIEW,
g_param_spec_boolean ("clip-to-view",
"Clip to view",
"Clip to view",
TRUE,
ST_PARAM_READWRITE));
/* StScrollable properties */ /* StScrollable properties */
g_object_class_override_property (object_class, g_object_class_override_property (object_class,
PROP_HADJUST, PROP_HADJUST,
@ -566,10 +603,13 @@ st_viewport_class_init (StViewportClass *klass)
g_object_class_override_property (object_class, g_object_class_override_property (object_class,
PROP_VADJUST, PROP_VADJUST,
"vadjustment"); "vadjustment");
} }
static void static void
st_viewport_init (StViewport *self) st_viewport_init (StViewport *self)
{ {
StViewportPrivate *priv =
st_viewport_get_instance_private (self);
priv->clip_to_view = TRUE;
} }