[evolution/gnome-3-16] Bug 748878 - Crash in ect_dispose() on quit



commit a0eb59a402b2a70f860324906e0a0da1a200ec72
Author: Milan Crha <mcrha redhat com>
Date:   Thu May 7 17:02:55 2015 +0200

    Bug 748878 - Crash in ect_dispose() on quit

 e-util/e-table-click-to-add.c  |    9 +++++++
 e-util/gal-a11y-e-cell-text.c  |   41 ++++++++++++++++++---------------
 e-util/gal-a11y-e-table-item.c |   48 +++++++++++++++++++++------------------
 3 files changed, 57 insertions(+), 41 deletions(-)
---
diff --git a/e-util/e-table-click-to-add.c b/e-util/e-table-click-to-add.c
index 6dc8138..ddea91b 100644
--- a/e-util/e-table-click-to-add.c
+++ b/e-util/e-table-click-to-add.c
@@ -397,6 +397,15 @@ finish_editing (ETableClickToAdd *etcta)
                g_object_run_dispose (G_OBJECT (etcta->row));
                etcta->row = NULL;
 
+               if (etcta->text) {
+                       g_object_run_dispose (G_OBJECT (etcta->text));
+                       etcta->text = NULL;
+               }
+               if (etcta->rect) {
+                       g_object_run_dispose (G_OBJECT (etcta->rect));
+                       etcta->rect = NULL;
+               }
+
                one = e_table_one_new (etcta->model);
                etcta_add_one (etcta, one);
                g_object_unref (one);
diff --git a/e-util/gal-a11y-e-cell-text.c b/e-util/gal-a11y-e-cell-text.c
index 39be8e0..db65078 100644
--- a/e-util/gal-a11y-e-cell-text.c
+++ b/e-util/gal-a11y-e-cell-text.c
@@ -35,16 +35,26 @@
 static AtkObjectClass *parent_class;
 #define PARENT_TYPE (gal_a11y_e_cell_get_type ())
 
