app: do not warn for stray images from command lines.

The INFO message "a stray image seems to have been left around by a
plug-in" was annoying when GIMP is run non-interactively, and when it
was about images open from command lines. Typically this message would
be visible on our CI when the various gimp-data scripts would fail. This
could only confuse script developers.

The fact is that while a plug-in (or batch script) should definitely
clean after itself by deleting images it created (unless it gave it a
display, in which case ownership is moved to the GUI), it is absolutely
expected that images opened through the command line would still exist
at exit.
This commit is contained in:
Jehan 2026-04-06 12:34:02 +02:00
parent 1332a755eb
commit f00bf531ae
6 changed files with 53 additions and 6 deletions

View file

@ -321,15 +321,15 @@ app_run (const gchar *full_prog_name,
if (gimp->be_verbose)
g_print ("EXIT: %s\n", G_STRFUNC);
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, TRUE);
g_clear_object (&app);
gimp_gegl_exit (gimp);
errors_exit ();
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, TRUE);
g_object_unref (gimp);
gimp_debug_instances ();

View file

@ -28,6 +28,8 @@
#include "core-types.h"
#include "gimpcoreapp.h"
#include "config/gimprc.h"
#include "gegl/gimp-babl.h"
@ -1368,9 +1370,20 @@ gimp_exit_idle_cleanup_stray_images (Gimp *gimp)
{
GimpImage *image = image_iter->data;
/* TODO: localize after string freeze. */
g_printerr ("INFO: a stray image seems to have been left around by a plug-in: \"%s\"",
gimp_image_get_display_name (image));
/* Plug-in developers are expected to free the images they
* created, unless they add a display (while in GUI mode), in
* which case the user gets ownership of the image and it will be
* freed as any other image by the GUI.
* On the other hand, images created from command lines are very
* likely to still exist when the software exits, if it was closed
* by the --quit argument, or run without an interface. This is
* normal use case.
*/
if (! gimp_image_get_from_command_line (image) ||
(! gimp->no_interface && ! gimp_core_app_get_quit (GIMP_CORE_APP (gimp->app))))
/* TODO: localize after string freeze. */
g_printerr ("INFO: a stray image seems to have been left around by a plug-in: \"%s\"\n",
gimp_image_get_display_name (image));
g_object_unref (image);
}

View file

@ -148,6 +148,8 @@ struct _GimpImagePrivate
/* Signal emission accumulator */
GimpImageFlushAccumulator flush_accum;
gboolean from_command_line;
};
#define GIMP_IMAGE_GET_PRIVATE(image) (((GimpImage *) (image))->priv)

View file

@ -909,6 +909,8 @@ gimp_image_init (GimpImage *image)
private->flush_accum.mask_changed = FALSE;
private->flush_accum.floating_selection_changed = FALSE;
private->flush_accum.preview_invalidated = FALSE;
private->from_command_line = FALSE;
}
static void
@ -6408,3 +6410,28 @@ gimp_image_get_converting (GimpImage *image)
return private->converting;
}
void
gimp_image_set_from_command_line (GimpImage *image,
gboolean from_command_line)
{
GimpImagePrivate *private;
g_return_if_fail (GIMP_IS_IMAGE (image));
private = GIMP_IMAGE_GET_PRIVATE (image);
private->from_command_line = from_command_line;
}
gboolean
gimp_image_get_from_command_line (GimpImage *image)
{
GimpImagePrivate *private;
g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
private = GIMP_IMAGE_GET_PRIVATE (image);
return private->from_command_line;
}

View file

@ -508,3 +508,7 @@ void gimp_image_invalidate_previews (GimpImage *image);
void gimp_image_set_converting (GimpImage *image,
gboolean converting);
gboolean gimp_image_get_converting (GimpImage *image);
void gimp_image_set_from_command_line (GimpImage *image,
gboolean from_command_line);
gboolean gimp_image_get_from_command_line (GimpImage *image);

View file

@ -690,6 +690,7 @@ file_open_from_command_line (Gimp *gimp,
{
success = TRUE;
gimp_image_set_from_command_line (image, TRUE);
g_object_set_data_full (G_OBJECT (gimp), GIMP_FILE_OPEN_LAST_FILE_KEY,
g_object_ref (file),
(GDestroyNotify) g_object_unref);