gtk/dialogs: Destroy the window promptly on finish async function
authorMarco Trevisan (Treviño) <mail@3v1n0.net>
Tue, 11 Apr 2023 22:41:20 +0000 (00:41 +0200)
committerMarco Trevisan (Treviño) <mail@3v1n0.net>
Wed, 12 Apr 2023 13:39:39 +0000 (15:39 +0200)
Some bindings (GJS!) could add temporary references to the GAsyncResult
argument that we return, and thus to the GTask, which may cause the
dialog not to close when the finish function is called (but at garbage
collection instead!).

To prevent this, just manually destroy the window (by removing the task
data), so that we are not bound to the GTask lifetime anymore.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5741
gtk/gtkalertdialog.c
gtk/gtkcolordialog.c
gtk/gtkfiledialog.c
gtk/gtkfontdialog.c

index 33ccac37d9b852386c1f85efa25cb6f25d9618c1..efb4ed4a6427f27e61c9fe51a2273400c3b4520f 100644 (file)
@@ -747,6 +747,9 @@ gtk_alert_dialog_choose_finish (GtkAlertDialog  *self,
   g_return_val_if_fail (g_task_is_valid (result, self), -1);
   g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_alert_dialog_choose, -1);
 
+  /* Destroy the dialog window not to be bound to GTask lifecycle */
+  g_task_set_task_data (G_TASK (result), NULL, NULL);
+
   return (int) g_task_propagate_int (G_TASK (result), error);
 }
 
index d93c68ad3f4c99411fb265085706a79d491dc799..a6e69be7e9d1ce92fc3b8c9c3380a4452ba97312 100644 (file)
@@ -492,6 +492,9 @@ gtk_color_dialog_choose_rgba_finish (GtkColorDialog  *self,
   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
   g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_color_dialog_choose_rgba, NULL);
 
+  /* Destroy the dialog window not to be bound to GTask lifecycle */
+  g_task_set_task_data (G_TASK (result), NULL, NULL);
+
   return g_task_propagate_pointer (G_TASK (result), error);
 }
 
index 898650bf9d903c4b002a10004aad19939a90d33b..590b0327792ea5169762c218c64c89eb2ae2fa10 100644 (file)
@@ -976,6 +976,9 @@ gtk_file_dialog_open_finish (GtkFileDialog   *self,
   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
   g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_file_dialog_open, NULL);
 
+  /* Destroy the dialog window not to be bound to GTask lifecycle */
+  g_task_set_task_data (G_TASK (result), NULL, NULL);
+
   return finish_file_op (self, G_TASK (result), error);
 }
 
@@ -1050,6 +1053,9 @@ gtk_file_dialog_select_folder_finish (GtkFileDialog  *self,
   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
   g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_file_dialog_select_folder, NULL);
 
+  /* Destroy the dialog window not to be bound to GTask lifecycle */
+  g_task_set_task_data (G_TASK (result), NULL, NULL);
+
   return finish_file_op (self, G_TASK (result), error);
 }
 
@@ -1120,6 +1126,9 @@ gtk_file_dialog_save_finish (GtkFileDialog   *self,
   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
   g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_file_dialog_save, NULL);
 
+  /* Destroy the dialog window not to be bound to GTask lifecycle */
+  g_task_set_task_data (G_TASK (result), NULL, NULL);
+
   return finish_file_op (self, G_TASK (result), error);
 }
 
@@ -1194,6 +1203,9 @@ gtk_file_dialog_open_multiple_finish (GtkFileDialog   *self,
   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
   g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_file_dialog_open_multiple, NULL);
 
+  /* Destroy the dialog window not to be bound to GTask lifecycle */
+  g_task_set_task_data (G_TASK (result), NULL, NULL);
+
   return finish_multiple_files_op (self, G_TASK (result), error);
 }
 
@@ -1268,6 +1280,9 @@ gtk_file_dialog_select_multiple_folders_finish (GtkFileDialog   *self,
   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
   g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_file_dialog_select_multiple_folders, NULL);
 
+  /* Destroy the dialog window not to be bound to GTask lifecycle */
+  g_task_set_task_data (G_TASK (result), NULL, NULL);
+
   return finish_multiple_files_op (self, G_TASK (result), error);
 }
 
index 878456d94d2eebb5438922284f078f748d68571a..c533dac2cc04ce2850a5e9dfd88bf47e811a313f 100644 (file)
@@ -697,6 +697,9 @@ gtk_font_dialog_choose_family_finish (GtkFontDialog  *self,
   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
   g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_font_dialog_choose_family, NULL);
 
+  /* Destroy the dialog window not to be bound to GTask lifecycle */
+  g_task_set_task_data (G_TASK (result), NULL, NULL);
+
   return g_task_propagate_pointer (G_TASK (result), error);
 }
 
@@ -777,6 +780,9 @@ gtk_font_dialog_choose_face_finish (GtkFontDialog  *self,
   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
   g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_font_dialog_choose_face, NULL);
 
+  /* Destroy the dialog window not to be bound to GTask lifecycle */
+  g_task_set_task_data (G_TASK (result), NULL, NULL);
+
   return g_task_propagate_pointer (G_TASK (result), error);
 }
 
@@ -855,6 +861,9 @@ gtk_font_dialog_choose_font_finish (GtkFontDialog  *self,
   g_return_val_if_fail (g_task_is_valid (result, self), NULL);
   g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_font_dialog_choose_font, NULL);
 
+  /* Destroy the dialog window not to be bound to GTask lifecycle */
+  g_task_set_task_data (G_TASK (result), NULL, NULL);
+
   return g_task_propagate_pointer (G_TASK (result), error);
 }
 
@@ -944,6 +953,8 @@ gtk_font_dialog_choose_font_and_features_finish (GtkFontDialog         *self,
   g_return_val_if_fail (g_task_is_valid (result, self), FALSE);
   g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_font_dialog_choose_font_and_features, FALSE);
 
+  /* Destroy the dialog window not to be bound to GTask lifecycle */
+  g_task_set_task_data (G_TASK (result), NULL, NULL);
   font_result = g_task_propagate_pointer (G_TASK (result), error);
 
   if (font_result)