changeset 17620:c1c533448097

sadrul's fix for the userinfo notify crash on disconnect that was caused by the fancy new "Retrieving..." thing. This is version 3 of the fix. This is nosnilmot committing this, with no idea what the --author option to mtn commit actually does. committer: Stu Tomlinson <stu@nosnilmot.com>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Thu, 14 Jun 2007 01:24:16 +0000
parents 727c7a9af52f
children 840862547a63 e0e4fc6e2cc8
files libpurple/notify.c pidgin/gtknotify.c
diffstat 2 files changed, 28 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/notify.c	Wed Jun 13 21:52:37 2007 +0000
+++ b/libpurple/notify.c	Thu Jun 14 01:24:16 2007 +0000
@@ -749,18 +749,16 @@
 void
 purple_notify_close_with_handle(void *handle)
 {
-	GList *l, *l_next;
+	GList *l, *prev = NULL;
 	PurpleNotifyUiOps *ops;
 
 	g_return_if_fail(handle != NULL);
 
 	ops = purple_notify_get_ui_ops();
 
-	for (l = handles; l != NULL; l = l_next) {
+	for (l = handles; l != NULL; l = prev ? prev->next : handles) {
 		PurpleNotifyInfo *info = l->data;
 
-		l_next = l->next;
-
 		if (info->handle == handle) {
 			handles = g_list_remove(handles, info);
 
@@ -771,7 +769,8 @@
 				info->cb(info->cb_user_data);
 
 			g_free(info);
-		}
+		} else
+			prev = l;
 	}
 }
 
--- a/pidgin/gtknotify.c	Wed Jun 13 21:52:37 2007 +0000
+++ b/pidgin/gtknotify.c	Thu Jun 14 01:24:16 2007 +0000
@@ -40,6 +40,12 @@
 
 typedef struct
 {
+	GtkWidget *window;
+	int count;
+} PidginUserInfo;
+
+typedef struct
+{
 	PurpleAccount *account;
 	char *url;
 	GtkWidget *label;
@@ -624,7 +630,7 @@
 	gtk_widget_show(button);
 
 	g_signal_connect_swapped(G_OBJECT(button), "clicked",
-							 G_CALLBACK(formatted_close_cb), window);
+							 G_CALLBACK(gtk_widget_destroy), window);
 	g_signal_connect(G_OBJECT(window), "key_press_event",
 					 G_CALLBACK(formatted_input_cb), NULL);
 
@@ -878,6 +884,11 @@
 static void
 remove_userinfo(GtkWidget *widget, gpointer key)
 {
+	PidginUserInfo *pinfo = g_hash_table_lookup(userinfo, key);
+
+	while (pinfo->count--)
+		purple_notify_close(PURPLE_NOTIFY_USERINFO, widget);
+
 	g_hash_table_remove(userinfo, key);
 }
 
@@ -888,26 +899,33 @@
 	char *info;
 	void *ui_handle;
 	char *key = userinfo_hash(purple_connection_get_account(gc), who);
+	PidginUserInfo *pinfo = NULL;
 
 	if (!userinfo) {
-		userinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+		userinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 	}
 
 	info = purple_notify_user_info_get_text_with_newline(user_info, "<br />");
-	ui_handle = g_hash_table_lookup(userinfo, key);
-	if (ui_handle != NULL) {
-		GtkIMHtml *imhtml = g_object_get_data(G_OBJECT(ui_handle), "info-widget");
+	pinfo = g_hash_table_lookup(userinfo, key);
+	if (pinfo != NULL) {
+		GtkIMHtml *imhtml = g_object_get_data(G_OBJECT(pinfo->window), "info-widget");
 		char *linked_text = purple_markup_linkify(info);
 		gtk_imhtml_clear(imhtml);
 		gtk_imhtml_append_text(imhtml, linked_text, notify_imhtml_options());
 		g_free(linked_text);
 		g_free(key);
+		ui_handle = pinfo->window;
+		pinfo->count++;
 	} else {
 		char *primary = g_strdup_printf(_("Info for %s"), who);
 		ui_handle = pidgin_notify_formatted(_("Buddy Information"), primary, NULL, info);
-		g_hash_table_insert(userinfo, key, ui_handle);
+		g_signal_handlers_disconnect_by_func(G_OBJECT(ui_handle), G_CALLBACK(formatted_close_cb), NULL);
 		g_signal_connect(G_OBJECT(ui_handle), "destroy", G_CALLBACK(remove_userinfo), key);
 		g_free(primary);
+		pinfo = g_new0(PidginUserInfo, 1);
+		pinfo->window = ui_handle;
+		pinfo->count = 1;
+		g_hash_table_insert(userinfo, key, pinfo);
 	}
 	g_free(info);
 	return ui_handle;