libgimp, plug-ins: add a "parent-handle" argument to the metadata-editor.

This handle is one of the opaque window handles as returned by
gimp_dialog_get_native_handle() or gimp_progress_get_window_handle() and
therefore it works even across processes. Now any export procedure using
the GimpExportProcedureDialog will call "plug-in-metadata-editor" as a
transient window of itself when clicking the "Metadata (edit)" button.
In particular, the Metadata editor won't be hidden by mistake when
appearing or similar issues.

Nevertheless it only works for systems where we have a transient window
implementation (so far, only X11 and Wayland, since the Windows
implementation is currently commented out because of #10229, and we have
no macOS implementation).

Note though that setting destroy-with-parent doesn't work, most likely
because the GimpExportProcedureDialog is still waiting for the Metadata
editor procedure to return (commit 54d01b5a0b), otherwise we end up with
a bad state in GIMP Protocol.
A proper solution to this will likely be to create a temp procedure from
metadata-editor to request it to close from another plug-in.
This commit is contained in:
Jehan 2024-08-31 01:44:47 +02:00
parent 9b5463b5c5
commit 03398391e4
2 changed files with 27 additions and 8 deletions

View File

@ -356,15 +356,18 @@ gimp_export_procedure_dialog_edit_metadata_thread (gpointer data)
{
GimpExportProcedureDialog *dialog = data;
GimpProcedure *procedure;
GBytes *dialog_handle;
g_mutex_lock (&dialog->metadata_thread_mutex);
dialog->metadata_thread_running = TRUE;
g_mutex_unlock (&dialog->metadata_thread_mutex);
procedure = gimp_pdb_lookup_procedure (gimp_get_pdb (), "plug-in-metadata-editor");
procedure = gimp_pdb_lookup_procedure (gimp_get_pdb (), "plug-in-metadata-editor");
dialog_handle = gimp_dialog_get_native_handle (GIMP_DIALOG (dialog));
gimp_procedure_run (procedure,
"run-mode", GIMP_RUN_INTERACTIVE,
"image", dialog->image,
"run-mode", GIMP_RUN_INTERACTIVE,
"image", dialog->image,
"parent-handle", dialog_handle,
NULL);
g_mutex_lock (&dialog->metadata_thread_mutex);

View File

@ -133,6 +133,7 @@ static void metadata_editor_create_tree_grid (const me_column_info *tree_inf
static gboolean metadata_editor_dialog (GimpImage *image,
GimpMetadata *metadata,
GimpProcedureConfig *config,
GError **error);
static void metadata_dialog_editor_set_metadata (GExiv2Metadata *metadata,
@ -768,6 +769,11 @@ metadata_create_procedure (GimpPlugIn *plug_in,
"Ben Touchette",
"Ben Touchette",
"2017");
gimp_procedure_add_bytes_argument (procedure, "parent-handle",
_("Parent's window handle"),
_("The opaque handle of the window to set this plug-in's dialog transient to"),
G_PARAM_READWRITE | GIMP_PARAM_DONT_SERIALIZE);
}
return procedure;
@ -800,7 +806,7 @@ metadata_run (GimpProcedure *procedure,
gimp_image_set_metadata (image, metadata);
}
if (metadata_editor_dialog (image, metadata, &error))
if (metadata_editor_dialog (image, metadata, config, &error))
return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
else
return gimp_procedure_new_return_values (procedure, GIMP_PDB_EXECUTION_ERROR, error);
@ -1140,9 +1146,10 @@ metadata_editor_create_tree_grid (const me_column_info *tree_info,
}
static gboolean
metadata_editor_dialog (GimpImage *image,
GimpMetadata *g_metadata,
GError **error)
metadata_editor_dialog (GimpImage *image,
GimpMetadata *g_metadata,
GimpProcedureConfig *config,
GError **error)
{
GExiv2Metadata *metadata;
GtkWidget *dialog;
@ -1154,9 +1161,12 @@ metadata_editor_dialog (GimpImage *image,
GtkWidget *grid;
GtkWidget *widget;
GtkListStore *store;
GBytes *parent_handle = NULL;
gchar *title;
gchar *name;
g_object_get (config, "parent-handle", &parent_handle, NULL);
metadata = GEXIV2_METADATA (g_metadata);
meta_args.image = image;
@ -1189,7 +1199,13 @@ metadata_editor_dialog (GimpImage *image,
GTK_RESPONSE_CANCEL,
-1);
gimp_window_set_transient (GTK_WINDOW (dialog));
if (parent_handle && g_bytes_get_size (parent_handle) != 0)
gimp_window_set_transient_for (GTK_WINDOW (dialog), parent_handle);
else
gimp_window_set_transient (GTK_WINDOW (dialog));
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
g_bytes_unref (parent_handle);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));