[gnome-terminal] window: Use weak refs while waiting for clipboard info



commit 9f2ba3d5b642973a21e7916fe1a60a5c44126720
Author: Christian Persch <chpe gnome org>
Date:   Sun Aug 11 14:51:01 2013 +0200

    window: Use weak refs while waiting for clipboard info
    
    https://retrace.fedoraproject.org/faf/problems/1137333/
    https://retrace.fedoraproject.org/faf/problems/1003772/
    https://bugzilla.redhat.com/show_bug.cgi?id=977010

 src/terminal-screen.c |   18 +++++++++++++++++-
 src/terminal-screen.h |    4 +++-
 src/terminal-window.c |   38 +++++++++++++++++++++++++++-----------
 3 files changed, 47 insertions(+), 13 deletions(-)
---
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index 78e146f..948b822 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -1368,7 +1368,8 @@ terminal_screen_popup_info_new (TerminalScreen *screen)
   info = g_slice_new0 (TerminalScreenPopupInfo);
   info->ref_count = 1;
   info->screen = g_object_ref (screen);
-  info->window = terminal_screen_get_window (screen);
+
+  g_weak_ref_init (&info->window_weak_ref, terminal_screen_get_window (screen));
 
   return info;
 }
@@ -1391,10 +1392,25 @@ terminal_screen_popup_info_unref (TerminalScreenPopupInfo *info)
     return;
 
   g_object_unref (info->screen);
+  g_weak_ref_clear (&info->window_weak_ref);
   g_free (info->string);
   g_slice_free (TerminalScreenPopupInfo, info);
 }
 
+/**
+ * terminal_screen_popup_info_ref_window:
+ * @info: a #TerminalScreenPopupInfo
+ *
+ * Returns: the window, or %NULL
+ */
+TerminalWindow *
+terminal_screen_popup_info_ref_window (TerminalScreenPopupInfo *info)
+{
+  g_return_val_if_fail (info != NULL, NULL);
+
+  return g_weak_ref_get (&info->window_weak_ref);
+}
+
 static gboolean
 terminal_screen_popup_menu (GtkWidget *widget)
 {
diff --git a/src/terminal-screen.h b/src/terminal-screen.h
index eb4ea72..baa231a 100644
--- a/src/terminal-screen.h
+++ b/src/terminal-screen.h
@@ -146,7 +146,7 @@ gboolean terminal_screen_has_foreground_process (TerminalScreen *screen);
 
 struct _TerminalScreenPopupInfo {
   int ref_count;
-  TerminalWindow *window;
+  GWeakRef window_weak_ref;
   TerminalScreen *screen;
   char *string;
   TerminalURLFlavour flavour;
@@ -159,6 +159,8 @@ TerminalScreenPopupInfo *terminal_screen_popup_info_ref (TerminalScreenPopupInfo
 
 void terminal_screen_popup_info_unref (TerminalScreenPopupInfo *info);
 
+TerminalWindow *terminal_screen_popup_info_ref_window (TerminalScreenPopupInfo *info);
+
 G_END_DECLS
 
 #endif /* TERMINAL_SCREEN_H */
diff --git a/src/terminal-window.c b/src/terminal-window.c
index dfc153b..1eab509 100644
--- a/src/terminal-window.c
+++ b/src/terminal-window.c
@@ -1715,12 +1715,20 @@ static void
 update_edit_menu_cb (GtkClipboard *clipboard,
                      GdkAtom *targets,
                      int n_targets,
-                     TerminalWindow *window)
+                     GWeakRef *ref)
 {
-  TerminalWindowPrivate *priv = window->priv;
+  TerminalWindow *window;
+  TerminalWindowPrivate *priv;
   GtkAction *action;
   gboolean can_paste, can_paste_uris;
 
+  window = g_weak_ref_get (ref);
+  if (window == NULL)
+    goto out;
+
+  /* Now we know the window is still alive */
+  priv = window->priv;
+
   can_paste = targets != NULL && gtk_targets_include_text (targets, n_targets);
   can_paste_uris = targets != NULL && gtk_targets_include_uri (targets, n_targets);
 
@@ -1730,8 +1738,9 @@ update_edit_menu_cb (GtkClipboard *clipboard,
   gtk_action_set_visible (action, can_paste_uris);
   gtk_action_set_sensitive (action, can_paste_uris);
 
-  /* Ref was added in gtk_clipboard_request_targets below */
   g_object_unref (window);
+ out:
+  g_slice_free (GWeakRef, ref);
 }
 
 static void
@@ -1739,9 +1748,13 @@ update_edit_menu (GtkClipboard *clipboard,
                   GdkEvent *event G_GNUC_UNUSED,
                   TerminalWindow *window)
 {
+  GWeakRef *ref;
+
+  ref = g_slice_new0 (GWeakRef);
+  g_weak_ref_init (ref, window);
   gtk_clipboard_request_targets (clipboard,
                                  (GtkClipboardTargetsReceivedFunc) update_edit_menu_cb,
-                                 g_object_ref (window));
+                                 ref);
 }
 
 static void
@@ -1964,22 +1977,25 @@ popup_clipboard_targets_received_cb (GtkClipboard *clipboard,
                                      int n_targets,
                                      TerminalScreenPopupInfo *info)
 {
-  TerminalWindow *window = info->window;
-  TerminalWindowPrivate *priv = window->priv;
+  TerminalWindow *window;
+  TerminalWindowPrivate *priv;
   TerminalScreen *screen = info->screen;
   GtkWidget *popup_menu;
   GtkAction *action;
   gboolean can_paste, can_paste_uris, show_link, show_email_link, show_call_link;
 
-  if (!gtk_widget_get_realized (GTK_WIDGET (screen)))
+  window = terminal_screen_popup_info_ref_window (info);
+  if (window == NULL ||
+      !gtk_widget_get_realized (GTK_WIDGET (screen)))
     {
       terminal_screen_popup_info_unref (info);
       return;
     }
 
-  /* Now we know that the screen is realized, we know that the window is still alive */
-  remove_popup_info (window);
+  /* Now we know that the window is still alive */
+  priv = window->priv;
 
+  remove_popup_info (window);
   priv->popup_info = info; /* adopt the ref added when requesting the clipboard */
 
   can_paste = targets != NULL && gtk_targets_include_text (targets, n_targets);
@@ -2024,6 +2040,8 @@ popup_clipboard_targets_received_cb (GtkClipboard *clipboard,
                   NULL, NULL, 
                   info->button,
                   info->timestamp);
+
+  g_object_unref (window);
 }
 
 static void
@@ -2033,8 +2051,6 @@ screen_show_popup_menu_callback (TerminalScreen *screen,
 {
   GtkClipboard *clipboard;
 
-  g_return_if_fail (info->window == window);
-
   clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_CLIPBOARD);
   gtk_clipboard_request_targets (clipboard,
                                   (GtkClipboardTargetsReceivedFunc) popup_clipboard_targets_received_cb,


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