[evolution] Bug 793125 - Crash due to popup menus left attached too long



commit 2bfd906d260dbd3fe7a66908481aaa4ee21bb68a
Author: Milan Crha <mcrha redhat com>
Date:   Tue Feb 13 14:34:18 2018 +0100

    Bug 793125 - Crash due to popup menus left attached too long

 src/calendar/gui/e-to-do-pane.c               |   22 +---------------------
 src/e-util/e-attachment-view.c                |   16 +++++++++++++++-
 src/e-util/e-calendar-item.c                  |   18 +-----------------
 src/e-util/e-html-editor.c                    |   17 ++++++++++++++++-
 src/e-util/e-table-header-item.c              |    3 ++-
 src/e-util/e-text.c                           |    9 ++-------
 src/e-util/e-web-view.c                       |   23 +++++++++++++++++++----
 src/mail/e-mail-reader.c                      |   17 ++++++++++++++++-
 src/mail/em-subscription-editor.c             |    2 ++
 src/modules/calendar/e-calendar-preferences.c |    1 +
 src/shell/e-shell-view.c                      |   15 ++++++++++++++-
 11 files changed, 89 insertions(+), 54 deletions(-)
---
diff --git a/src/calendar/gui/e-to-do-pane.c b/src/calendar/gui/e-to-do-pane.c
index d45e9a9..ad432f1 100644
--- a/src/calendar/gui/e-to-do-pane.c
+++ b/src/calendar/gui/e-to-do-pane.c
@@ -2103,24 +2103,6 @@ etdp_fill_popup_menu (EToDoPane *to_do_pane,
        gtk_menu_shell_append (menu_shell, item);
 }
 
-static gboolean
-etdp_destroy_menu_idle_cb (gpointer user_data)
-{
-       GtkWidget *widget = user_data;
-
-       g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
-
-       gtk_widget_destroy (widget);
-
-       return FALSE;
-}
-
-static void
-etdp_menu_deactivate_cb (GtkWidget *widget)
-{
-       g_idle_add (etdp_destroy_menu_idle_cb, widget);
-}
-
 static void
 etdp_popup_menu (EToDoPane *to_do_pane,
                 GdkEvent *event)
@@ -2129,12 +2111,10 @@ etdp_popup_menu (EToDoPane *to_do_pane,
 
        menu = GTK_MENU (gtk_menu_new ());
 
-       g_signal_connect (menu, "deactivate",
-               G_CALLBACK (etdp_menu_deactivate_cb), NULL);
-
        etdp_fill_popup_menu (to_do_pane, menu);
 
        gtk_menu_attach_to_widget (menu, GTK_WIDGET (to_do_pane->priv->tree_view), NULL);
+       g_signal_connect (menu, "deactivate", G_CALLBACK (gtk_menu_detach), NULL);
        gtk_menu_popup_at_pointer (menu, event);
 }
 
diff --git a/src/e-util/e-attachment-view.c b/src/e-util/e-attachment-view.c
index 43f3b86..5a7df35 100644
--- a/src/e-util/e-attachment-view.c
+++ b/src/e-util/e-attachment-view.c
@@ -1845,6 +1845,16 @@ e_attachment_view_get_action_group (EAttachmentView *view,
        return e_lookup_action_group (ui_manager, group_name);
 }
 
+static void
+e_attachment_view_menu_deactivate_cb (GtkMenu *popup_menu,
+                                     gpointer user_data)
+{
+       g_return_if_fail (GTK_IS_MENU (popup_menu));
+
+       g_signal_handlers_disconnect_by_func (popup_menu, e_attachment_view_menu_deactivate_cb, user_data);
+       gtk_menu_detach (popup_menu);
+}
+
 GtkWidget *
 e_attachment_view_get_popup_menu (EAttachmentView *view)
 {
@@ -1857,10 +1867,14 @@ e_attachment_view_get_popup_menu (EAttachmentView *view)
        menu = gtk_ui_manager_get_widget (ui_manager, "/context");
        g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
 
-       if (!gtk_menu_get_attach_widget (GTK_MENU (menu)))
+       if (!gtk_menu_get_attach_widget (GTK_MENU (menu))) {
                gtk_menu_attach_to_widget (GTK_MENU (menu),
                                           GTK_WIDGET (view),
                                           NULL);
+               g_signal_connect (
+                       menu, "deactivate",
+                       G_CALLBACK (e_attachment_view_menu_deactivate_cb), NULL);
+       }
 
        return menu;
 }
