st/scroll-view: Stop implementing ClutterContainer

Instead, listen to ::actor-{added,removed} allowing ClutterActor's
regular add/remove API to work as expected — at least so long only one
child is added

We also no longer inherit StBin as we actually have up to three
children (including the two scrollbars), but by implementing :child
ourselves the API seen by JS is unchanged

Fix: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2661
Fix: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3172
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3010>
This commit is contained in:
Zander Brown 2023-11-08 07:36:30 +00:00 committed by Marge Bot
parent b36f81b955
commit 42fc986e91
2 changed files with 275 additions and 164 deletions

View File

@ -67,16 +67,9 @@
#include <clutter/clutter.h>
#include <math.h>
static void clutter_container_iface_init (ClutterContainerIface *iface);
static ClutterContainerIface *st_scroll_view_parent_iface = NULL;
typedef struct _StScrollViewPrivate StScrollViewPrivate;
struct _StScrollViewPrivate
{
/* a pointer to the child; this is actually stored
* inside StBin:child, but we keep it to avoid
* calling st_bin_get_child() every time we need it
*/
ClutterActor *child;
StAdjustment *hadjustment;
@ -98,14 +91,12 @@ struct _StScrollViewPrivate
guint vscrollbar_visible : 1;
};
G_DEFINE_TYPE_WITH_CODE (StScrollView, st_scroll_view, ST_TYPE_BIN,
G_ADD_PRIVATE (StScrollView)
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
clutter_container_iface_init))
G_DEFINE_TYPE_WITH_PRIVATE (StScrollView, st_scroll_view, ST_TYPE_WIDGET)
enum {
PROP_0,
PROP_CHILD,
PROP_HSCROLL,
PROP_VSCROLL,
PROP_HSCROLLBAR_POLICY,
@ -126,10 +117,14 @@ st_scroll_view_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
StScrollViewPrivate *priv = ((StScrollView *) object)->priv;
StScrollViewPrivate *priv =
st_scroll_view_get_instance_private (ST_SCROLL_VIEW (object));
switch (property_id)
{
case PROP_CHILD:
g_value_set_object (value, priv->child);
break;
case PROP_HSCROLL:
g_value_set_object (value, priv->hscroll);
break;
@ -210,10 +205,13 @@ st_scroll_view_set_property (GObject *object,
GParamSpec *pspec)
{
StScrollView *self = ST_SCROLL_VIEW (object);
StScrollViewPrivate *priv = self->priv;
StScrollViewPrivate *priv = st_scroll_view_get_instance_private (self);
switch (property_id)
{
case PROP_CHILD:
st_scroll_view_set_child (self, g_value_get_object (value));
break;
case PROP_MOUSE_SCROLL:
st_scroll_view_set_mouse_scrolling (self,
g_value_get_boolean (value));
@ -240,15 +238,17 @@ st_scroll_view_set_property (GObject *object,
static void
st_scroll_view_dispose (GObject *object)
{
StScrollViewPrivate *priv = ST_SCROLL_VIEW (object)->priv;
StScrollViewPrivate *priv =
st_scroll_view_get_instance_private (ST_SCROLL_VIEW (object));
/* The fade effect disconnects from the adjustments and
* needs to be removed while those are still alive.
*/
clutter_actor_clear_effects (CLUTTER_ACTOR (object));
g_clear_pointer (&priv->vscroll, clutter_actor_destroy);
g_clear_pointer (&priv->hscroll, clutter_actor_destroy);
g_clear_weak_pointer (&priv->child);
g_clear_weak_pointer (&priv->vscroll);
g_clear_weak_pointer (&priv->hscroll);
/* For most reliable freeing of memory, an object with signals
* like StAdjustment should be explicitly disposed. Since we own
@ -256,18 +256,14 @@ st_scroll_view_dispose (GObject *object)
* the signal handlers that we established on creation.
*/
if (priv->hadjustment)
{
g_object_run_dispose (G_OBJECT (priv->hadjustment));
g_object_unref (priv->hadjustment);
priv->hadjustment = NULL;
}
g_object_run_dispose (G_OBJECT (priv->hadjustment));
g_clear_object (&priv->hadjustment);
if (priv->vadjustment)
{
g_object_run_dispose (G_OBJECT (priv->vadjustment));
g_object_unref (priv->vadjustment);
priv->vadjustment = NULL;
}
g_object_run_dispose (G_OBJECT (priv->vadjustment));
g_clear_object (&priv->vadjustment);
G_OBJECT_CLASS (st_scroll_view_parent_class)->dispose (object);
}
@ -276,7 +272,8 @@ static void
st_scroll_view_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{
StScrollViewPrivate *priv = ST_SCROLL_VIEW (actor)->priv;
StScrollViewPrivate *priv =
st_scroll_view_get_instance_private (ST_SCROLL_VIEW (actor));
st_widget_paint_background (ST_WIDGET (actor), paint_context);
@ -292,7 +289,8 @@ static void
st_scroll_view_pick (ClutterActor *actor,
ClutterPickContext *pick_context)
{
StScrollViewPrivate *priv = ST_SCROLL_VIEW (actor)->priv;
StScrollViewPrivate *priv =
st_scroll_view_get_instance_private (ST_SCROLL_VIEW (actor));
/* Chain up so we get a bounding box pained (if we are reactive) */
CLUTTER_ACTOR_CLASS (st_scroll_view_parent_class)->pick (actor, pick_context);
@ -316,7 +314,7 @@ static double
get_scrollbar_width (StScrollView *scroll,
gfloat for_height)
{
StScrollViewPrivate *priv = scroll->priv;
StScrollViewPrivate *priv = st_scroll_view_get_instance_private (scroll);
if (clutter_actor_is_visible (priv->vscroll))
{
@ -334,7 +332,7 @@ static double
get_scrollbar_height (StScrollView *scroll,
gfloat for_width)
{
StScrollViewPrivate *priv = scroll->priv;
StScrollViewPrivate *priv = st_scroll_view_get_instance_private (scroll);
if (clutter_actor_is_visible (priv->hscroll))
{
@ -355,7 +353,8 @@ st_scroll_view_get_preferred_width (ClutterActor *actor,
gfloat *min_width_p,
gfloat *natural_width_p)
{
StScrollViewPrivate *priv = ST_SCROLL_VIEW (actor)->priv;
StScrollViewPrivate *priv =
st_scroll_view_get_instance_private (ST_SCROLL_VIEW (actor));
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
gboolean account_for_vscrollbar = FALSE;
gfloat min_width = 0, natural_width;
@ -432,7 +431,8 @@ st_scroll_view_get_preferred_height (ClutterActor *actor,
gfloat *min_height_p,
gfloat *natural_height_p)
{
StScrollViewPrivate *priv = ST_SCROLL_VIEW (actor)->priv;
StScrollViewPrivate *priv =
st_scroll_view_get_instance_private (ST_SCROLL_VIEW (actor));
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
gboolean account_for_hscrollbar = FALSE;
gfloat min_height = 0, natural_height;
@ -532,11 +532,11 @@ static void
st_scroll_view_allocate (ClutterActor *actor,
const ClutterActorBox *box)
{
StScrollViewPrivate *priv =
st_scroll_view_get_instance_private (ST_SCROLL_VIEW (actor));
ClutterActorBox content_box, child_box;
gfloat avail_width, avail_height, sb_width, sb_height;
gboolean hscrollbar_visible, vscrollbar_visible;
StScrollViewPrivate *priv = ST_SCROLL_VIEW (actor)->priv;
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
clutter_actor_set_allocation (actor, box);
@ -762,7 +762,8 @@ static gboolean
st_scroll_view_scroll_event (ClutterActor *self,
ClutterEvent *event)
{
StScrollViewPrivate *priv = ST_SCROLL_VIEW (self)->priv;
StScrollViewPrivate *priv =
st_scroll_view_get_instance_private (ST_SCROLL_VIEW (self));
ClutterTextDirection direction;
ClutterScrollDirection scroll_direction;
@ -818,6 +819,44 @@ st_scroll_view_scroll_event (ClutterActor *self,
return TRUE;
}
static void
st_scroll_view_popup_menu (StWidget *widget)
{
StScrollViewPrivate *priv =
st_scroll_view_get_instance_private (ST_SCROLL_VIEW (widget));
if (priv->child && ST_IS_WIDGET (priv->child))
st_widget_popup_menu (ST_WIDGET (priv->child));
}
static gboolean
st_scroll_view_navigate_focus (StWidget *widget,
ClutterActor *from,
StDirectionType direction)
{
StScrollViewPrivate *priv =
st_scroll_view_get_instance_private (ST_SCROLL_VIEW (widget));
ClutterActor *bin_actor = CLUTTER_ACTOR (widget);
if (st_widget_get_can_focus (widget))
{
if (from && clutter_actor_contains (bin_actor, from))
return FALSE;
if (clutter_actor_is_mapped (bin_actor))
{
clutter_actor_grab_key_focus (bin_actor);
return TRUE;
}
else
return FALSE;
}
else if (priv->child && ST_IS_WIDGET (priv->child))
return st_widget_navigate_focus (ST_WIDGET (priv->child), from, direction, FALSE);
else
return FALSE;
}
static void
st_scroll_view_class_init (StScrollViewClass *klass)
{
@ -838,6 +877,18 @@ st_scroll_view_class_init (StScrollViewClass *klass)
actor_class->scroll_event = st_scroll_view_scroll_event;
widget_class->style_changed = st_scroll_view_style_changed;
widget_class->popup_menu = st_scroll_view_popup_menu;
widget_class->navigate_focus = st_scroll_view_navigate_focus;
/**
* StScrollView:child:
*
* The child #StScrollable of the #StScrollView container.
*/
props[PROP_CHILD] =
g_param_spec_object ("child", NULL, NULL,
ST_TYPE_SCROLLABLE,
ST_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* StScrollView:hscroll:
@ -940,10 +991,68 @@ st_scroll_view_class_init (StScrollViewClass *klass)
g_object_class_install_properties (object_class, N_PROPS, props);
}
static void
set_child (StScrollView *scroll, ClutterActor *child)
{
StScrollViewPrivate *priv = st_scroll_view_get_instance_private (scroll);
ClutterActor *old = priv->child;
if (!g_set_weak_pointer (&priv->child, child))
return;
if (old)
st_scrollable_set_adjustments (ST_SCROLLABLE (old), NULL, NULL);
if (priv->child)
st_scrollable_set_adjustments (ST_SCROLLABLE (priv->child),
priv->hadjustment,
priv->vadjustment);
g_object_notify_by_pspec (G_OBJECT (scroll), props[PROP_CHILD]);
}
static void
actor_added (ClutterActor *container,
ClutterActor *actor)
{
StScrollView *scroll = ST_SCROLL_VIEW (container);
StScrollViewPrivate *priv = st_scroll_view_get_instance_private (scroll);
if (!ST_IS_SCROLLABLE (actor))
{
g_warning ("Attempting to add an actor of type %s to "
"an StScrollView, but the actor does "
"not implement StScrollable.",
G_OBJECT_TYPE_NAME (actor));
return;
}
if (priv->child)
g_warning ("Attempting to add an actor of type %s to "
"an StScrollView, but the view already contains a %s. "
"Was add_child() used repeatedly?",
G_OBJECT_TYPE_NAME (actor),
G_OBJECT_TYPE_NAME (priv->child));
set_child (scroll, actor);
}
static void
actor_removed (ClutterActor *container,
ClutterActor *actor)
{
StScrollView *scroll = ST_SCROLL_VIEW (container);
StScrollViewPrivate *priv = st_scroll_view_get_instance_private (scroll);
if (priv->child == actor)
set_child (scroll, NULL);
}
static void
st_scroll_view_init (StScrollView *self)
{
StScrollViewPrivate *priv = self->priv = st_scroll_view_get_instance_private (self);
StScrollViewPrivate *priv = st_scroll_view_get_instance_private (self);
ClutterActor *scrollbar;
priv->hscrollbar_policy = ST_POLICY_AUTOMATIC;
priv->vscrollbar_policy = ST_POLICY_AUTOMATIC;
@ -951,97 +1060,31 @@ st_scroll_view_init (StScrollView *self)
priv->hadjustment = g_object_new (ST_TYPE_ADJUSTMENT,
"actor", self,
NULL);
priv->hscroll = g_object_new (ST_TYPE_SCROLL_BAR,
"adjustment", priv->hadjustment,
"vertical", FALSE,
NULL);
scrollbar = g_object_new (ST_TYPE_SCROLL_BAR,
"adjustment", priv->hadjustment,
"vertical", FALSE,
NULL);
g_set_weak_pointer (&priv->hscroll, scrollbar);
priv->vadjustment = g_object_new (ST_TYPE_ADJUSTMENT,
"actor", self,
NULL);
priv->vscroll = g_object_new (ST_TYPE_SCROLL_BAR,
"adjustment", priv->vadjustment,
"vertical", TRUE,
NULL);
scrollbar = g_object_new (ST_TYPE_SCROLL_BAR,
"adjustment", priv->vadjustment,
"vertical", TRUE,
NULL);
g_set_weak_pointer (&priv->vscroll, scrollbar);
clutter_actor_add_child (CLUTTER_ACTOR (self), priv->hscroll);
clutter_actor_add_child (CLUTTER_ACTOR (self), priv->vscroll);
/* mouse scroll is enabled by default, so we also need to be reactive */
priv->mouse_scroll = TRUE;
g_object_set (G_OBJECT (self), "reactive", TRUE, NULL);
}
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
static void
st_scroll_view_add (ClutterContainer *container,
ClutterActor *actor)
{
StScrollView *self = ST_SCROLL_VIEW (container);
StScrollViewPrivate *priv = self->priv;
if (ST_IS_SCROLLABLE (actor))
{
priv->child = actor;
/* chain up to StBin::add() */
st_scroll_view_parent_iface->add (container, actor);
st_scrollable_set_adjustments (ST_SCROLLABLE (actor),
priv->hadjustment, priv->vadjustment);
}
else
{
g_warning ("Attempting to add an actor of type %s to "
"a StScrollView, but the actor does "
"not implement StScrollable.",
g_type_name (G_OBJECT_TYPE (actor)));
}
}
static void
st_scroll_view_remove (ClutterContainer *container,
ClutterActor *actor)
{
StScrollView *self = ST_SCROLL_VIEW (container);
StScrollViewPrivate *priv = self->priv;
if (actor == priv->child)
{
g_object_ref (priv->child);
/* chain up to StBin::remove() */
st_scroll_view_parent_iface->remove (container, actor);
st_scrollable_set_adjustments (ST_SCROLLABLE (priv->child),
NULL, NULL);
g_object_unref (priv->child);
priv->child = NULL;
}
else
{
if (actor == priv->vscroll)
priv->vscroll = NULL;
else if (actor == priv->hscroll)
priv->hscroll = NULL;
else
g_assert ("Unknown child removed from StScrollView");
clutter_actor_remove_child (CLUTTER_ACTOR (container), actor);
}
}
static void
clutter_container_iface_init (ClutterContainerIface *iface)
{
/* store a pointer to the StBin implementation of
* ClutterContainer so that we can chain up when
* overriding the methods
*/
st_scroll_view_parent_iface = g_type_interface_peek_parent (iface);
iface->add = st_scroll_view_add;
iface->remove = st_scroll_view_remove;
/* Connect these *after* we've added our internal actors */
g_signal_connect (self, "actor-added", G_CALLBACK (actor_added), NULL);
g_signal_connect (self, "actor-removed", G_CALLBACK (actor_removed), NULL);
}
/**
@ -1057,6 +1100,61 @@ st_scroll_view_new (void)
return g_object_new (ST_TYPE_SCROLL_VIEW, NULL);
}
/**
* st_scroll_view_get_child:
* @scroll: a #StBin
*
* Gets the #StScrollable content of @scroll.
*
* Returns: (transfer none) (nullable): a #StScrollable, or %NULL
*/
StScrollable *
st_scroll_view_get_child (StScrollView *scroll)
{
StScrollViewPrivate *priv;
g_return_val_if_fail (ST_IS_SCROLL_VIEW (scroll), NULL);
priv = st_scroll_view_get_instance_private (scroll);
if (!priv->child)
return NULL;
return ST_SCROLLABLE (priv->child);
}
/**
* st_scroll_view_set_child:
* @scroll: a #StScrollView
* @child: (nullable): a #StScrollable, or %NULL
*
* Sets @child as the content of @scroll.
*
* If @scroll already has a child, the previous child is removed.
*/
void
st_scroll_view_set_child (StScrollView *scroll,
StScrollable *child)
{
StScrollViewPrivate *priv;
g_return_if_fail (ST_IS_SCROLL_VIEW (scroll));
g_return_if_fail (child == NULL || ST_IS_SCROLLABLE (child));
priv = st_scroll_view_get_instance_private (scroll);
g_object_freeze_notify (G_OBJECT (scroll));
if (priv->child)
clutter_actor_remove_child (CLUTTER_ACTOR (scroll), priv->child);
if (child)
clutter_actor_add_child (CLUTTER_ACTOR (scroll),
CLUTTER_ACTOR (child));
g_object_thaw_notify (G_OBJECT (scroll));
}
/**
* st_scroll_view_get_hscroll_bar:
* @scroll: a #StScrollView
@ -1068,9 +1166,13 @@ st_scroll_view_new (void)
ClutterActor *
st_scroll_view_get_hscroll_bar (StScrollView *scroll)
{
StScrollViewPrivate *priv;
g_return_val_if_fail (ST_IS_SCROLL_VIEW (scroll), NULL);
return scroll->priv->hscroll;
priv = st_scroll_view_get_instance_private (scroll);
return priv->hscroll;
}
/**
@ -1084,9 +1186,13 @@ st_scroll_view_get_hscroll_bar (StScrollView *scroll)
ClutterActor *
st_scroll_view_get_vscroll_bar (StScrollView *scroll)
{
StScrollViewPrivate *priv;
g_return_val_if_fail (ST_IS_SCROLL_VIEW (scroll), NULL);
return scroll->priv->vscroll;
priv = st_scroll_view_get_instance_private (scroll);
return priv->vscroll;
}
/**
@ -1100,11 +1206,14 @@ st_scroll_view_get_vscroll_bar (StScrollView *scroll)
gfloat
st_scroll_view_get_column_size (StScrollView *scroll)
{
StScrollViewPrivate *priv;
gdouble column_size;
g_return_val_if_fail (scroll, 0);
g_return_val_if_fail (ST_IS_SCROLL_VIEW (scroll), 0);
g_object_get (scroll->priv->hadjustment,
priv = st_scroll_view_get_instance_private (scroll);
g_object_get (priv->hadjustment,
"step-increment", &column_size,
NULL);
@ -1122,20 +1231,24 @@ void
st_scroll_view_set_column_size (StScrollView *scroll,
gfloat column_size)
{
g_return_if_fail (scroll);
StScrollViewPrivate *priv;
g_return_if_fail (ST_IS_SCROLL_VIEW (scroll));
priv = st_scroll_view_get_instance_private (scroll);
if (column_size < 0)
{
scroll->priv->column_size_set = FALSE;
scroll->priv->column_size = -1;
priv->column_size_set = FALSE;
priv->column_size = -1;
}
else
{
scroll->priv->column_size_set = TRUE;
scroll->priv->column_size = column_size;
priv->column_size_set = TRUE;
priv->column_size = column_size;
g_object_set (scroll->priv->hadjustment,
"step-increment", (gdouble) scroll->priv->column_size,
g_object_set (priv->hadjustment,
"step-increment", (double) priv->column_size,
NULL);
}
}
@ -1151,11 +1264,14 @@ st_scroll_view_set_column_size (StScrollView *scroll,
gfloat
st_scroll_view_get_row_size (StScrollView *scroll)
{
StScrollViewPrivate *priv;
gdouble row_size;
g_return_val_if_fail (scroll, 0);
g_return_val_if_fail (ST_IS_SCROLL_VIEW (scroll), 0);
g_object_get (scroll->priv->vadjustment,
priv = st_scroll_view_get_instance_private (scroll);
g_object_get (priv->vadjustment,
"step-increment", &row_size,
NULL);
@ -1173,20 +1289,24 @@ void
st_scroll_view_set_row_size (StScrollView *scroll,
gfloat row_size)
{
g_return_if_fail (scroll);
StScrollViewPrivate *priv;
g_return_if_fail (ST_IS_SCROLL_VIEW (scroll));
priv = st_scroll_view_get_instance_private (scroll);
if (row_size < 0)
{
scroll->priv->row_size_set = FALSE;
scroll->priv->row_size = -1;
priv->row_size_set = FALSE;
priv->row_size = -1;
}
else
{
scroll->priv->row_size_set = TRUE;
scroll->priv->row_size = row_size;
priv->row_size_set = TRUE;
priv->row_size = row_size;
g_object_set (scroll->priv->vadjustment,
"step-increment", (gdouble) scroll->priv->row_size,
g_object_set (priv->vadjustment,
"step-increment", (double) priv->row_size,
NULL);
}
}
@ -1206,7 +1326,7 @@ st_scroll_view_set_mouse_scrolling (StScrollView *scroll,
g_return_if_fail (ST_IS_SCROLL_VIEW (scroll));
priv = ST_SCROLL_VIEW (scroll)->priv;
priv = st_scroll_view_get_instance_private (scroll);
if (priv->mouse_scroll != enabled)
{
@ -1235,7 +1355,7 @@ st_scroll_view_get_mouse_scrolling (StScrollView *scroll)
g_return_val_if_fail (ST_IS_SCROLL_VIEW (scroll), FALSE);
priv = ST_SCROLL_VIEW (scroll)->priv;
priv = st_scroll_view_get_instance_private (scroll);
return priv->mouse_scroll;
}
@ -1255,7 +1375,7 @@ st_scroll_view_set_overlay_scrollbars (StScrollView *scroll,
g_return_if_fail (ST_IS_SCROLL_VIEW (scroll));
priv = ST_SCROLL_VIEW (scroll)->priv;
priv = st_scroll_view_get_instance_private (scroll);
if (priv->overlay_scrollbars != enabled)
{
@ -1281,7 +1401,7 @@ st_scroll_view_get_overlay_scrollbars (StScrollView *scroll)
g_return_val_if_fail (ST_IS_SCROLL_VIEW (scroll), FALSE);
priv = ST_SCROLL_VIEW (scroll)->priv;
priv = st_scroll_view_get_instance_private (scroll);
return priv->overlay_scrollbars;
}
@ -1303,7 +1423,7 @@ st_scroll_view_set_policy (StScrollView *scroll,
g_return_if_fail (ST_IS_SCROLL_VIEW (scroll));
priv = ST_SCROLL_VIEW (scroll)->priv;
priv = st_scroll_view_get_instance_private (scroll);
if (priv->hscrollbar_policy == hscroll && priv->vscrollbar_policy == vscroll)
return;

View File

@ -24,15 +24,20 @@
#error "Only <st/st.h> can be included directly.h"
#endif
#ifndef __ST_SCROLL_VIEW_H__
#define __ST_SCROLL_VIEW_H__
#pragma once
#include <st/st-bin.h>
#include <st/st-widget.h>
#include <st/st-scrollable.h>
G_BEGIN_DECLS
#define ST_TYPE_SCROLL_VIEW (st_scroll_view_get_type())
G_DECLARE_FINAL_TYPE (StScrollView, st_scroll_view, ST, SCROLL_VIEW, StBin)
G_DECLARE_DERIVABLE_TYPE (StScrollView, st_scroll_view, ST, SCROLL_VIEW, StWidget)
struct _StScrollViewClass
{
StWidgetClass parent_class;
};
typedef enum
{
@ -42,24 +47,12 @@ typedef enum
ST_POLICY_EXTERNAL,
} StPolicyType;
typedef struct _StScrollViewPrivate StScrollViewPrivate;
/**
* StScrollView:
*
* The contents of this structure are private and should only be accessed
* through the public API.
*/
struct _StScrollView
{
/*< private >*/
StBin parent_instance;
StScrollViewPrivate *priv;
};
StWidget *st_scroll_view_new (void);
StScrollable *st_scroll_view_get_child (StScrollView *scroll);
void st_scroll_view_set_child (StScrollView *scroll,
StScrollable *child);
ClutterActor *st_scroll_view_get_hscroll_bar (StScrollView *scroll);
ClutterActor *st_scroll_view_get_vscroll_bar (StScrollView *scroll);
@ -86,5 +79,3 @@ void st_scroll_view_update_fade_effect (StScrollView *scroll,
ClutterMargin *fade_margins);
G_END_DECLS
#endif /* __ST_SCROLL_VIEW_H__ */