[gimp] Bug 793539 - Gimp stops each time you close a picture



commit 4a0cc01dfac117d63e63478ccdfe41336f4de39f
Author: Ell <ell_se yahoo com>
Date:   Sun Feb 18 09:32:35 2018 -0500

    Bug 793539 - Gimp stops each time you close a picture
    
    Don't choke when calling gimp_tool_rectangle_set_constraint() while
    there's no active image, or while the active image has no active
    layer, which can happen when updating the default aspect ratio of
    the crop tool.  This would previously result in CRITICALs.
    
    Additionally, use weak pointers for the crop tool's current_image
    and current_layer members, to avoid potential dangling pointers.
    While not currently necessary, this makes the code less dependent
    on the exact order of events.

 app/display/gimptoolrectangle.c |   27 +++++++++++++++++----------
 app/tools/gimpcroptool.c        |   25 +++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 10 deletions(-)
---
diff --git a/app/display/gimptoolrectangle.c b/app/display/gimptoolrectangle.c
index 6964b41..ccfbbe2 100644
--- a/app/display/gimptoolrectangle.c
+++ b/app/display/gimptoolrectangle.c
@@ -3662,20 +3662,27 @@ gimp_tool_rectangle_get_constraints (GimpToolRectangle       *rectangle,
   switch (constraint)
     {
     case GIMP_RECTANGLE_CONSTRAIN_IMAGE:
-      *min_x = 0;
-      *min_y = 0;
-      *max_x = gimp_image_get_width  (image);
-      *max_y = gimp_image_get_height (image);
+      if (image)
+        {
+          *min_x = 0;
+          *min_y = 0;
+          *max_x = gimp_image_get_width  (image);
+          *max_y = gimp_image_get_height (image);
+        }
       break;
 
     case GIMP_RECTANGLE_CONSTRAIN_DRAWABLE:
-      {
-        GimpItem *item = GIMP_ITEM (gimp_image_get_active_drawable (image));
+      if (image)
+        {
+          GimpItem *item = GIMP_ITEM (gimp_image_get_active_drawable (image));
 
-        gimp_item_get_offset (item, min_x, min_y);
-        *max_x = *min_x + gimp_item_get_width  (item);
-        *max_y = *min_y + gimp_item_get_height (item);
-      }
+          if (item)
+            {
+              gimp_item_get_offset (item, min_x, min_y);
+              *max_x = *min_x + gimp_item_get_width  (item);
+              *max_y = *min_y + gimp_item_get_height (item);
+            }
+        }
       break;
 
     default:
diff --git a/app/tools/gimpcroptool.c b/app/tools/gimpcroptool.c
index fc485de..c008f97 100644
--- a/app/tools/gimpcroptool.c
+++ b/app/tools/gimpcroptool.c
@@ -45,6 +45,7 @@
 
 
 static void      gimp_crop_tool_constructed                (GObject              *object);
+static void      gimp_crop_tool_dispose                    (GObject              *object);
 
 static void      gimp_crop_tool_control                    (GimpTool             *tool,
                                                             GimpToolAction        action,
@@ -129,6 +130,7 @@ gimp_crop_tool_class_init (GimpCropToolClass *klass)
   GimpToolClass *tool_class   = GIMP_TOOL_CLASS (klass);
 
   object_class->constructed  = gimp_crop_tool_constructed;
+  object_class->dispose      = gimp_crop_tool_dispose;
 
   tool_class->control        = gimp_crop_tool_control;
   tool_class->button_press   = gimp_crop_tool_button_press;
@@ -183,6 +185,17 @@ gimp_crop_tool_constructed (GObject *object)
 }
 
 static void
+gimp_crop_tool_dispose (GObject *object)
+{
+  GimpCropTool *crop_tool = GIMP_CROP_TOOL (object);
+
+  /* Clean up current_image and current_layer. */
+  gimp_crop_tool_image_changed (crop_tool, NULL, NULL);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
 gimp_crop_tool_control (GimpTool       *tool,
                         GimpToolAction  action,
                         GimpDisplay    *display)
@@ -614,12 +627,18 @@ gimp_crop_tool_image_changed (GimpCropTool *crop_tool,
       g_signal_handlers_disconnect_by_func (crop_tool->current_image,
                                             gimp_crop_tool_image_active_layer_changed,
                                             NULL);
+
+      g_object_remove_weak_pointer (G_OBJECT (crop_tool->current_image),
+                                    (gpointer) &crop_tool->current_image);
     }
 
   crop_tool->current_image = image;
 
   if (crop_tool->current_image)
     {
+      g_object_add_weak_pointer (G_OBJECT (crop_tool->current_image),
+                                 (gpointer) &crop_tool->current_image);
+
       g_signal_connect_object (crop_tool->current_image, "size-changed",
                                G_CALLBACK (gimp_crop_tool_image_size_changed),
                                crop_tool,
@@ -652,6 +671,9 @@ gimp_crop_tool_image_active_layer_changed (GimpCropTool *crop_tool)
       g_signal_handlers_disconnect_by_func (crop_tool->current_layer,
                                             gimp_crop_tool_layer_size_changed,
                                             NULL);
+
+      g_object_remove_weak_pointer (G_OBJECT (crop_tool->current_layer),
+                                    (gpointer) &crop_tool->current_layer);
     }
 
   if (crop_tool->current_image)
@@ -666,6 +688,9 @@ gimp_crop_tool_image_active_layer_changed (GimpCropTool *crop_tool)
 
   if (crop_tool->current_layer)
     {
+      g_object_add_weak_pointer (G_OBJECT (crop_tool->current_layer),
+                                 (gpointer) &crop_tool->current_layer);
+
       g_signal_connect_object (crop_tool->current_layer, "size-changed",
                                G_CALLBACK (gimp_crop_tool_layer_size_changed),
                                crop_tool,


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