+#define GAL_A11Y_E_CELL_TEXT_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), GAL_A11Y_TYPE_E_CELL_TEXT, GalA11yECellTextPrivate))
+
+struct _GalA11yECellTextPrivate {
+       ECell *cell;
+};
+
 /* Static functions */
 static void
 ect_dispose (GObject *object)
 {
        GObjectClass *g_class;
-       GalA11yECell *gaec = GAL_A11Y_E_CELL (object);
        GalA11yECellText *gaet = GAL_A11Y_E_CELL_TEXT (object);
+       GalA11yECellTextPrivate *priv;
+
+       priv = GAL_A11Y_E_CELL_TEXT_GET_PRIVATE (object);
 
-       if (gaet->inserted_id != 0) {
-               ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
+       if (gaet->inserted_id != 0 && priv->cell) {
+               ECellText *ect = E_CELL_TEXT (priv->cell);
 
                if (ect) {
                        g_signal_handler_disconnect (ect, gaet->inserted_id);
@@ -55,6 +65,8 @@ ect_dispose (GObject *object)
                gaet->deleted_id = 0;
        }
 
+       g_clear_object (&priv->cell);
+
        g_class = (GObjectClass *)parent_class;
        if (g_class->dispose)
                g_class->dispose (object);
@@ -600,6 +612,8 @@ ect_class_init (GalA11yECellTextClass *klass)
        AtkObjectClass *a11y      = ATK_OBJECT_CLASS (klass);
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+       g_type_class_add_private (klass, sizeof (GalA11yECellTextPrivate));
+
        parent_class              = g_type_class_ref (PARENT_TYPE);
        a11y->get_name            = ect_get_name;
        object_class->dispose     = ect_dispose;
@@ -668,14 +682,6 @@ gal_a11y_e_cell_text_get_type (void)
        return type;
 }
 
-static void
-cell_text_destroyed (gpointer data)
-{
-       g_return_if_fail (GAL_A11Y_IS_E_CELL_TEXT (data));
-
-       g_object_unref (data);
-}
-
 AtkObject *
 gal_a11y_e_cell_text_new (ETableItem *item,
                          ECellView  *cell_view,
@@ -687,6 +693,7 @@ gal_a11y_e_cell_text_new (ETableItem *item,
        AtkObject *a11y;
        GalA11yECell *gaec;
        GalA11yECellText *gaet;
+       GalA11yECellTextPrivate *priv;
        ECellText *ect;
 
        a11y = g_object_new (gal_a11y_e_cell_text_get_type (), NULL);
@@ -700,18 +707,14 @@ gal_a11y_e_cell_text_new (ETableItem *item,
                                   row);
        gaet = GAL_A11Y_E_CELL_TEXT (a11y);
 
-       /* will be unrefed in cell_text_destroyed */
-       g_object_ref (a11y);
+       priv = GAL_A11Y_E_CELL_TEXT_GET_PRIVATE (a11y);
+       priv->cell = g_object_ref (((ECellView *) cell_view)->ecell);
 
-       gaet->inserted_id = g_signal_connect (E_CELL_TEXT (((ECellView *)cell_view)->ecell),
+       gaet->inserted_id = g_signal_connect (E_CELL_TEXT (priv->cell),
                                                "text_inserted", G_CALLBACK (ect_text_inserted_cb), a11y);
-       gaet->deleted_id = g_signal_connect (E_CELL_TEXT (((ECellView *)cell_view)->ecell),
+       gaet->deleted_id = g_signal_connect (E_CELL_TEXT (priv->cell),
                                             "text_deleted", G_CALLBACK (ect_text_deleted_cb), a11y);
 
-       g_object_weak_ref (G_OBJECT (((ECellView *)cell_view)->ecell),
-                          (GWeakNotify) cell_text_destroyed,
-                          a11y);
-
        ect_action_init (gaet);
 
        ect = E_CELL_TEXT (cell_view->ecell);
diff --git a/e-util/gal-a11y-e-table-item.c b/e-util/gal-a11y-e-table-item.c
index a2ff9d5..49ccdb3 100644
--- a/e-util/gal-a11y-e-table-item.c
+++ b/e-util/gal-a11y-e-table-item.c
@@ -86,17 +86,39 @@ free_columns (ETableCol **columns)
 }
 
 static void
+table_item_cell_gone_cb (gpointer user_data,
+                        GObject *gone_cell)
+{
+       GalA11yETableItem *a11y;
+       GObject *old_cell;
+
+       a11y = GAL_A11Y_E_TABLE_ITEM (user_data);
+
+       old_cell = g_object_get_data (G_OBJECT (a11y), "gail-focus-object");
+       if (old_cell == gone_cell)
+               g_object_set_data (G_OBJECT (a11y), "gail-focus-object", NULL);
+}
+
+static void
 item_finalized (gpointer user_data,
                 GObject *gone_item)
 {
        GalA11yETableItem *a11y;
        GalA11yETableItemPrivate *priv;
+       GObject *old_cell;
 
        a11y = GAL_A11Y_E_TABLE_ITEM (user_data);
        priv = GET_PRIVATE (a11y);
 
        priv->item = NULL;
 
+       old_cell = g_object_get_data (G_OBJECT (a11y), "gail-focus-object");
+       if (old_cell) {
+               g_object_weak_unref (G_OBJECT (old_cell), table_item_cell_gone_cb, a11y);
+               g_object_unref (old_cell);
+       }
+       g_object_set_data (G_OBJECT (a11y), "gail-focus-object", NULL);
+
        atk_state_set_add_state (priv->state_set, ATK_STATE_DEFUNCT);
        atk_object_notify_state_change (ATK_OBJECT (a11y), ATK_STATE_DEFUNCT, TRUE);
 
@@ -211,8 +233,10 @@ eti_a11y_reset_focus_object (GalA11yETableItem *a11y,
        if (old_cell && GAL_A11Y_IS_E_CELL (old_cell))
                gal_a11y_e_cell_remove_state (
                        GAL_A11Y_E_CELL (old_cell), ATK_STATE_FOCUSED, FALSE);
-       if (old_cell)
+       if (old_cell) {
+               g_object_weak_unref (G_OBJECT (old_cell), table_item_cell_gone_cb, a11y);
                g_object_unref (old_cell);
+       }
 
        cell = eti_ref_at (ATK_TABLE (a11y), view_row, view_col);
 
@@ -220,6 +244,7 @@ eti_a11y_reset_focus_object (GalA11yETableItem *a11y,
                g_object_set_data (G_OBJECT (a11y), "gail-focus-object", cell);
                gal_a11y_e_cell_add_state (
                        GAL_A11Y_E_CELL (cell), ATK_STATE_FOCUSED, FALSE);
+               g_object_weak_ref (G_OBJECT (cell), table_item_cell_gone_cb, a11y);
        } else
                g_object_set_data (G_OBJECT (a11y), "gail-focus-object", NULL);
 
@@ -361,23 +386,6 @@ eti_ref_accessible_at_point (AtkComponent *component,
        }
 }
 
-static void
-cell_destroyed (gpointer data)
-{
-       GalA11yECell * cell;
-
-       g_return_if_fail (GAL_A11Y_IS_E_CELL (data));
-       cell = GAL_A11Y_E_CELL (data);
-
-       g_return_if_fail (cell->item && G_IS_OBJECT (cell->item));
-
-       if (cell->item) {
-               g_object_unref (cell->item);
-               cell->item = NULL;
-       }
-
-}
-
 /* atk table */
 static AtkObject *
 eti_ref_at (AtkTable *table,
@@ -411,10 +419,6 @@ eti_ref_at (AtkTable *table,
                        column,
                        row);
                if (ATK_IS_OBJECT (ret)) {
-                       g_object_weak_ref (
-                               G_OBJECT (ret),
-                               (GWeakNotify) cell_destroyed,
-                               ret);
                        /* if current cell is focused, add FOCUSED state */
                        if (e_selection_model_cursor_row (item->selection) ==
                                GAL_A11Y_E_CELL (ret)->row &&


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]