Fix problems on destruction

StScrollBar: Be robust against being disposed multiple times,
  which can happen, and in fact, normally happens when destroying
  the parent.

StScrollView: Implement remove() for the hscroll and vscroll members,
  and just destroy them in dispose() and let them be removed.
  unparent the shadows, instead of just unref'ing them directly.

https://bugzilla.gnome.org/show_bug.cgi?id=611203
This commit is contained in:
Owen W. Taylor 2010-02-26 12:48:07 -05:00
parent ed3e287d91
commit 6423cbfc92
2 changed files with 41 additions and 27 deletions

View File

@ -188,14 +188,23 @@ st_scroll_bar_dispose (GObject *gobject)
priv->handle = NULL; priv->handle = NULL;
} }
clutter_actor_unparent (priv->bw_stepper); if (priv->bw_stepper)
priv->bw_stepper = NULL; {
clutter_actor_unparent (priv->bw_stepper);
priv->bw_stepper = NULL;
}
clutter_actor_unparent (priv->fw_stepper); if (priv->fw_stepper)
priv->fw_stepper = NULL; {
clutter_actor_unparent (priv->fw_stepper);
priv->fw_stepper = NULL;
}
clutter_actor_unparent (priv->trough); if (priv->trough)
priv->trough = NULL; {
clutter_actor_unparent (priv->trough);
priv->trough = NULL;
}
G_OBJECT_CLASS (st_scroll_bar_parent_class)->dispose (gobject); G_OBJECT_CLASS (st_scroll_bar_parent_class)->dispose (gobject);
} }

View File

@ -215,34 +215,29 @@ st_scroll_view_dispose (GObject *object)
{ {
StScrollViewPrivate *priv = ST_SCROLL_VIEW (object)->priv; StScrollViewPrivate *priv = ST_SCROLL_VIEW (object)->priv;
priv->child = NULL;
if (priv->vscroll) if (priv->vscroll)
{ clutter_actor_destroy (priv->vscroll);
clutter_actor_destroy (priv->vscroll);
priv->vscroll = NULL;
}
if (priv->hscroll) if (priv->hscroll)
clutter_actor_destroy (priv->hscroll);
/* since it's impossible to get a handle to these actors, we can
* just directly unparent them and not go through destroy/remove */
if (priv->top_shadow)
{ {
clutter_actor_destroy (priv->hscroll); clutter_actor_unparent (priv->top_shadow);
priv->hscroll = NULL; priv->top_shadow = NULL;
}
if (priv->bottom_shadow)
{
clutter_actor_unparent (priv->bottom_shadow);
priv->bottom_shadow = NULL;
} }
G_OBJECT_CLASS (st_scroll_view_parent_class)->dispose (object); G_OBJECT_CLASS (st_scroll_view_parent_class)->dispose (object);
} }
static void
st_scroll_view_finalize (GObject *object)
{
StScrollViewPrivate *priv = ST_SCROLL_VIEW (object)->priv;
g_object_unref (priv->top_shadow);
g_object_unref (priv->bottom_shadow);
G_OBJECT_CLASS (st_scroll_view_parent_class)->finalize (object);
}
static void static void
st_scroll_view_paint (ClutterActor *actor) st_scroll_view_paint (ClutterActor *actor)
{ {
@ -573,8 +568,7 @@ st_scroll_view_class_init (StScrollViewClass *klass)
object_class->get_property = st_scroll_view_get_property; object_class->get_property = st_scroll_view_get_property;
object_class->set_property = st_scroll_view_set_property; object_class->set_property = st_scroll_view_set_property;
object_class->dispose= st_scroll_view_dispose; object_class->dispose = st_scroll_view_dispose;
object_class->finalize = st_scroll_view_finalize;
actor_class->paint = st_scroll_view_paint; actor_class->paint = st_scroll_view_paint;
actor_class->pick = st_scroll_view_pick; actor_class->pick = st_scroll_view_pick;
@ -833,6 +827,17 @@ st_scroll_view_remove (ClutterContainer *container,
g_object_unref (priv->child); g_object_unref (priv->child);
priv->child = NULL; 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_unparent (actor);
}
} }
static void static void