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)
committerMatthias Clasen <mclasen@redhat.com>
Fri, 21 Apr 2023 07:17:07 +0000 (09:17 +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 8b9fc21a6aabf45d6bebcf1d4c16bcf47daf2d26..b267e2d2390b5e9d909dc963deb49807c4d51bb2 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)