diff --git a/src/e-util/e-calendar-item.c b/src/e-util/e-calendar-item.c
index 3e9692b..6708e8b 100644
--- a/src/e-util/e-calendar-item.c
+++ b/src/e-util/e-calendar-item.c
@@ -3643,22 +3643,6 @@ e_calendar_item_ensure_days_visible (ECalendarItem *calitem,
        return need_update;
 }
 
-static gboolean
-destroy_menu_idle_cb (gpointer menu)
-{
-       gtk_widget_destroy (menu);
-
-       return FALSE;
-}
-
-static void
-deactivate_menu_cb (GtkWidget *menu)
-{
-       g_signal_handlers_disconnect_by_func (menu, deactivate_menu_cb, NULL);
-
-       g_idle_add (destroy_menu_idle_cb, menu);
-}
-
 static void
 e_calendar_item_show_popup_menu (ECalendarItem *calitem,
                                  GdkEvent *button_event,
@@ -3713,7 +3697,7 @@ e_calendar_item_show_popup_menu (ECalendarItem *calitem,
 
        g_signal_connect (
                menu, "deactivate",
-               G_CALLBACK (deactivate_menu_cb), NULL);
+               G_CALLBACK (gtk_menu_detach), NULL);
 
        canvas_widget = GTK_WIDGET (calitem->canvas_item.canvas);
        gtk_menu_attach_to_widget (GTK_MENU (menu), canvas_widget, NULL);
diff --git a/src/e-util/e-html-editor.c b/src/e-util/e-html-editor.c
index 4ca2b25..9b46be6 100644
--- a/src/e-util/e-html-editor.c
+++ b/src/e-util/e-html-editor.c
@@ -507,6 +507,16 @@ context_menu_data_free (gpointer ptr)
        }
 }
 
+static void
+html_editor_menu_deactivate_cb (GtkMenu *popup_menu,
+                               gpointer user_data)
+{
+       g_return_if_fail (GTK_IS_MENU (popup_menu));
+
+       g_signal_handlers_disconnect_by_func (popup_menu, html_editor_menu_deactivate_cb, user_data);
+       gtk_menu_detach (popup_menu);
+}
+
 static gboolean
 html_editor_show_context_menu_idle_cb (gpointer user_data)
 {
@@ -523,9 +533,14 @@ html_editor_show_context_menu_idle_cb (gpointer user_data)
 
                g_signal_emit (editor, signals[UPDATE_ACTIONS], 0, cmd->flags);
 
-               if (!gtk_menu_get_attach_widget (GTK_MENU (menu)))
+               if (!gtk_menu_get_attach_widget (GTK_MENU (menu))) {
                        gtk_menu_attach_to_widget (GTK_MENU (menu), GTK_WIDGET (editor), NULL);
 
+                       g_signal_connect (
+                               menu, "deactivate",
+                               G_CALLBACK (html_editor_menu_deactivate_cb), NULL);
+               }
+
                gtk_menu_popup_at_pointer (GTK_MENU (menu), cmd->event);
 
                g_object_unref (editor);
diff --git a/src/e-util/e-table-header-item.c b/src/e-util/e-table-header-item.c
index d43f088..4d09e61 100644
--- a/src/e-util/e-table-header-item.c
+++ b/src/e-util/e-table-header-item.c
@@ -1799,7 +1799,6 @@ ethi_header_context_menu (ETableHeaderItem *ethi,
                        G_CALLBACK (sort_by_id), ethi);
        }
 
-       g_object_ref_sink (popup);
        g_signal_connect (
                popup, "selection-done",
                G_CALLBACK (free_popup_info), info);
@@ -1807,6 +1806,7 @@ ethi_header_context_menu (ETableHeaderItem *ethi,
        gtk_menu_attach_to_widget (GTK_MENU (popup),
                                   GTK_WIDGET (ethi->parent.canvas),
                                   NULL);
+       g_signal_connect (popup, "deactivate", G_CALLBACK (gtk_menu_detach), NULL);
        gtk_menu_popup_at_pointer (popup, button_event);
 }
 
