From f77f772f56d4092bc23dbb5358f5e47652cd8ec7 Mon Sep 17 00:00:00 2001 From: Jehan Date: Thu, 9 Feb 2023 21:50:54 +0100 Subject: [PATCH] Issue #8359: GIMP crashes from "open the font selection dialog" button. Apparently GDK/Win32 sends the "grab-broken-event" signal before the "clicked" signal. This has only been changed since GTK4 so far. Anyway the bottom line is that GimpContainerPopup would process a handled on "clicked", using the object destroyed when "grab-broken-event" happened as callback data. The solution is to make sure that the object stays alive long enough. So I'm changing gimp_editor_add_button() to connect to signals with g_signal_connect_object() (since all usage of this function was used with GObject callback data, it was not a problem). See discussion in !815. As a side change, gimp_container_popup_dialog_clicked() should emit the "cancel", not "confirm". This part was taken from MR !815 by Lloyd Konneker. --- app/tools/gimpgradienttool-editor.c | 6 +++--- app/widgets/gimpcolordisplayeditor.c | 4 ++-- app/widgets/gimpcontainerpopup.c | 8 ++++---- app/widgets/gimpcontrollerlist.c | 6 +++--- app/widgets/gimpdeviceeditor.c | 2 +- app/widgets/gimpdevicestatus.c | 2 +- app/widgets/gimpeditor.c | 29 +++++++++++++++++++++------- app/widgets/gimpeditor.h | 2 +- app/widgets/gimpsettingseditor.c | 6 +++--- app/widgets/gimptooleditor.c | 10 +++++----- app/widgets/gimptooloptionseditor.c | 6 +++--- 11 files changed, 48 insertions(+), 33 deletions(-) diff --git a/app/tools/gimpgradienttool-editor.c b/app/tools/gimpgradienttool-editor.c index 4b17d61d0e..9d19f7c7fc 100644 --- a/app/tools/gimpgradienttool-editor.c +++ b/app/tools/gimpgradienttool-editor.c @@ -1450,7 +1450,7 @@ gimp_gradient_tool_editor_init_stop_gui (GimpGradientTool *gradient_tool) GIMP_ICON_EDIT_DELETE, _("Delete stop"), NULL, G_CALLBACK (gimp_gradient_tool_editor_stop_delete_clicked), - NULL, gradient_tool); + NULL, G_OBJECT (gradient_tool)); } static void @@ -1547,7 +1547,7 @@ gimp_gradient_tool_editor_init_midpoint_gui (GimpGradientTool *gradient_tool) GIMP_ICON_DOCUMENT_NEW, _("New stop at midpoint"), NULL, G_CALLBACK (gimp_gradient_tool_editor_midpoint_new_stop_clicked), - NULL, gradient_tool); + NULL, G_OBJECT (gradient_tool)); /* the center button */ gradient_tool->midpoint_center_button = @@ -1555,7 +1555,7 @@ gimp_gradient_tool_editor_init_midpoint_gui (GimpGradientTool *gradient_tool) GIMP_ICON_CENTER_HORIZONTAL, _("Center midpoint"), NULL, G_CALLBACK (gimp_gradient_tool_editor_midpoint_center_clicked), - NULL, gradient_tool); + NULL, G_OBJECT (gradient_tool)); } static void diff --git a/app/widgets/gimpcolordisplayeditor.c b/app/widgets/gimpcolordisplayeditor.c index f37dbd75ae..7b40c7b1c4 100644 --- a/app/widgets/gimpcolordisplayeditor.c +++ b/app/widgets/gimpcolordisplayeditor.c @@ -231,7 +231,7 @@ gimp_color_display_editor_init (GimpColorDisplayEditor *editor) NULL, G_CALLBACK (gimp_color_display_editor_up_clicked), NULL, - editor); + G_OBJECT (editor)); editor->down_button = gimp_editor_add_button (GIMP_EDITOR (ed), @@ -240,7 +240,7 @@ gimp_color_display_editor_init (GimpColorDisplayEditor *editor) NULL, G_CALLBACK (gimp_color_display_editor_down_clicked), NULL, - editor); + G_OBJECT (editor)); gtk_widget_set_sensitive (editor->up_button, FALSE); gtk_widget_set_sensitive (editor->down_button, FALSE); diff --git a/app/widgets/gimpcontainerpopup.c b/app/widgets/gimpcontainerpopup.c index 0639e5455d..c1647aae3e 100644 --- a/app/widgets/gimpcontainerpopup.c +++ b/app/widgets/gimpcontainerpopup.c @@ -316,12 +316,12 @@ gimp_container_popup_create_view (GimpContainerPopup *popup) _("Smaller Previews"), NULL, G_CALLBACK (gimp_container_popup_smaller_clicked), NULL, - popup); + G_OBJECT (popup)); gimp_editor_add_button (editor, "zoom-in", _("Larger Previews"), NULL, G_CALLBACK (gimp_container_popup_larger_clicked), NULL, - popup); + G_OBJECT (popup)); button = gimp_editor_add_icon_box (editor, GIMP_TYPE_VIEW_TYPE, "gimp", G_CALLBACK (gimp_container_popup_view_type_toggled), @@ -333,7 +333,7 @@ gimp_container_popup_create_view (GimpContainerPopup *popup) popup->dialog_tooltip, NULL, G_CALLBACK (gimp_container_popup_dialog_clicked), NULL, - popup); + G_OBJECT (popup)); gtk_widget_grab_focus (GTK_WIDGET (popup->editor)); @@ -404,7 +404,7 @@ gimp_container_popup_dialog_clicked (GtkWidget *button, popup->dialog_factory, gimp_widget_get_monitor (button), popup->dialog_identifier); - g_signal_emit_by_name (popup, "confirm"); + g_signal_emit_by_name (popup, "cancel"); } static void diff --git a/app/widgets/gimpcontrollerlist.c b/app/widgets/gimpcontrollerlist.c index c327c4027a..5ded6b668b 100644 --- a/app/widgets/gimpcontrollerlist.c +++ b/app/widgets/gimpcontrollerlist.c @@ -295,7 +295,7 @@ gimp_controller_list_init (GimpControllerList *list) NULL, G_CALLBACK (gimp_controller_list_edit_clicked), NULL, - list); + G_OBJECT (list)); list->up_button = gimp_editor_add_button (GIMP_EDITOR (list->dest), GIMP_ICON_GO_UP, @@ -303,7 +303,7 @@ gimp_controller_list_init (GimpControllerList *list) NULL, G_CALLBACK (gimp_controller_list_up_clicked), NULL, - list); + G_OBJECT (list)); list->down_button = gimp_editor_add_button (GIMP_EDITOR (list->dest), GIMP_ICON_GO_DOWN, @@ -311,7 +311,7 @@ gimp_controller_list_init (GimpControllerList *list) NULL, G_CALLBACK (gimp_controller_list_down_clicked), NULL, - list); + G_OBJECT (list)); gtk_widget_set_sensitive (list->edit_button, FALSE); gtk_widget_set_sensitive (list->up_button, FALSE); diff --git a/app/widgets/gimpdeviceeditor.c b/app/widgets/gimpdeviceeditor.c index e3e89e37fc..739518c263 100644 --- a/app/widgets/gimpdeviceeditor.c +++ b/app/widgets/gimpdeviceeditor.c @@ -161,7 +161,7 @@ gimp_device_editor_init (GimpDeviceEditor *editor) NULL, G_CALLBACK (gimp_device_editor_delete_clicked), NULL, - editor); + G_OBJECT (editor)); gtk_widget_set_sensitive (private->delete_button, FALSE); diff --git a/app/widgets/gimpdevicestatus.c b/app/widgets/gimpdevicestatus.c index 7f04c54d82..c873dc1dae 100644 --- a/app/widgets/gimpdevicestatus.c +++ b/app/widgets/gimpdevicestatus.c @@ -153,7 +153,7 @@ gimp_device_status_init (GimpDeviceStatus *status) _("Save device status"), NULL, G_CALLBACK (gimp_device_status_save_clicked), NULL, - status); + G_OBJECT (status)); } static void diff --git a/app/widgets/gimpeditor.c b/app/widgets/gimpeditor.c index 92178d870b..1a56103aed 100644 --- a/app/widgets/gimpeditor.c +++ b/app/widgets/gimpeditor.c @@ -512,6 +512,21 @@ gimp_editor_popup_menu_at_rect (GimpEditor *editor, return FALSE; } +/** + * gimp_editor_add_button: + * @editor: + * @icon_name: + * @tooltip: + * @help_id: + * @callback: + * @extended_callback: + * @callback_data: + * + * Creates a new button, connect @callback to the "clicked" signal and + * @extended_callback to the "extended-clicked" signal. + * The @callback_data has to be a %GObject so that we keep a ref on it and avoid + * bad surprises. + */ GtkWidget * gimp_editor_add_button (GimpEditor *editor, const gchar *icon_name, @@ -519,7 +534,7 @@ gimp_editor_add_button (GimpEditor *editor, const gchar *help_id, GCallback callback, GCallback extended_callback, - gpointer callback_data) + GObject *callback_data) { GtkWidget *button; GtkWidget *image; @@ -540,14 +555,14 @@ gimp_editor_add_button (GimpEditor *editor, gimp_help_set_help_data (button, tooltip, help_id); if (callback) - g_signal_connect (button, "clicked", - callback, - callback_data); + g_signal_connect_object (button, "clicked", + callback, + callback_data, 0); if (extended_callback) - g_signal_connect (button, "extended-clicked", - extended_callback, - callback_data); + g_signal_connect_object (button, "extended-clicked", + extended_callback, + callback_data, 0); image = gtk_image_new_from_icon_name (icon_name, button_icon_size); gtk_container_add (GTK_CONTAINER (button), image); diff --git a/app/widgets/gimpeditor.h b/app/widgets/gimpeditor.h index 1cecb2e5f0..b135a42d9e 100644 --- a/app/widgets/gimpeditor.h +++ b/app/widgets/gimpeditor.h @@ -74,7 +74,7 @@ GtkWidget * gimp_editor_add_button (GimpEditor *editor, const gchar *help_id, GCallback callback, GCallback extended_callback, - gpointer callback_data); + GObject *callback_data); GtkWidget * gimp_editor_add_icon_box (GimpEditor *editor, GType enum_type, const gchar *icon_prefix, diff --git a/app/widgets/gimpsettingseditor.c b/app/widgets/gimpsettingseditor.c index af29f6d488..76946b7f4e 100644 --- a/app/widgets/gimpsettingseditor.c +++ b/app/widgets/gimpsettingseditor.c @@ -193,7 +193,7 @@ gimp_settings_editor_constructed (GObject *object) NULL, G_CALLBACK (gimp_settings_editor_import_clicked), NULL, - editor); + G_OBJECT (editor)); private->export_button = gimp_editor_add_button (GIMP_EDITOR (tree_view), @@ -202,7 +202,7 @@ gimp_settings_editor_constructed (GObject *object) NULL, G_CALLBACK (gimp_settings_editor_export_clicked), NULL, - editor); + G_OBJECT (editor)); private->delete_button = gimp_editor_add_button (GIMP_EDITOR (tree_view), @@ -211,7 +211,7 @@ gimp_settings_editor_constructed (GObject *object) NULL, G_CALLBACK (gimp_settings_editor_delete_clicked), NULL, - editor); + G_OBJECT (editor)); gtk_widget_set_sensitive (private->delete_button, FALSE); } diff --git a/app/widgets/gimptooleditor.c b/app/widgets/gimptooleditor.c index b1cedded16..a79b41b46c 100644 --- a/app/widgets/gimptooleditor.c +++ b/app/widgets/gimptooleditor.c @@ -243,7 +243,7 @@ gimp_tool_editor_constructed (GObject *object) _("Create a new tool group"), NULL, G_CALLBACK (gimp_tool_editor_new_group_clicked), NULL, - tool_editor); + G_OBJECT (tool_editor)); tool_editor->priv->raise_button = gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_GO_UP, @@ -251,7 +251,7 @@ gimp_tool_editor_constructed (GObject *object) _("Raise this item to the top"), G_CALLBACK (gimp_tool_editor_raise_clicked), G_CALLBACK (gimp_tool_editor_raise_extend_clicked), - tool_editor); + G_OBJECT (tool_editor)); tool_editor->priv->lower_button = gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_GO_DOWN, @@ -259,21 +259,21 @@ gimp_tool_editor_constructed (GObject *object) _("Lower this item to the bottom"), G_CALLBACK (gimp_tool_editor_lower_clicked), G_CALLBACK (gimp_tool_editor_lower_extend_clicked), - tool_editor); + G_OBJECT (tool_editor)); tool_editor->priv->delete_button = gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_EDIT_DELETE, _("Delete this tool group"), NULL, G_CALLBACK (gimp_tool_editor_delete_clicked), NULL, - tool_editor); + G_OBJECT (tool_editor)); tool_editor->priv->reset_button = gimp_editor_add_button (GIMP_EDITOR (tool_editor), GIMP_ICON_RESET, _("Reset tool order and visibility"), NULL, G_CALLBACK (gimp_tool_editor_reset_clicked), NULL, - tool_editor); + G_OBJECT (tool_editor)); gimp_tool_editor_update_sensitivity (tool_editor); } diff --git a/app/widgets/gimptooloptionseditor.c b/app/widgets/gimptooloptionseditor.c index 206674e746..d04e7fb045 100644 --- a/app/widgets/gimptooloptionseditor.c +++ b/app/widgets/gimptooloptionseditor.c @@ -196,7 +196,7 @@ gimp_tool_options_editor_constructed (GObject *object) GIMP_HELP_TOOL_OPTIONS_SAVE, G_CALLBACK (gimp_tool_options_editor_save_clicked), NULL, - editor); + G_OBJECT (editor)); editor->p->restore_button = gimp_editor_add_button (GIMP_EDITOR (editor), @@ -205,7 +205,7 @@ gimp_tool_options_editor_constructed (GObject *object) GIMP_HELP_TOOL_OPTIONS_RESTORE, G_CALLBACK (gimp_tool_options_editor_restore_clicked), NULL, - editor); + G_OBJECT (editor)); editor->p->delete_button = gimp_editor_add_button (GIMP_EDITOR (editor), @@ -214,7 +214,7 @@ gimp_tool_options_editor_constructed (GObject *object) GIMP_HELP_TOOL_OPTIONS_DELETE, G_CALLBACK (gimp_tool_options_editor_delete_clicked), NULL, - editor); + G_OBJECT (editor)); editor->p->reset_button = gimp_editor_add_action_button (GIMP_EDITOR (editor), "tool-options",