[gimp] app: add layers/channels/vectors freeze/thaw to gimpplugin-cleanup



commit 7e1df2c8c6fbe80b3812217810025edc55005ae4
Author: Michael Natterer <mitch gimp org>
Date:   Mon May 7 20:09:07 2018 +0200

    app: add layers/channels/vectors freeze/thaw to gimpplugin-cleanup
    
    so plug-ins cannot thaw what they haven't frozen, and the code
    can clean up frozen stuff left behind by crashed or broken plug-ins.
    
    Also redo the cleanup code so it only keeps track of the undo group
    counts and freeze counts of what *this* GimpPlugInProcFrame did
    itself. That should make it even stricter against broken code that
    could mess up internals.

 app/pdb/image-cmds.c             |   55 +++++--
 app/plug-in/gimpplugin-cleanup.c |  355 +++++++++++++++++++++++++++++++-------
 app/plug-in/gimpplugin-cleanup.h |   15 ++
 pdb/groups/image.pdb             |   55 +++++--
 4 files changed, 396 insertions(+), 84 deletions(-)
---
diff --git a/app/pdb/image-cmds.c b/app/pdb/image-cmds.c
index 41c9626..7dd4670 100644
--- a/app/pdb/image-cmds.c
+++ b/app/pdb/image-cmds.c
@@ -53,6 +53,7 @@
 #include "core/gimpselection.h"
 #include "core/gimptempbuf.h"
 #include "file/file-utils.h"
+#include "plug-in/gimpplugin-cleanup.h"
 #include "plug-in/gimpplugin.h"
 #include "plug-in/gimppluginmanager.h"
 #include "vectors/gimpvectors.h"