@@ -2111,6 +2111,7 @@ ethi_event (GnomeCanvasItem *item,
                        gtk_menu_attach_to_widget (GTK_MENU (popup),
                                                   GTK_WIDGET (canvas),
                                                   NULL);
+                       g_signal_connect (popup, "deactivate", G_CALLBACK (gtk_menu_detach), NULL);
                        gtk_menu_popup_at_pointer (popup, event);
                } else if (event_keyval == GDK_KEY_space) {
                        ETableCol *ecol;
diff --git a/src/e-util/e-text.c b/src/e-util/e-text.c
index 1655775..2a5cf4b 100644
--- a/src/e-util/e-text.c
+++ b/src/e-util/e-text.c
@@ -2034,12 +2034,6 @@ typedef struct {
 } PopupClosure;
 
 static void
-popup_menu_detach (GtkWidget *attach_widget,
-                   GtkMenu *menu)
-{
-}
-
-static void
 popup_targets_received (GtkClipboard *clipboard,
                         GtkSelectionData *data,
                         gpointer user_data)
@@ -2060,7 +2054,8 @@ popup_targets_received (GtkClipboard *clipboard,
        gtk_menu_attach_to_widget (
                GTK_MENU (popup_menu),
                GTK_WIDGET (GNOME_CANVAS_ITEM (text)->canvas),
-               popup_menu_detach);
+               NULL);
+       g_signal_connect (popup_menu, "deactivate", G_CALLBACK (gtk_menu_detach), NULL);
 
        /* cut menu item */
        menuitem = gtk_image_menu_item_new_with_mnemonic (_("Cu_t"));
diff --git a/src/e-util/e-web-view.c b/src/e-util/e-web-view.c
index 8b1500a..af0dfd3 100644
--- a/src/e-util/e-web-view.c
+++ b/src/e-util/e-web-view.c
@@ -3272,6 +3272,16 @@ e_web_view_get_ui_manager (EWebView *web_view)
        return web_view->priv->ui_manager;
 }
 
+static void
+e_web_view_popup_menu_deactivate_cb (GtkMenu *popup_menu,
+                                    GtkWidget *web_view)
+{
+       g_return_if_fail (GTK_IS_MENU (popup_menu));
+
+       g_signal_handlers_disconnect_by_func (popup_menu, e_web_view_popup_menu_deactivate_cb, web_view);
+       gtk_menu_detach (popup_menu);
+}
+
 GtkWidget *
 e_web_view_get_popup_menu (EWebView *web_view)
 {
@@ -3284,10 +3294,15 @@ e_web_view_get_popup_menu (EWebView *web_view)
        menu = gtk_ui_manager_get_widget (ui_manager, "/context");
        g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
 
-       if (!gtk_menu_get_attach_widget (GTK_MENU (menu)))
-               gtk_menu_attach_to_widget (GTK_MENU (menu),
-                                          GTK_WIDGET (web_view),
-                                          NULL);
+       g_warn_if_fail (!gtk_menu_get_attach_widget (GTK_MENU (menu)));
+
+       gtk_menu_attach_to_widget (GTK_MENU (menu),
+                                  GTK_WIDGET (web_view),
+                                  NULL);
+
+       g_signal_connect (
+               menu, "deactivate",
+               G_CALLBACK (e_web_view_popup_menu_deactivate_cb), web_view);
 
        return menu;
 }
diff --git a/src/mail/e-mail-reader.c b/src/mail/e-mail-reader.c
index bead182..2c84230 100644
--- a/src/mail/e-mail-reader.c
+++ b/src/mail/e-mail-reader.c
@@ -4930,6 +4930,16 @@ e_mail_reader_get_message_list (EMailReader *reader)
        return iface->get_message_list (reader);
 }
 
