From 6423cbfc92ac4c59e250a08d63226df38df04d96 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Fri, 26 Feb 2010 12:48:07 -0500 Subject: [PATCH] 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 --- src/st/st-scroll-bar.c | 21 ++++++++++++------ src/st/st-scroll-view.c | 47 +++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/st/st-scroll-bar.c b/src/st/st-scroll-bar.c index 836681c95..2698397d4 100644 --- a/src/st/st-scroll-bar.c +++ b/src/st/st-scroll-bar.c @@ -188,14 +188,23 @@ st_scroll_bar_dispose (GObject *gobject) priv->handle = NULL; } - clutter_actor_unparent (priv->bw_stepper); - priv->bw_stepper = NULL; + if (priv->bw_stepper) + { + clutter_actor_unparent (priv->bw_stepper); + priv->bw_stepper = NULL; + } - clutter_actor_unparent (priv->fw_stepper); - priv->fw_stepper = NULL; + if (priv->fw_stepper) + { + clutter_actor_unparent (priv->fw_stepper); + priv->fw_stepper = NULL; + } - clutter_actor_unparent (priv->trough); - priv->trough = NULL; + if (priv->trough) + { + clutter_actor_unparent (priv->trough); + priv->trough = NULL; + } G_OBJECT_CLASS (st_scroll_bar_parent_class)->dispose (gobject); } diff --git a/src/st/st-scroll-view.c b/src/st/st-scroll-view.c index 7fef4a023..51263fd82 100644 --- a/src/st/st-scroll-view.c +++ b/src/st/st-scroll-view.c @@ -215,34 +215,29 @@ st_scroll_view_dispose (GObject *object) { StScrollViewPrivate *priv = ST_SCROLL_VIEW (object)->priv; - priv->child = NULL; - if (priv->vscroll) - { - clutter_actor_destroy (priv->vscroll); - priv->vscroll = NULL; - } + clutter_actor_destroy (priv->vscroll); 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); - priv->hscroll = NULL; + clutter_actor_unparent (priv->top_shadow); + 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); } -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 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->set_property = st_scroll_view_set_property; - object_class->dispose= st_scroll_view_dispose; - object_class->finalize = st_scroll_view_finalize; + object_class->dispose = st_scroll_view_dispose; actor_class->paint = st_scroll_view_paint; actor_class->pick = st_scroll_view_pick; @@ -833,6 +827,17 @@ st_scroll_view_remove (ClutterContainer *container, 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_unparent (actor); + } } static void