changeset 21519:5123f25788f2

Don't crash when someone ignores an error. The mini-dialog was being gtk_widget_destroy()ed twice.
author Will Thompson <will.thompson@collabora.co.uk>
date Thu, 15 Nov 2007 12:30:51 +0000
parents dde2859a3225
children f3e3c604ea0e
files pidgin/minidialog.c
diffstat 1 files changed, 14 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/minidialog.c	Wed Nov 14 18:47:24 2007 +0000
+++ b/pidgin/minidialog.c	Thu Nov 15 12:30:51 2007 +0000
@@ -53,6 +53,8 @@
 	GtkLabel *title;
 	GtkLabel *desc;
 	GtkBox *buttons;
+
+	guint idle_destroy_cb_id;
 } PidginMiniDialogPrivate;
 
 #define PIDGIN_MINI_DIALOG_GET_PRIVATE(dialog) \
@@ -118,10 +120,18 @@
                               gpointer user_data)
 {
 	struct _mini_dialog_button_clicked_cb_data *data = user_data;
+	PidginMiniDialogPrivate *priv =
+		PIDGIN_MINI_DIALOG_GET_PRIVATE(data->mini_dialog);
+
+	/* Set up the destruction callback before calling the clicked callback,
+	 * so that if the mini-dialog gets destroyed during the clicked callback
+	 * the idle_destroy_cb is correctly removed by _finalize.
+	 */
+	priv->idle_destroy_cb_id =
+		g_idle_add((GSourceFunc) idle_destroy_cb, data->mini_dialog);
 
 	data->callback(data->mini_dialog, button, data->user_data);
 
-	g_idle_add((GSourceFunc) idle_destroy_cb, data->mini_dialog);
 }
 
 static void
@@ -272,6 +282,9 @@
 	PidginMiniDialog *self = PIDGIN_MINI_DIALOG(object);
 	PidginMiniDialogPrivate *priv = PIDGIN_MINI_DIALOG_GET_PRIVATE(self);
 
+	if (priv->idle_destroy_cb_id)
+		g_source_remove(priv->idle_destroy_cb_id);
+
 	g_free(priv);
 	self->priv = NULL;