@@ -910,9 +911,14 @@ image_freeze_layers_invoker (GimpProcedure         *procedure,
 
   if (success)
     {
+      GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
       GimpContainer *container = gimp_image_get_layers (image);
 
-      gimp_container_freeze (container);
+      if (plug_in)
+        success = gimp_plug_in_cleanup_layers_freeze (plug_in, image);
+
+      if (success)
+        gimp_container_freeze (container);
     }
 
   return gimp_procedure_get_return_values (procedure, success,
@@ -934,12 +940,17 @@ image_thaw_layers_invoker (GimpProcedure         *procedure,
 
   if (success)
     {
+      GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
       GimpContainer *container = gimp_image_get_layers (image);
 
-      if (gimp_container_frozen (container))
+      if (plug_in)
+        success = gimp_plug_in_cleanup_layers_thaw (plug_in, image);
+
+      if (success)
+        success = gimp_container_frozen (container);
+
+      if (success)
         gimp_container_thaw (container);
-      else
-        success = FALSE;
     }
 
   return gimp_procedure_get_return_values (procedure, success,
@@ -1064,9 +1075,14 @@ image_freeze_channels_invoker (GimpProcedure         *procedure,
 
   if (success)
     {
+      GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
       GimpContainer *container = gimp_image_get_channels (image);
 
-      gimp_container_freeze (container);
+      if (plug_in)
+        success = gimp_plug_in_cleanup_channels_freeze (plug_in, image);
+
+      if (success)
+        gimp_container_freeze (container);
     }
 
   return gimp_procedure_get_return_values (procedure, success,
@@ -1088,12 +1104,17 @@ image_thaw_channels_invoker (GimpProcedure         *procedure,
 
   if (success)
     {
+      GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
       GimpContainer *container = gimp_image_get_channels (image);
 
-      if (gimp_container_frozen (container))
+      if (plug_in)
+        success = gimp_plug_in_cleanup_channels_thaw (plug_in, image);
+
+      if (success)
+        success = gimp_container_frozen (container);
+
+      if (success)
         gimp_container_thaw (container);
-      else
-        success = FALSE;
     }
 
   return gimp_procedure_get_return_values (procedure, success,
@@ -1218,9 +1239,14 @@ image_freeze_vectors_invoker (GimpProcedure         *procedure,
 
   if (success)
     {
+      GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
       GimpContainer *container = gimp_image_get_vectors (image);
 
-      gimp_container_freeze (container);
+      if (plug_in)
+        success = gimp_plug_in_cleanup_vectors_freeze (plug_in, image);
+
+      if (success)
+        gimp_container_freeze (container);
     }
 
   return gimp_procedure_get_return_values (procedure, success,
@@ -1242,12 +1268,17 @@ image_thaw_vectors_invoker (GimpProcedure         *procedure,
 
   if (success)
     {
+      GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
       GimpContainer *container = gimp_image_get_vectors (image);
 
-      if (gimp_container_frozen (container))
+      if (plug_in)
+        success = gimp_plug_in_cleanup_vectors_thaw (plug_in, image);
+
+      if (success)
+        success = gimp_container_frozen (container);
+
+      if (success)
         gimp_container_thaw (container);
-      else
-        success = FALSE;
     }
 
   return gimp_procedure_get_return_values (procedure, success,
diff --git a/app/plug-in/gimpplugin-cleanup.c b/app/plug-in/gimpplugin-cleanup.c
index 8903c32..05ee15b 100644
--- a/app/plug-in/gimpplugin-cleanup.c
+++ b/app/plug-in/gimpplugin-cleanup.c
@@ -48,6 +48,9 @@ struct _GimpPlugInCleanupImage
   gint       image_ID;
 
   gint       undo_group_count;
+  gint       layers_freeze_count;
+  gint       channels_freeze_count;
+  gint       vectors_freeze_count;
 };
 
 
@@ -65,22 +68,30 @@ struct _GimpPlugInCleanupItem
 /*  local function prototypes  */
 
 static GimpPlugInCleanupImage *
-              gimp_plug_in_cleanup_image_new  (GimpImage              *image);
-static void   gimp_plug_in_cleanup_image_free (GimpPlugInCleanupImage *cleanup);
+              gimp_plug_in_cleanup_image_new      (GimpPlugInProcFrame    *proc_frame,
+                                                   GimpImage              *image);
+static void   gimp_plug_in_cleanup_image_free     (GimpPlugInProcFrame    *proc_frame,
+                                                   GimpPlugInCleanupImage *cleanup);
+static gboolean
+              gimp_plug_in_cleanup_image_is_clean (GimpPlugInCleanupImage *cleanup);
 static GimpPlugInCleanupImage *
-              gimp_plug_in_cleanup_image_get  (GimpPlugInProcFrame    *proc_frame,
-                                               GimpImage              *image);
-static void   gimp_plug_in_cleanup_image      (GimpPlugInProcFrame    *proc_frame,
-                                               GimpPlugInCleanupImage *cleanup);
+              gimp_plug_in_cleanup_image_get      (GimpPlugInProcFrame    *proc_frame,
+                                                   GimpImage              *image);
+static void   gimp_plug_in_cleanup_image          (GimpPlugInProcFrame    *proc_frame,
+                                                   GimpPlugInCleanupImage *cleanup);
 
 static GimpPlugInCleanupItem *
-              gimp_plug_in_cleanup_item_new   (GimpItem               *item);
-static void   gimp_plug_in_cleanup_item_free  (GimpPlugInCleanupItem  *cleanup);
+              gimp_plug_in_cleanup_item_new       (GimpPlugInProcFrame    *proc_frame,
+                                                   GimpItem               *item);
+static void   gimp_plug_in_cleanup_item_free      (GimpPlugInProcFrame    *proc_frame,
+                                                   GimpPlugInCleanupItem  *cleanup);
+static gboolean
+              gimp_plug_in_cleanup_item_is_clean  (GimpPlugInCleanupItem  *cleanup);
 static GimpPlugInCleanupItem *
-              gimp_plug_in_cleanup_item_get   (GimpPlugInProcFrame    *proc_frame,
-                                               GimpItem               *item);
-static void   gimp_plug_in_cleanup_item       (GimpPlugInProcFrame    *proc_frame,
-                                               GimpPlugInCleanupItem  *cleanup);
+              gimp_plug_in_cleanup_item_get       (GimpPlugInProcFrame    *proc_frame,
+                                                   GimpItem               *item);
+static void   gimp_plug_in_cleanup_item           (GimpPlugInProcFrame    *proc_frame,
+                                                   GimpPlugInCleanupItem  *cleanup);
 
 
 /*  public functions  */
@@ -99,21 +110,66 @@ gimp_plug_in_cleanup_undo_group_start (GimpPlugIn *plug_in,
   cleanup    = gimp_plug_in_cleanup_image_get (proc_frame, image);
 
   if (! cleanup)
+    cleanup = gimp_plug_in_cleanup_image_new (proc_frame, image);
+
+  cleanup->undo_group_count++;
+
+  return TRUE;
+}
+
+gboolean
+gimp_plug_in_cleanup_undo_group_end (GimpPlugIn *plug_in,
+                                     GimpImage  *image)
+{
+  GimpPlugInProcFrame    *proc_frame;
+  GimpPlugInCleanupImage *cleanup;
+
+  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
+
+  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
+  cleanup    = gimp_plug_in_cleanup_image_get (proc_frame, image);
+
+  if (! cleanup)
+    return FALSE;
+
+  if (cleanup->undo_group_count > 0)
     {
-      cleanup = gimp_plug_in_cleanup_image_new (image);
+      cleanup->undo_group_count--;
 
-      cleanup->undo_group_count = gimp_image_get_undo_group_count (image);
+      if (gimp_plug_in_cleanup_image_is_clean (cleanup))
+        gimp_plug_in_cleanup_image_free (proc_frame, cleanup);
 
-      proc_frame->image_cleanups = g_list_prepend (proc_frame->image_cleanups,
-                                                   cleanup);
+      return TRUE;
     }
 
+  return FALSE;
+}
+
+gboolean
+gimp_plug_in_cleanup_layers_freeze (GimpPlugIn *plug_in,
+                                    GimpImage  *image)
+{
+  GimpPlugInProcFrame    *proc_frame;
+  GimpPlugInCleanupImage *cleanup;
+
+  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
+
+  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
+  cleanup    = gimp_plug_in_cleanup_image_get (proc_frame, image);
+
+  if (! cleanup)
+    cleanup = gimp_plug_in_cleanup_image_new (proc_frame, image);
+
+  cleanup->layers_freeze_count++;
+
   return TRUE;
 }
 
 gboolean
-gimp_plug_in_cleanup_undo_group_end (GimpPlugIn *plug_in,
-                                     GimpImage  *image)
+gimp_plug_in_cleanup_layers_thaw (GimpPlugIn *plug_in,
+                                  GimpImage  *image)
 {
   GimpPlugInProcFrame    *proc_frame;
   GimpPlugInCleanupImage *cleanup;
@@ -127,17 +183,120 @@ gimp_plug_in_cleanup_undo_group_end (GimpPlugIn *plug_in,
   if (! cleanup)
     return FALSE;
 
-  if (cleanup->undo_group_count == gimp_image_get_undo_group_count (image) - 1)
+  if (cleanup->layers_freeze_count > 0)
     {
-      proc_frame->image_cleanups = g_list_remove (proc_frame->image_cleanups,
-                                                  cleanup);
-      gimp_plug_in_cleanup_image_free (cleanup);
+      cleanup->layers_freeze_count--;
+
+      if (gimp_plug_in_cleanup_image_is_clean (cleanup))
+        gimp_plug_in_cleanup_image_free (proc_frame, cleanup);
+
+      return TRUE;
     }
 
+  return FALSE;
+}
+
+gboolean
+gimp_plug_in_cleanup_channels_freeze (GimpPlugIn *plug_in,
+                                      GimpImage  *image)
+{
+  GimpPlugInProcFrame    *proc_frame;
+  GimpPlugInCleanupImage *cleanup;
+
+  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
+
+  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
+  cleanup    = gimp_plug_in_cleanup_image_get (proc_frame, image);
+
+  if (! cleanup)
+    cleanup = gimp_plug_in_cleanup_image_new (proc_frame, image);
+
+  cleanup->channels_freeze_count++;
+
   return TRUE;
 }
 
 gboolean
+gimp_plug_in_cleanup_channels_thaw (GimpPlugIn *plug_in,
+                                    GimpImage  *image)
+{
+  GimpPlugInProcFrame    *proc_frame;
+  GimpPlugInCleanupImage *cleanup;
+
+  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
+
+  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
+  cleanup    = gimp_plug_in_cleanup_image_get (proc_frame, image);
+
+  if (! cleanup)
+    return FALSE;
+
+  if (cleanup->channels_freeze_count > 0)
+    {
+      cleanup->channels_freeze_count--;
+
+      if (gimp_plug_in_cleanup_image_is_clean (cleanup))
+        gimp_plug_in_cleanup_image_free (proc_frame, cleanup);
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+gboolean
+gimp_plug_in_cleanup_vectors_freeze (GimpPlugIn *plug_in,
+                                     GimpImage  *image)
+{
+  GimpPlugInProcFrame    *proc_frame;
+  GimpPlugInCleanupImage *cleanup;
+
+  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
+
+  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
+  cleanup    = gimp_plug_in_cleanup_image_get (proc_frame, image);
+
+  if (! cleanup)
+    cleanup = gimp_plug_in_cleanup_image_new (proc_frame, image);
+
+  cleanup->vectors_freeze_count++;
+
+  return TRUE;
+}
+
+gboolean
+gimp_plug_in_cleanup_vectors_thaw (GimpPlugIn *plug_in,
+                                   GimpImage  *image)
+{
+  GimpPlugInProcFrame    *proc_frame;
+  GimpPlugInCleanupImage *cleanup;
+
+  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
+
+  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
+  cleanup    = gimp_plug_in_cleanup_image_get (proc_frame, image);
+
+  if (! cleanup)
+    return FALSE;
+
+  if (cleanup->vectors_freeze_count > 0)
+    {
+      cleanup->vectors_freeze_count--;
+
+      if (gimp_plug_in_cleanup_image_is_clean (cleanup))
+        gimp_plug_in_cleanup_image_free (proc_frame, cleanup);
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+gboolean
 gimp_plug_in_cleanup_add_shadow (GimpPlugIn   *plug_in,
                                  GimpDrawable *drawable)
 {
@@ -151,12 +310,7 @@ gimp_plug_in_cleanup_add_shadow (GimpPlugIn   *plug_in,
   cleanup    = gimp_plug_in_cleanup_item_get (proc_frame, GIMP_ITEM (drawable));
 
   if (! cleanup)
-    {
-      cleanup = gimp_plug_in_cleanup_item_new (GIMP_ITEM (drawable));
-
-      proc_frame->item_cleanups = g_list_prepend (proc_frame->item_cleanups,
-                                                  cleanup);
-    }
+    cleanup = gimp_plug_in_cleanup_item_new (proc_frame, GIMP_ITEM (drawable));
 
   cleanup->shadow_buffer = TRUE;
 
@@ -179,28 +333,29 @@ gimp_plug_in_cleanup_remove_shadow (GimpPlugIn   *plug_in,
   if (! cleanup)
     return FALSE;
 
-  if (! cleanup->shadow_buffer)
-    return FALSE;
+  if (cleanup->shadow_buffer)
+    {
+      cleanup->shadow_buffer = FALSE;
 
-  proc_frame->item_cleanups = g_list_remove (proc_frame->item_cleanups,
-                                             cleanup);
-  gimp_plug_in_cleanup_item_free (cleanup);
+      if (gimp_plug_in_cleanup_item_is_clean (cleanup))
+        gimp_plug_in_cleanup_item_free (proc_frame, cleanup);
 
-  return TRUE;
+      return TRUE;
+    }
+
+  return FALSE;
 }
 
 void
 gimp_plug_in_cleanup (GimpPlugIn          *plug_in,
                       GimpPlugInProcFrame *proc_frame)
 {
-  GList *list;
-
   g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
   g_return_if_fail (proc_frame != NULL);
 
-  for (list = proc_frame->image_cleanups; list; list = g_list_next (list))
+  while (proc_frame->image_cleanups)
     {
-      GimpPlugInCleanupImage *cleanup = list->data;
+      GimpPlugInCleanupImage *cleanup = proc_frame->image_cleanups->data;
 
       if (gimp_image_get_by_ID (plug_in->manager->gimp,
                                 cleanup->image_ID) == cleanup->image)
@@ -208,15 +363,12 @@ gimp_plug_in_cleanup (GimpPlugIn          *plug_in,
           gimp_plug_in_cleanup_image (proc_frame, cleanup);
         }
 
-      gimp_plug_in_cleanup_image_free (cleanup);
+      gimp_plug_in_cleanup_image_free (proc_frame, cleanup);
     }
 
-  g_list_free (proc_frame->image_cleanups);
-  proc_frame->image_cleanups = NULL;
-
-  for (list = proc_frame->item_cleanups; list; list = g_list_next (list))
+  while (proc_frame->item_cleanups)
     {
-      GimpPlugInCleanupItem *cleanup = list->data;
+      GimpPlugInCleanupItem *cleanup = proc_frame->item_cleanups->data;
 
       if (gimp_item_get_by_ID (plug_in->manager->gimp,
                                cleanup->item_ID) == cleanup->item)
@@ -224,33 +376,56 @@ gimp_plug_in_cleanup (GimpPlugIn          *plug_in,
           gimp_plug_in_cleanup_item (proc_frame, cleanup);
         }
 
-      gimp_plug_in_cleanup_item_free (cleanup);
+      gimp_plug_in_cleanup_item_free (proc_frame, cleanup);
     }
-
-  g_list_free (proc_frame->item_cleanups);
-  proc_frame->item_cleanups = NULL;
 }
 
 
 /*  private functions  */
 
 static GimpPlugInCleanupImage *
-gimp_plug_in_cleanup_image_new (GimpImage *image)
+gimp_plug_in_cleanup_image_new (GimpPlugInProcFrame *proc_frame,
+                                GimpImage           *image)
 {
   GimpPlugInCleanupImage *cleanup = g_slice_new0 (GimpPlugInCleanupImage);
 
   cleanup->image    = image;
   cleanup->image_ID = gimp_image_get_ID (image);
 
+  proc_frame->image_cleanups = g_list_prepend (proc_frame->image_cleanups,
+                                               cleanup);
+
   return cleanup;
 }
 
 static void
-gimp_plug_in_cleanup_image_free (GimpPlugInCleanupImage *cleanup)
+gimp_plug_in_cleanup_image_free (GimpPlugInProcFrame    *proc_frame,
+                                 GimpPlugInCleanupImage *cleanup)
 {
+  proc_frame->image_cleanups = g_list_remove (proc_frame->image_cleanups,
+                                              cleanup);
+
   g_slice_free (GimpPlugInCleanupImage, cleanup);
 }
 
+static gboolean
+gimp_plug_in_cleanup_image_is_clean (GimpPlugInCleanupImage *cleanup)
+{
+  if (cleanup->undo_group_count > 0)
+    return FALSE;
+
+  if (cleanup->layers_freeze_count > 0)
+    return FALSE;
+
+  if (cleanup->channels_freeze_count > 0)
+    return FALSE;
+
+  if (cleanup->vectors_freeze_count > 0)
+    return FALSE;
+
+  return TRUE;
+}
+
 static GimpPlugInCleanupImage *
 gimp_plug_in_cleanup_image_get (GimpPlugInProcFrame *proc_frame,
                                 GimpImage           *image)
@@ -272,42 +447,100 @@ static void
 gimp_plug_in_cleanup_image (GimpPlugInProcFrame    *proc_frame,
                             GimpPlugInCleanupImage *cleanup)
 {
-  GimpImage *image = cleanup->image;
+  GimpImage     *image = cleanup->image;
+  GimpContainer *container;
 
-  if (gimp_image_get_undo_group_count (image) == 0)
-    return;
-
-  if (cleanup->undo_group_count != gimp_image_get_undo_group_count (image))
+  if (cleanup->undo_group_count > 0)
     {
       g_message ("Plug-in '%s' left image undo in inconsistent state, "
                  "closing open undo groups.",
                  gimp_procedure_get_label (proc_frame->procedure));
 
-      while (cleanup->undo_group_count < gimp_image_get_undo_group_count (image))
+      while (cleanup->undo_group_count--)
+        if (! gimp_image_undo_group_end (image))
+          break;
+    }
+
+  container = gimp_image_get_layers (image);
+
+  if (cleanup->layers_freeze_count > 0)
+    {
+      g_message ("Plug-in '%s' left image's layers frozen, "
+                 "thawing layers.",
+                 gimp_procedure_get_label (proc_frame->procedure));
+
+      while (cleanup->layers_freeze_count-- > 0 &&
+             gimp_container_frozen (container))
+        {
+          gimp_container_thaw (container);
+        }
+    }
+
+  container = gimp_image_get_channels (image);
+
+  if (cleanup->channels_freeze_count > 0)
+    {
+      g_message ("Plug-in '%s' left image's channels frozen, "
+                 "thawing channels.",
+                 gimp_procedure_get_label (proc_frame->procedure));
+
+      while (cleanup->channels_freeze_count-- > 0 &&
+             gimp_container_frozen (container))
         {
-          if (! gimp_image_undo_group_end (image))
-            break;
+          gimp_container_thaw (container);
+        }
+    }
+
+  container = gimp_image_get_vectors (image);
+
+  if (cleanup->vectors_freeze_count > 0)
+    {
+      g_message ("Plug-in '%s' left image's vectors frozen, "
+                 "thawing vectors.",
+                 gimp_procedure_get_label (proc_frame->procedure));
+
+      while (cleanup->vectors_freeze_count > 0 &&
+             gimp_container_frozen (container))
+        {
+          gimp_container_thaw (container);
         }
     }
 }
 
 static GimpPlugInCleanupItem *
-gimp_plug_in_cleanup_item_new (GimpItem *item)
+gimp_plug_in_cleanup_item_new (GimpPlugInProcFrame *proc_frame,
+                               GimpItem            *item)
 {
   GimpPlugInCleanupItem *cleanup = g_slice_new0 (GimpPlugInCleanupItem);
 
   cleanup->item    = item;
   cleanup->item_ID = gimp_item_get_ID (item);
 
+  proc_frame->item_cleanups = g_list_remove (proc_frame->item_cleanups,
+                                             cleanup);
+
   return cleanup;
 }
 
 static void
-gimp_plug_in_cleanup_item_free (GimpPlugInCleanupItem *cleanup)
+gimp_plug_in_cleanup_item_free (GimpPlugInProcFrame   *proc_frame,
+                                GimpPlugInCleanupItem *cleanup)
 {
+  proc_frame->item_cleanups = g_list_remove (proc_frame->item_cleanups,
+                                             cleanup);
+
   g_slice_free (GimpPlugInCleanupItem, cleanup);
 }
 
+static gboolean
+gimp_plug_in_cleanup_item_is_clean (GimpPlugInCleanupItem *cleanup)
+{
+  if (cleanup->shadow_buffer)
+    return FALSE;
+
+  return TRUE;
+}
+
 static GimpPlugInCleanupItem *
 gimp_plug_in_cleanup_item_get (GimpPlugInProcFrame *proc_frame,
                                GimpItem            *item)
@@ -339,5 +572,7 @@ gimp_plug_in_cleanup_item (GimpPlugInProcFrame   *proc_frame,
                 gimp_procedure_get_label (proc_frame->procedure));
 
       gimp_drawable_free_shadow_buffer (GIMP_DRAWABLE (item));
+
+      cleanup->shadow_buffer = FALSE;
     }
 }
diff --git a/app/plug-in/gimpplugin-cleanup.h b/app/plug-in/gimpplugin-cleanup.h
index b5eeb8f..e639025 100644
--- a/app/plug-in/gimpplugin-cleanup.h
+++ b/app/plug-in/gimpplugin-cleanup.h
@@ -26,6 +26,21 @@ gboolean   gimp_plug_in_cleanup_undo_group_start (GimpPlugIn          *plug_in,
 gboolean   gimp_plug_in_cleanup_undo_group_end   (GimpPlugIn          *plug_in,
                                                   GimpImage           *image);
 
+gboolean   gimp_plug_in_cleanup_layers_freeze    (GimpPlugIn          *plug_in,
+                                                  GimpImage           *image);
+gboolean   gimp_plug_in_cleanup_layers_thaw      (GimpPlugIn          *plug_in,
+                                                  GimpImage           *image);
+
+gboolean   gimp_plug_in_cleanup_channels_freeze  (GimpPlugIn          *plug_in,
+                                                  GimpImage           *image);
+gboolean   gimp_plug_in_cleanup_channels_thaw    (GimpPlugIn          *plug_in,
+                                                  GimpImage           *image);
+
+gboolean   gimp_plug_in_cleanup_vectors_freeze   (GimpPlugIn          *plug_in,
+                                                  GimpImage           *image);
+gboolean   gimp_plug_in_cleanup_vectors_thaw     (GimpPlugIn          *plug_in,
+                                                  GimpImage           *image);
+
 gboolean   gimp_plug_in_cleanup_add_shadow       (GimpPlugIn          *plug_in,
                                                   GimpDrawable        *drawable);
 gboolean   gimp_plug_in_cleanup_remove_shadow    (GimpPlugIn          *plug_in,
diff --git a/pdb/groups/image.pdb b/pdb/groups/image.pdb
index 1ae9655..940afab 100644
--- a/pdb/groups/image.pdb
+++ b/pdb/groups/image.pdb
@@ -1044,9 +1044,14 @@ HELP
     %invoke = (
     code => <<'CODE'
 {
+  GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
   GimpContainer *container = gimp_image_get_layers (image);
 
-  gimp_container_freeze (container);
+  if (plug_in)
+    success = gimp_plug_in_cleanup_layers_freeze (plug_in, image);
+
+  if (success)
+    gimp_container_freeze (container);
 }
 CODE
     );
@@ -1074,12 +1079,17 @@ HELP
     %invoke = (
     code => <<'CODE'
 {
+  GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
   GimpContainer *container = gimp_image_get_layers (image);
 
-  if (gimp_container_frozen (container))
+  if (plug_in)
+    success = gimp_plug_in_cleanup_layers_thaw (plug_in, image);
+
+  if (success)
+    success = gimp_container_frozen (container);
+
+  if (success)
     gimp_container_thaw (container);
-  else
-    success = FALSE;
 }
 CODE
     );
@@ -1214,9 +1224,14 @@ HELP
     %invoke = (
     code => <<'CODE'
 {
+  GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
   GimpContainer *container = gimp_image_get_channels (image);
 
-  gimp_container_freeze (container);
+  if (plug_in)
+    success = gimp_plug_in_cleanup_channels_freeze (plug_in, image);
+
+  if (success)
+    gimp_container_freeze (container);
 }
 CODE
     );
@@ -1244,12 +1259,17 @@ HELP
     %invoke = (
     code => <<'CODE'
 {
+  GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
   GimpContainer *container = gimp_image_get_channels (image);
 
-  if (gimp_container_frozen (container))
+  if (plug_in)
+    success = gimp_plug_in_cleanup_channels_thaw (plug_in, image);
+
+  if (success)
+    success = gimp_container_frozen (container);
+
+  if (success)
     gimp_container_thaw (container);
-  else
-    success = FALSE;
 }
 CODE
     );
@@ -1382,9 +1402,14 @@ HELP
     %invoke = (
     code => <<'CODE'
 {
+  GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
   GimpContainer *container = gimp_image_get_vectors (image);
 
-  gimp_container_freeze (container);
+  if (plug_in)
+    success = gimp_plug_in_cleanup_vectors_freeze (plug_in, image);
+
+  if (success)
+    gimp_container_freeze (container);
 }
 CODE
     );
@@ -1412,12 +1437,17 @@ HELP
     %invoke = (
     code => <<'CODE'
 {
+  GimpPlugIn    *plug_in   = gimp->plug_in_manager->current_plug_in;
   GimpContainer *container = gimp_image_get_vectors (image);
 
-  if (gimp_container_frozen (container))
+  if (plug_in)
+    success = gimp_plug_in_cleanup_vectors_thaw (plug_in, image);
+
+  if (success)
+    success = gimp_container_frozen (container);
+
+  if (success)
     gimp_container_thaw (container);
-  else
-    success = FALSE;
 }
 CODE
     );
@@ -3051,6 +3081,7 @@ CODE
               "core/gimptempbuf.h"
               "file/file-utils.h"
               "plug-in/gimpplugin.h"
+              "plug-in/gimpplugin-cleanup.h"
               "plug-in/gimppluginmanager.h"
               "gimppdbcontext.h"
               "gimppdberror.h"


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