[gimp/gimp-2-10] Issue #1538 - Crash when adding file to already opened image and...



commit 75682c165054c1e66babf0370f7e2a0ac14ec60a
Author: Michael Natterer <mitch gimp org>
Date:   Thu Jan 3 16:46:00 2019 +0100

    Issue #1538 - Crash when adding file to already opened image and...
    
    ...closing this image while the file is being loaded
    
    Ref the image around all calls to file_open_layers() and
    gimp_image_add_layers() so it stays around even if the user closes the
    display in the meantime.
    
    (cherry picked from commit fc4add7c2b1e91d3721db6cf068cea059aacc19b)

 app/dialogs/file-open-dialog.c     | 20 ++++++++++++++++---
 app/display/gimpdisplayshell-dnd.c | 39 ++++++++++++++++++++++++++------------
 app/widgets/gimplayertreeview.c    |  4 ++++
 3 files changed, 48 insertions(+), 15 deletions(-)
---
diff --git a/app/dialogs/file-open-dialog.c b/app/dialogs/file-open-dialog.c
index 2113703e56..59219d4b2a 100644
--- a/app/dialogs/file-open-dialog.c
+++ b/app/dialogs/file-open-dialog.c
@@ -128,6 +128,9 @@ file_open_dialog_response (GtkWidget *dialog,
   if (! open_dialog->open_as_layers)
     gtk_window_set_transient_for (GTK_WINDOW (dialog), NULL);
 
+  if (file_dialog->image)
+    g_object_ref (file_dialog->image);
+
   for (list = files; list; list = g_slist_next (list))
     {
       GFile *file = list->data;
@@ -142,7 +145,10 @@ file_open_dialog_response (GtkWidget *dialog,
                                                                 file_dialog->file_proc);
 
               if (file_dialog->image)
-                success = TRUE;
+                {
+                  g_object_ref (file_dialog->image);
+                  success = TRUE;
+                }
             }
           else if (file_open_dialog_open_layers (dialog,
                                                  file_dialog->image,
@@ -174,13 +180,21 @@ file_open_dialog_response (GtkWidget *dialog,
 
   if (success)
     {
-      if (open_dialog->open_as_layers && file_dialog->image)
-        gimp_image_flush (file_dialog->image);
+      if (file_dialog->image)
+        {
+          if (open_dialog->open_as_layers)
+            gimp_image_flush (file_dialog->image);
+
+          g_object_unref (file_dialog->image);
+        }
 
       gtk_widget_destroy (dialog);
     }
   else
     {
+      if (file_dialog->image)
+        g_object_unref (file_dialog->image);
+
       gimp_file_dialog_set_sensitive (file_dialog, TRUE);
     }
 
diff --git a/app/display/gimpdisplayshell-dnd.c b/app/display/gimpdisplayshell-dnd.c
index 996cb75595..24ed1c238a 100644
--- a/app/display/gimpdisplayshell-dnd.c
+++ b/app/display/gimpdisplayshell-dnd.c
@@ -518,12 +518,11 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
   GList            *list;
   gboolean          open_as_layers;
 
-  /* If the app is already being torn down, shell->display might be NULL here.
-   * Play it safe. */
+  /* If the app is already being torn down, shell->display might be
+   * NULL here.  Play it safe.
+   */
   if (! shell->display)
-    {
-      return;
-    }
+    return;
 
   image = gimp_display_get_image (shell->display);
   context = gimp_get_user_context (shell->display->gimp);
@@ -532,6 +531,9 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
 
   open_as_layers = (image != NULL);
 
+  if (image)
+    g_object_ref (image);
+
   for (list = uri_list; list; list = g_list_next (list))
     {
       GFile             *file  = g_file_new_for_uri (list->data);
@@ -543,6 +545,7 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
         {
           /* It seems as if GIMP is being torn down for quitting. Bail out. */
           g_object_unref (file);
+          g_clear_object (&image);
           return;
         }
 
@@ -558,11 +561,14 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
 
           if (new_layers)
             {
-              gint x, y;
-              gint width, height;
+              gint x      = 0;
+              gint y      = 0;
+              gint width  = gimp_image_get_width  (image);
+              gint height = gimp_image_get_height (image);
 
-              gimp_display_shell_untransform_viewport (shell, &x, &y,
-                                                       &width, &height);
+              if (gimp_display_get_image (shell->display))
+                gimp_display_shell_untransform_viewport (shell, &x, &y,
+                                                         &width, &height);
 
               gimp_image_add_layers (image, new_layers,
                                      GIMP_IMAGE_ACTIVE_PARENT, -1,
@@ -601,13 +607,20 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
                                           gimp_widget_get_monitor (widget),
                                           &status, &error);
 
-          if (! image && status != GIMP_PDB_CANCEL)
-            warn = TRUE;
+          if (image)
+            {
+              g_object_ref (image);
+            }
+          else if (status != GIMP_PDB_CANCEL)
+            {
+              warn = TRUE;
+            }
         }
 
       /* Something above might have run a few rounds of the main loop. Check
        * that shell->display is still there, otherwise ignore this as the app
-       * is being torn down for quitting. */
+       * is being torn down for quitting.
+       */
       if (warn && shell->display)
         {
           gimp_message (shell->display->gimp, G_OBJECT (shell->display),
@@ -622,6 +635,8 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
 
   if (image)
     gimp_display_shell_dnd_flush (shell, image);
+
+  g_clear_object (&image);
 }
 
 static void
diff --git a/app/widgets/gimplayertreeview.c b/app/widgets/gimplayertreeview.c
index e88fc2ea99..0968850b60 100644
--- a/app/widgets/gimplayertreeview.c
+++ b/app/widgets/gimplayertreeview.c
@@ -735,6 +735,8 @@ gimp_layer_tree_view_drop_uri_list (GimpContainerTreeView   *view,
                                               drop_pos,
                                               (GimpViewable **) &parent);
 
+  g_object_ref (image);
+
   for (list = uri_list; list; list = g_list_next (list))
     {
       const gchar       *uri   = list->data;
@@ -774,6 +776,8 @@ gimp_layer_tree_view_drop_uri_list (GimpContainerTreeView   *view,
     }
 
   gimp_image_flush (image);
+
+  g_object_unref (image);
 }
 
 static void


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