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.
This commit is contained in:
Jehan 2023-02-09 21:50:54 +01:00
parent 9328c9c03c
commit f77f772f56
11 changed files with 48 additions and 33 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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",