mirror of https://github.com/GNOME/gimp.git
Issue #11922: Fatal error on closing main window when in export plug-in.
This commit is contained in:
parent
8b57aabed2
commit
42f7a167c3
|
@ -103,34 +103,36 @@ enum
|
|||
};
|
||||
|
||||
|
||||
static void gimp_constructed (GObject *object);
|
||||
static void gimp_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_dispose (GObject *object);
|
||||
static void gimp_finalize (GObject *object);
|
||||
static void gimp_constructed (GObject *object);
|
||||
static void gimp_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_dispose (GObject *object);
|
||||
static void gimp_finalize (GObject *object);
|
||||
|
||||
static gint64 gimp_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size);
|
||||
static gint64 gimp_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size);
|
||||
|
||||
static void gimp_real_initialize (Gimp *gimp,
|
||||
GimpInitStatusFunc status_callback);
|
||||
static void gimp_real_restore (Gimp *gimp,
|
||||
GimpInitStatusFunc status_callback);
|
||||
static gboolean gimp_real_exit (Gimp *gimp,
|
||||
gboolean force);
|
||||
static void gimp_real_initialize (Gimp *gimp,
|
||||
GimpInitStatusFunc status_callback);
|
||||
static void gimp_real_restore (Gimp *gimp,
|
||||
GimpInitStatusFunc status_callback);
|
||||
static gboolean gimp_real_exit (Gimp *gimp,
|
||||
gboolean force);
|
||||
|
||||
static void gimp_global_config_notify (GObject *global_config,
|
||||
GParamSpec *param_spec,
|
||||
GObject *edit_config);
|
||||
static void gimp_edit_config_notify (GObject *edit_config,
|
||||
GParamSpec *param_spec,
|
||||
GObject *global_config);
|
||||
static void gimp_global_config_notify (GObject *global_config,
|
||||
GParamSpec *param_spec,
|
||||
GObject *edit_config);
|
||||
static void gimp_edit_config_notify (GObject *edit_config,
|
||||
GParamSpec *param_spec,
|
||||
GObject *global_config);
|
||||
|
||||
static gboolean gimp_exit_idle_cleanup_stray_images (Gimp *gimp);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (Gimp, gimp, GIMP_TYPE_OBJECT)
|
||||
|
@ -891,8 +893,7 @@ void
|
|||
gimp_exit (Gimp *gimp,
|
||||
gboolean force)
|
||||
{
|
||||
gboolean handled;
|
||||
GList *image_iter;
|
||||
gboolean handled;
|
||||
|
||||
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
||||
|
||||
|
@ -906,17 +907,9 @@ gimp_exit (Gimp *gimp,
|
|||
if (handled)
|
||||
return;
|
||||
|
||||
/* Get rid of images without display. We do this *after* handling the
|
||||
* usual exit callbacks, because the things that are torn down there
|
||||
* might have references to these images (for instance GimpActions
|
||||
* in the UI manager).
|
||||
*/
|
||||
while ((image_iter = gimp_get_image_iter (gimp)))
|
||||
{
|
||||
GimpImage *image = image_iter->data;
|
||||
|
||||
g_object_unref (image);
|
||||
}
|
||||
g_idle_add_full (G_PRIORITY_LOW,
|
||||
(GSourceFunc) gimp_exit_idle_cleanup_stray_images,
|
||||
gimp, NULL);
|
||||
}
|
||||
|
||||
GList *
|
||||
|
@ -1237,3 +1230,27 @@ gimp_get_temp_file (Gimp *gimp,
|
|||
|
||||
return file;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_exit_idle_cleanup_stray_images (Gimp *gimp)
|
||||
{
|
||||
GList *image_iter;
|
||||
|
||||
while (g_main_context_pending (NULL))
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
/* Get rid of images without display. We do this *after* handling the
|
||||
* usual exit callbacks and any other pending event, because the
|
||||
* things that are torn down there might have references to these
|
||||
* images, for instance GimpActions in the UI manager, or some plug-in
|
||||
* which was still running and had to get killed in gimp_exit() (cf. #11922).
|
||||
*/
|
||||
while ((image_iter = gimp_get_image_iter (gimp)))
|
||||
{
|
||||
GimpImage *image = image_iter->data;
|
||||
|
||||
g_object_unref (image);
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE ;
|
||||
}
|
||||
|
|
|
@ -820,6 +820,13 @@ file_save_dialog_save_image (GimpProgress *progress,
|
|||
|
||||
gimp_image_set_xcf_compression (image, xcf_compression);
|
||||
|
||||
/* The save may fail and the progress widget be already freed if we
|
||||
* close the main window while the save dialog is running. So add a
|
||||
* weak pointer to avoid sending an error message to an already-freed
|
||||
* GimpProgress. See #11922.
|
||||
*/
|
||||
g_object_add_weak_pointer (G_OBJECT (progress), (gpointer *) &progress);
|
||||
|
||||
status = file_save (gimp, image, progress, file,
|
||||
save_proc, run_mode,
|
||||
change_saved_state, export_backward, export_forward,
|
||||
|
@ -832,7 +839,7 @@ file_save_dialog_save_image (GimpProgress *progress,
|
|||
break;
|
||||
|
||||
case GIMP_PDB_CANCEL:
|
||||
if (verbose_cancel)
|
||||
if (verbose_cancel && progress)
|
||||
gimp_message_literal (gimp,
|
||||
G_OBJECT (progress), GIMP_MESSAGE_INFO,
|
||||
_("Saving canceled"));
|
||||
|
@ -840,15 +847,19 @@ file_save_dialog_save_image (GimpProgress *progress,
|
|||
|
||||
default:
|
||||
{
|
||||
gimp_message (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR,
|
||||
_("Saving '%s' failed:\n\n%s"),
|
||||
gimp_file_get_utf8_name (file),
|
||||
error ? error->message : _("Unknown error"));
|
||||
if (progress)
|
||||
gimp_message (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR,
|
||||
_("Saving '%s' failed:\n\n%s"),
|
||||
gimp_file_get_utf8_name (file),
|
||||
error ? error->message : _("Unknown error"));
|
||||
g_clear_error (&error);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (progress)
|
||||
g_object_remove_weak_pointer (G_OBJECT (progress), (gpointer *) &progress);
|
||||
|
||||
for (list = gimp_action_groups_from_name ("file");
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
|
|
|
@ -770,7 +770,7 @@ gimp_plug_in_close (GimpPlugIn *plug_in,
|
|||
{
|
||||
GimpPlugInProcFrame *proc_frame = plug_in->temp_proc_frames->data;
|
||||
|
||||
#ifdef GIMP_UNSTABLE
|
||||
#ifndef GIMP_RELEASE
|
||||
g_printerr ("plug-in '%s' aborted before sending its "
|
||||
"temporary procedure return values\n",
|
||||
gimp_object_get_name (plug_in));
|
||||
|
@ -792,10 +792,11 @@ gimp_plug_in_close (GimpPlugIn *plug_in,
|
|||
if (plug_in->main_proc_frame.main_loop &&
|
||||
g_main_loop_is_running (plug_in->main_proc_frame.main_loop))
|
||||
{
|
||||
#ifdef GIMP_UNSTABLE
|
||||
g_printerr ("plug-in '%s' aborted before sending its "
|
||||
"procedure return values\n",
|
||||
gimp_object_get_name (plug_in));
|
||||
#ifndef GIMP_RELEASE
|
||||
if (! kill_it)
|
||||
g_printerr ("plug-in '%s' aborted before sending its "
|
||||
"procedure return values\n",
|
||||
gimp_object_get_name (plug_in));
|
||||
#endif
|
||||
|
||||
g_main_loop_quit (plug_in->main_proc_frame.main_loop);
|
||||
|
@ -804,7 +805,7 @@ gimp_plug_in_close (GimpPlugIn *plug_in,
|
|||
if (plug_in->ext_main_loop &&
|
||||
g_main_loop_is_running (plug_in->ext_main_loop))
|
||||
{
|
||||
#ifdef GIMP_UNSTABLE
|
||||
#ifndef GIMP_RELEASE
|
||||
g_printerr ("extension '%s' aborted before sending its "
|
||||
"extension_ack message\n",
|
||||
gimp_object_get_name (plug_in));
|
||||
|
|
Loading…
Reference in New Issue