[evolution/gnome-3-18] EAttachment/Store not freed in the message preview panel



commit 14db27f08e8d3135a51162f5e93b559a2e17bb47
Author: Milan Crha <mcrha redhat com>
Date:   Fri Nov 20 09:07:31 2015 +0100

    EAttachment/Store not freed in the message preview panel
    
    The main issue was that the e_attachment_store_remove_all() removed
    the content of the tree model, but then left the attachment index
    untouched, while the attachments contain GtkTreeRowReference-s, which
    reference the model, thus there is a circular dependency involved.
    The rest of the changes is related.

 e-util/e-attachment-button.c |    6 ++++--
 e-util/e-attachment-store.c  |   13 +++++++++----
 e-util/e-attachment.c        |    6 +++---
 mail/e-mail-display.c        |   26 +++++++++++++++++++++++++-
 4 files changed, 41 insertions(+), 10 deletions(-)
---
diff --git a/e-util/e-attachment-button.c b/e-util/e-attachment-button.c
index 4d8af48..090b619 100644
--- a/e-util/e-attachment-button.c
+++ b/e-util/e-attachment-button.c
@@ -205,8 +205,10 @@ attachment_button_update_cell_view (EAttachmentButton *button)
        path = gtk_tree_row_reference_get_path (reference);
 
 exit:
+
        gtk_cell_view_set_model (cell_view, model);
-       gtk_cell_view_set_displayed_row (cell_view, path);
+       if (model)
+               gtk_cell_view_set_displayed_row (cell_view, path);
 
        if (path != NULL)
                gtk_tree_path_free (path);
@@ -803,7 +805,7 @@ e_attachment_button_set_attachment (EAttachmentButton *button,
                        G_BINDING_SYNC_CREATE);
                button->priv->shown_binding = binding;
 
-               handler_id = e_signal_connect_notify_swapped (
+               handler_id = g_signal_connect_swapped (
                        attachment, "notify::reference",
                        G_CALLBACK (attachment_button_update_cell_view),
                        button);
diff --git a/e-util/e-attachment-store.c b/e-util/e-attachment-store.c
index 027eee6..f0648db 100644
--- a/e-util/e-attachment-store.c
+++ b/e-util/e-attachment-store.c
@@ -287,6 +287,12 @@ e_attachment_store_remove_all (EAttachmentStore *store)
        if (!g_hash_table_size (store->priv->attachment_index))
                return;
 
+       g_object_freeze_notify (G_OBJECT (store));
+
+       /* Get the list of attachments before clearing the list store,
+          otherwise there would be returned no attachments. */
+       list = e_attachment_store_get_attachments (store);
+
        /* Clear the list store before cancelling EAttachment load/save
         * operations.  This will invalidate the EAttachment's tree row
         * reference so it won't try to update the row's icon column in
@@ -294,14 +300,13 @@ e_attachment_store_remove_all (EAttachmentStore *store)
         * the list store is being disposed. */
        gtk_list_store_clear (GTK_LIST_STORE (store));
 
-       g_object_freeze_notify (G_OBJECT (store));
-
-       list = e_attachment_store_get_attachments (store);
        for (iter = list; iter; iter = iter->next) {
                EAttachment *attachment = iter->data;
 
                e_attachment_cancel (attachment);
-               g_hash_table_remove (store->priv->attachment_index, iter->data);
+               e_attachment_set_reference (attachment, NULL);
+
+               g_warn_if_fail (g_hash_table_remove (store->priv->attachment_index, attachment));
        }
 
        g_list_foreach (list, (GFunc) g_object_unref, NULL);
diff --git a/e-util/e-attachment.c b/e-util/e-attachment.c
index 31014c5..ebe77af 100644
--- a/e-util/e-attachment.c
+++ b/e-util/e-attachment.c
@@ -1136,15 +1136,15 @@ e_attachment_init (EAttachment *attachment)
                attachment, "notify::percent",
                G_CALLBACK (attachment_update_progress_columns), NULL);
 
-       e_signal_connect_notify (
+       g_signal_connect (
                attachment, "notify::reference",
                G_CALLBACK (attachment_update_file_info_columns), NULL);
 
-       e_signal_connect_notify (
+       g_signal_connect (
                attachment, "notify::reference",
                G_CALLBACK (attachment_update_icon_column), NULL);
 
-       e_signal_connect_notify (
+       g_signal_connect (
                attachment, "notify::reference",
                G_CALLBACK (attachment_update_progress_columns), NULL);
 
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
index 9b4b628..4b1bd6f 100644
--- a/mail/e-mail-display.c
+++ b/mail/e-mail-display.c
@@ -678,6 +678,24 @@ mail_display_attachment_count_changed (EAttachmentStore *store,
        }
 }
 
+typedef struct _NumAttachmentsData {
+       EAttachmentStore *store;
+       gulong handler_id;
+} NumAttachmentsData;
+
+static void
+attachment_bar_box_gone_cb (gpointer data,
+                           GObject *gone_box)
+{
+       NumAttachmentsData *nad = data;
+
+       if (nad) {
+               g_signal_handler_disconnect (nad->store, nad->handler_id);
+               g_object_unref (nad->store);
+               g_free (nad);
+       }
+}
+
 static GtkWidget *
 mail_display_plugin_widget_requested (WebKitWebView *web_view,
                                       gchar *mime_type,
@@ -794,6 +812,7 @@ mail_display_plugin_widget_requested (WebKitWebView *web_view,
        if (E_IS_ATTACHMENT_BAR (widget)) {
                GtkWidget *box = NULL;
                EAttachmentStore *store;
+               NumAttachmentsData *nad;
 
                /* Only when packed in box (grid does not work),
                 * EAttachmentBar reports correct height */
@@ -813,11 +832,16 @@ mail_display_plugin_widget_requested (WebKitWebView *web_view,
 
                /* Always hide an attachment bar without attachments */
                store = e_attachment_bar_get_store (E_ATTACHMENT_BAR (widget));
-               g_signal_connect (
+
+               nad = g_new0 (NumAttachmentsData, 1);
+               nad->store = g_object_ref (store);
+               nad->handler_id = g_signal_connect (
                        store, "notify::num-attachments",
                        G_CALLBACK (mail_display_attachment_count_changed),
                        box);
 
+               g_object_weak_ref (G_OBJECT (box), attachment_bar_box_gone_cb, nad);
+
                gtk_widget_show (widget);
                gtk_widget_show (box);
 


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