+static void
+e_mail_reader_popup_menu_deactivate_cb (GtkMenu *popup_menu,
+                                       EMailReader *reader)
+{
+       g_return_if_fail (GTK_IS_MENU (popup_menu));
+
+       g_signal_handlers_disconnect_by_func (popup_menu, e_mail_reader_popup_menu_deactivate_cb, reader);
+       gtk_menu_detach (popup_menu);
+}
+
 GtkMenu *
 e_mail_reader_get_popup_menu (EMailReader *reader)
 {
@@ -4942,10 +4952,15 @@ e_mail_reader_get_popup_menu (EMailReader *reader)
        g_return_val_if_fail (iface->get_popup_menu != NULL, NULL);
 
        menu = iface->get_popup_menu (reader);
-       if (!gtk_menu_get_attach_widget (GTK_MENU (menu)))
+       if (!gtk_menu_get_attach_widget (GTK_MENU (menu))) {
                gtk_menu_attach_to_widget (GTK_MENU (menu),
                                           GTK_WIDGET (reader),
                                           NULL);
+               g_signal_connect (
+                       menu, "deactivate",
+                       G_CALLBACK (e_mail_reader_popup_menu_deactivate_cb), reader);
+       }
+
        return menu;
 }
 
diff --git a/src/mail/em-subscription-editor.c b/src/mail/em-subscription-editor.c
index d228626..404cb7d 100644
--- a/src/mail/em-subscription-editor.c
+++ b/src/mail/em-subscription-editor.c
@@ -833,6 +833,7 @@ subscription_editor_subscribe_popup_cb (EMSubscriptionEditor *editor)
                        editor));
 
        gtk_menu_attach_to_widget (GTK_MENU (menu), GTK_WIDGET (editor), NULL);
+       g_signal_connect (menu, "deactivate", G_CALLBACK (gtk_menu_detach), NULL);
 
        g_object_set (menu,
                      "anchor-hints", (GDK_ANCHOR_FLIP_Y |
@@ -955,6 +956,7 @@ subscription_editor_unsubscribe_popup_cb (EMSubscriptionEditor *editor)
                        editor));
 
        gtk_menu_attach_to_widget (GTK_MENU (menu), GTK_WIDGET (editor), NULL);
+       g_signal_connect (menu, "deactivate", G_CALLBACK (gtk_menu_detach), NULL);
 
        g_object_set (menu,
                      "anchor-hints", (GDK_ANCHOR_FLIP_Y |
diff --git a/src/modules/calendar/e-calendar-preferences.c b/src/modules/calendar/e-calendar-preferences.c
index f765808..3f40929 100644
--- a/src/modules/calendar/e-calendar-preferences.c
+++ b/src/modules/calendar/e-calendar-preferences.c
@@ -402,6 +402,7 @@ day_second_zone_clicked (GtkWidget *widget,
        gtk_widget_show_all (menu);
 
        gtk_menu_attach_to_widget (GTK_MENU (menu), widget, NULL);
+       g_signal_connect (menu, "deactivate", G_CALLBACK (gtk_menu_detach), NULL);
        gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
 }
 
diff --git a/src/shell/e-shell-view.c b/src/shell/e-shell-view.c
index f8b1fd4..66bcc2c 100644
--- a/src/shell/e-shell-view.c
+++ b/src/shell/e-shell-view.c
@@ -1884,6 +1884,16 @@ e_shell_view_update_actions_in_idle (EShellView *shell_view)
                        shell_view_call_update_actions_idle, shell_view);
 }
 
+static void
+e_shell_view_popup_menu_deactivate (GtkMenu *popup_menu,
+                                   gpointer user_data)
+{
+       g_return_if_fail (GTK_IS_MENU (popup_menu));
+
+       g_signal_handlers_disconnect_by_func (popup_menu, e_shell_view_popup_menu_deactivate, user_data);
+       gtk_menu_detach (popup_menu);
+}
+
 /**
  * e_shell_view_show_popup_menu:
  * @shell_view: an #EShellView
@@ -1916,11 +1926,14 @@ e_shell_view_show_popup_menu (EShellView *shell_view,
        menu = e_shell_window_get_managed_widget (shell_window, widget_path);
        g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
 
-       if (!gtk_menu_get_attach_widget (GTK_MENU (menu)))
+       if (!gtk_menu_get_attach_widget (GTK_MENU (menu))) {
                gtk_menu_attach_to_widget (GTK_MENU (menu),
                                           GTK_WIDGET (shell_window),
                                           NULL);
 
+               g_signal_connect (menu, "deactivate", G_CALLBACK (e_shell_view_popup_menu_deactivate), NULL);
+       }
+
        gtk_menu_popup_at_pointer (GTK_MENU (menu), button_event);
 
        return menu;


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