[gnome-shell] StWidget: carefully clear ->accessible pointer to avoid resurrection
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] StWidget: carefully clear ->accessible pointer to avoid resurrection
- Date: Mon, 13 Oct 2014 16:46:51 +0000 (UTC)
commit 5e5035a0f70e75e54d74dee346f877a65f2713d3
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Wed Oct 8 07:54:09 2014 -0400
StWidget: carefully clear ->accessible pointer to avoid resurrection
The pointer to ->accessible was cleared too early in dispose, which
resulted in another accessible object being created when the actor
was removed from its parent in clutter_actor_dispose(). Use a
weak reference instead to clear the ->accessible pointer.
https://bugzilla.gnome.org/show_bug.cgi?id=738147
src/st/st-widget.c | 32 ++++++++++++++++++++++++--------
1 files changed, 24 insertions(+), 8 deletions(-)
---
diff --git a/src/st/st-widget.c b/src/st/st-widget.c
index 6353e48..5788d54 100644
--- a/src/st/st-widget.c
+++ b/src/st/st-widget.c
@@ -332,12 +332,6 @@ st_widget_dispose (GObject *gobject)
st_widget_remove_transition (actor);
- /* The real dispose of this accessible is done on
- * AtkGObjectAccessible weak ref callback
- */
- if (priv->accessible)
- priv->accessible = NULL;
-
g_clear_pointer (&priv->label_actor, g_object_unref);
if (priv->texture_file_changed_id != 0)
@@ -2495,6 +2489,17 @@ st_widget_get_accessible (ClutterActor *actor)
NULL);
atk_object_initialize (widget->priv->accessible, actor);
+
+ /* AtkGObjectAccessible, which StWidgetAccessible derives from, clears
+ * the back reference to the object in a weak notify for the object;
+ * weak-ref notification, which occurs during g_object_real_dispose(),
+ * is then the optimal time to clear the forward reference. We
+ * can't clear the reference in dispose() before chaining up, since
+ * clutter_actor_dispose() causes notifications to be sent out, which
+ * will result in a new accessible object being created.
+ */
+ g_object_add_weak_pointer (G_OBJECT (actor),
+ (gpointer *)&widget->priv->accessible);
}
return widget->priv->accessible;
@@ -2524,14 +2529,25 @@ st_widget_set_accessible (StWidget *widget,
AtkObject *accessible)
{
g_return_if_fail (ST_IS_WIDGET (widget));
+ g_return_if_fail (accessible == NULL || ATK_IS_GOBJECT_ACCESSIBLE (accessible));
if (widget->priv->accessible != accessible)
{
if (widget->priv->accessible)
- g_object_unref (widget->priv->accessible);
+ {
+ g_object_remove_weak_pointer (G_OBJECT (widget),
+ (gpointer *)&widget->priv->accessible);
+ g_object_unref (widget->priv->accessible);
+ widget->priv->accessible = NULL;
+ }
if (accessible)
- widget->priv->accessible = g_object_ref (accessible);
+ {
+ widget->priv->accessible = g_object_ref (accessible);
+ /* See note in st_widget_get_accessible() */
+ g_object_add_weak_pointer (G_OBJECT (widget),
+ (gpointer *)&widget->priv->accessible);
+ }
else
widget->priv->accessible = NULL;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]