changeset 26993:b18c6ab86e67

merge of '8641e216dc398048158e7424b56603087551b65f' and '8e62c013fdc6cdef291861b7633287b97df472a2'
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Tue, 19 May 2009 03:48:18 +0000
parents cda10ae89918 (current diff) 9ffd12823dc1 (diff)
children ed5aec1cff44
files ChangeLog libpurple/protocols/yahoo/yahoo_auth.c libpurple/protocols/yahoo/yahoo_auth.h libpurple/protocols/yahoo/yahoo_crypt.c libpurple/protocols/yahoo/yahoo_crypt.h pidgin/gtkconv.c
diffstat 8 files changed, 127 insertions(+), 335 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue May 19 01:06:56 2009 +0000
+++ b/ChangeLog	Tue May 19 03:48:18 2009 +0000
@@ -14,6 +14,8 @@
 	libpurple:
 	* Various memory cleanups when unloading libpurple. (Nick Hebner)
 	* Report idle time 'From last message sent' should work properly.
+	* Show the invite message for buddies that requested authorization
+	  from you on MSN.
 
 	XMPP:
 	* Voice & Video support with Jingle (XEP-0166, 0167, 0176, & 0177), and
--- a/libpurple/protocols/msn/contact.c	Tue May 19 01:06:56 2009 +0000
+++ b/libpurple/protocols/msn/contact.c	Tue May 19 03:48:18 2009 +0000
@@ -357,29 +357,36 @@
 	MsnUser *user = msn_userlist_find_add_user(session->userlist, passport, NULL);
 	xmlnode *annotation;
 	guint nid = MSN_NETWORK_UNKNOWN;
+	char *invite = NULL;
 
-	/* For EmailMembers, the network must be found in the annotations. */
-	if (!strcmp(node, "PassportName")) {
+	for (annotation = xmlnode_get_child(member, "Annotations/Annotation");
+	     annotation;
+	     annotation = xmlnode_get_next_twin(annotation)) {
+		char *name = xmlnode_get_data(xmlnode_get_child(annotation, "Name"));
+		char *value = xmlnode_get_data(xmlnode_get_child(annotation, "Value"));
+		if (name && value) {
+			if (!strcmp(name, "MSN.IM.BuddyType")) {
+				nid = strtoul(value, NULL, 10);
+			}
+			else if (!strcmp(name, "MSN.IM.InviteMessage")) {
+				invite = value;
+				value = NULL;
+			}
+		}
+		g_free(name);
+		g_free(value);
+	}
+
+	/* For EmailMembers, the network must be found in the annotations, above.
+	   Otherwise, PassportMembers are on the Passport network. */
+	if (!strcmp(node, "PassportName"))
 		nid = MSN_NETWORK_PASSPORT;
-	} else {
-		for (annotation = xmlnode_get_child(member, "Annotations/Annotation");
-		     annotation;
-		     annotation = xmlnode_get_next_twin(annotation)) {
-			char *name = xmlnode_get_data(xmlnode_get_child(annotation, "Name"));
-			if (name && !strcmp(name, "MSN.IM.BuddyType")) {
-				char *value = xmlnode_get_data(xmlnode_get_child(annotation, "Value"));
-				if (value != NULL)
-					nid = strtoul(value, NULL, 10);
-				g_free(value);
-			}
-			g_free(name);
-		}
-	}
 
 	purple_debug_info("msn", "CL: %s name: %s, Type: %s, MembershipID: %s, NetworkID: %u\n",
 		node, passport, type, member_id == NULL ? "(null)" : member_id, nid);
 
 	msn_user_set_network(user, nid);
+	msn_user_set_invite_message(user, invite);
 
 	if (member_id) {
 		user->membership_id[list] = atoi(member_id);
@@ -390,6 +397,7 @@
 	g_free(passport);
 	g_free(type);
 	g_free(member_id);
+	g_free(invite);
 }
 
 static void
@@ -717,8 +725,6 @@
 					g_free(msnEnabled);
 				}
 			}
-			if (passport == NULL) /* Couldn't find anything */
-				continue;
 		} else {
 			xmlnode *messenger_user;
 			/* ignore non-messenger contacts */
@@ -736,6 +742,7 @@
 			passport = xmlnode_get_data(passportName);
 		}
 
+		/* Couldn't find anything */
 		if (passport == NULL)
 			continue;
 
--- a/libpurple/protocols/msn/notification.c	Tue May 19 01:06:56 2009 +0000
+++ b/libpurple/protocols/msn/notification.c	Tue May 19 03:48:18 2009 +0000
@@ -149,48 +149,6 @@
 }
 
 /**************************************************************************
- * Util
- **************************************************************************/
-
-static void
-group_error_helper(MsnSession *session, const char *msg, const char *group_id, int error)
-{
-	PurpleAccount *account;
-	PurpleConnection *gc;
-	char *reason = NULL;
-	char *title = NULL;
-
-	account = session->account;
-	gc = purple_account_get_connection(account);
-
-	if (error == 224)
-	{
-		if (group_id == 0)
-		{
-			return;
-		}
-		else
-		{
-			const char *group_name;
-			group_name = msn_userlist_find_group_name(session->userlist,group_id);
-			reason = g_strdup_printf(_("%s is not a valid group."),
-									 group_name ? group_name : "");
-		}
-	}
-	else
-	{
-		reason = g_strdup(_("Unknown error."));
-	}
-
-	title = g_strdup_printf(_("%s on %s (%s)"), msg,
-						  purple_account_get_username(account),
-						  purple_account_get_protocol_name(account));
-	purple_notify_error(gc, NULL, title, reason);
-	g_free(title);
-	g_free(reason);
-}
-
-/**************************************************************************
  * Login
  **************************************************************************/
 
@@ -1102,38 +1060,6 @@
 }
 
 static void
-adg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
-	MsnSession *session;
-	gint group_id;
-	const char *group_name;
-
-	session = cmdproc->session;
-
-	group_id = atoi(cmd->params[3]);
-
-	group_name = purple_url_decode(cmd->params[2]);
-
-	msn_group_new(session->userlist, cmd->params[3], group_name);
-
-	/* There is a user that must be moved to this group */
-	if (cmd->trans->data)
-	{
-		/* msn_userlist_move_buddy(); */
-		MsnUserList *userlist = cmdproc->session->userlist;
-		MsnCallbackState *data = cmd->trans->data;
-
-		if (data->old_group_name != NULL)
-		{
-			msn_userlist_move_buddy(userlist, data->who, data->old_group_name, group_name);
-			g_free(data->old_group_name);
-		} else {
-			/* msn_add_contact_to_group(userlist, data, data->who, group_name); */
-		}
-	}
-}
-
-static void
 qng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
 	/* TODO: Call PNG after the timeout specified. */
@@ -1468,61 +1394,6 @@
 	}
 }
 
-static void
-reg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
-	MsnSession *session;
-	const char *group_id, *group_name;
-
-	session = cmdproc->session;
-	group_id = cmd->params[2];
-	group_name = purple_url_decode(cmd->params[3]);
-
-	msn_userlist_rename_group_id(session->userlist, group_id, group_name);
-}
-
-static void
-reg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
-	const char * group_id;
-	char **params;
-
-	params = g_strsplit(trans->params, " ", 0);
-
-	group_id = params[0];
-
-	group_error_helper(cmdproc->session, _("Unable to rename group"), group_id, error);
-
-	g_strfreev(params);
-}
-
-static void
-rmg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
-	MsnSession *session;
-	const char *group_id;
-
-	session = cmdproc->session;
-	group_id = cmd->params[2];
-
-	msn_userlist_remove_group_id(session->userlist, group_id);
-}
-
-static void
-rmg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
-	const char *group_id;
-	char **params;
-
-	params = g_strsplit(trans->params, " ", 0);
-
-	group_id = params[0];
-
-	group_error_helper(cmdproc->session, _("Unable to delete group"), group_id, error);
-
-	g_strfreev(params);
-}
-
 /**************************************************************************
  * Misc commands
  **************************************************************************/
@@ -2149,9 +2020,6 @@
 	msn_table_add_cmd(cbs_table, "VER", "VER", ver_cmd);
 	msn_table_add_cmd(cbs_table, "PRP", "PRP", prp_cmd);
 	msn_table_add_cmd(cbs_table, "BLP", "BLP", blp_cmd);
-	msn_table_add_cmd(cbs_table, "REG", "REG", reg_cmd);
-	msn_table_add_cmd(cbs_table, "ADG", "ADG", adg_cmd);
-	msn_table_add_cmd(cbs_table, "RMG", "RMG", rmg_cmd);
 	msn_table_add_cmd(cbs_table, "XFR", "XFR", xfr_cmd);
 
 	/* Asynchronous */
@@ -2187,8 +2055,6 @@
 	msn_table_add_error(cbs_table, "ADD", add_error);
 	msn_table_add_error(cbs_table, "ADL", adl_error);
 	msn_table_add_error(cbs_table, "FQY", fqy_error);
-	msn_table_add_error(cbs_table, "REG", reg_error);
-	msn_table_add_error(cbs_table, "RMG", rmg_error);
 	msn_table_add_error(cbs_table, "USR", usr_error);
 
 	msn_table_add_msg_type(cbs_table,
--- a/libpurple/protocols/msn/user.c	Tue May 19 01:06:56 2009 +0000
+++ b/libpurple/protocols/msn/user.c	Tue May 19 03:48:18 2009 +0000
@@ -74,6 +74,7 @@
 	g_free(user->media.title);
 	g_free(user->media.album);
 	g_free(user->statusline);
+	g_free(user->invite_message);
 
 	g_free(user);
 }
@@ -426,6 +427,15 @@
 	user->clientcaps = info;
 }
 
+void
+msn_user_set_invite_message(MsnUser *user, const char *message)
+{
+	g_return_if_fail(user != NULL);
+
+	g_free(user->invite_message);
+	user->invite_message = g_strdup(message);
+}
+
 const char *
 msn_user_get_passport(const MsnUser *user)
 {
@@ -489,3 +499,12 @@
 
 	return user->clientcaps;
 }
+
+const char *
+msn_user_get_invite_message(const MsnUser *user)
+{
+	g_return_val_if_fail(user != NULL, NULL);
+
+	return user->invite_message;
+}
+
--- a/libpurple/protocols/msn/user.h	Tue May 19 01:06:56 2009 +0000
+++ b/libpurple/protocols/msn/user.h	Tue May 19 03:48:18 2009 +0000
@@ -105,6 +105,8 @@
 
 	guint membership_id[5];	/**< The membershipId sent by the contacts server,
 				     indexed by the list it belongs to		*/
+
+	char *invite_message;   /**< Invite message of user request */
 };
 
 /**************************************************************************
@@ -290,6 +292,14 @@
  */
 void msn_user_set_client_caps(MsnUser *user, GHashTable *info);
 
+/**
+ * Sets the invite message for a user.
+ *
+ * @param user    The user.
+ * @param message The invite message for a user.
+ */
+void msn_user_set_invite_message(MsnUser *user, const char *message);
+
 
 /**
  * Returns the passport account for a user.
@@ -373,6 +383,15 @@
 GHashTable *msn_user_get_client_caps(const MsnUser *user);
 
 /**
+ * Returns the invite message for a user.
+ *
+ * @param user The user.
+ *
+ * @return The user's invite message.
+ */
+const char *msn_user_get_invite_message(const MsnUser *user);
+
+/**
  * check to see if user is online
  */
 gboolean
--- a/libpurple/protocols/msn/userlist.c	Tue May 19 01:06:56 2009 +0000
+++ b/libpurple/protocols/msn/userlist.c	Tue May 19 03:48:18 2009 +0000
@@ -86,7 +86,7 @@
 }
 
 static void
-got_new_entry(PurpleConnection *gc, const char *passport, const char *friendly)
+got_new_entry(PurpleConnection *gc, const char *passport, const char *friendly, const char *message)
 {
 	PurpleAccount *acct;
 	MsnPermitAdd *pa;
@@ -97,7 +97,7 @@
 	pa->gc = gc;
 
 	acct = purple_connection_get_account(gc);
-	purple_account_request_authorization(acct, passport, NULL, friendly, NULL,
+	purple_account_request_authorization(acct, passport, NULL, friendly, message,
 										 purple_find_buddy(acct, passport) != NULL,
 										 msn_accept_add_cb, msn_cancel_add_cb, pa);
 
@@ -142,155 +142,6 @@
  * Server functions
  **************************************************************************/
 
-MsnListId
-msn_get_list_id(const char *list)
-{
-	if (list[0] == 'F')
-		return MSN_LIST_FL;
-	else if (list[0] == 'A')
-		return MSN_LIST_AL;
-	else if (list[0] == 'B')
-		return MSN_LIST_BL;
-	else if (list[0] == 'R')
-		return MSN_LIST_RL;
-
-	return -1;
-}
-
-/* this function msn_got_add_user isn't called anywhere */
-void
-msn_got_add_user(MsnSession *session, MsnUser *user,
-				 MsnListId list_id, const char * group_id)
-{
-	PurpleAccount *account;
-	const char *passport;
-	const char *friendly;
-
-	purple_debug_info("msn", "got add user...\n");
-	account = session->account;
-
-	passport = msn_user_get_passport(user);
-	friendly = msn_user_get_friendly_name(user);
-
-	if (list_id == MSN_LIST_FL)
-	{
-		PurpleConnection *gc;
-
-		gc = purple_account_get_connection(account);
-
-		serv_got_alias(gc, passport, friendly);
-
-		if (group_id != NULL)
-		{
-			msn_user_add_group_id(user, group_id);
-		}
-	}
-	else if (list_id == MSN_LIST_AL)
-	{
-		purple_privacy_permit_add(account, passport, TRUE);
-	}
-	else if (list_id == MSN_LIST_BL)
-	{
-		purple_privacy_deny_add(account, passport, TRUE);
-	}
-	else if (list_id == MSN_LIST_RL)
-	{
-		PurpleConversation *convo;
-
-		purple_debug_info("msn",
-						"%s has added you to his or her buddy list.\n",
-						passport);
-
- 		convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, passport, account);
- 		if (convo) {
- 			PurpleBuddy *buddy;
- 			char *msg;
-
- 			buddy = purple_find_buddy(account, passport);
- 			msg = g_strdup_printf(
- 				_("%s has added you to his or her buddy list."),
- 				buddy ? purple_buddy_get_contact_alias(buddy) : passport);
- 			purple_conv_im_write(PURPLE_CONV_IM(convo), passport, msg,
- 				PURPLE_MESSAGE_SYSTEM, time(NULL));
- 			g_free(msg);
- 		}
-
-		if (!(user->list_op & (MSN_LIST_AL_OP | MSN_LIST_BL_OP)))
-		{
-			/*
-			 * TODO: The friendly name was NULL for me when I
-			 *       looked at this.  Maybe we should use the store
-			 *       name instead? --KingAnt
-			 */
-/*			got_new_entry(gc, passport, friendly); */
-		}
-	}
-
-	user->list_op |= (1 << list_id);
-	/* purple_user_add_list_id (user, list_id); */
-}
-
-void
-msn_got_rem_user(MsnSession *session, MsnUser *user,
-				 MsnListId list_id, const char * group_id)
-{
-	PurpleAccount *account;
-	const char *passport;
-
-	account = session->account;
-
-	passport = msn_user_get_passport(user);
-
-	if (list_id == MSN_LIST_FL)
-	{
-		/* TODO: When is the user totally removed? */
-		if (group_id != NULL)
-		{
-			msn_user_remove_group_id(user, group_id);
-			return;
-		}
-	}
-	else if (list_id == MSN_LIST_AL)
-	{
-		purple_privacy_permit_remove(account, passport, TRUE);
-	}
-	else if (list_id == MSN_LIST_BL)
-	{
-		purple_privacy_deny_remove(account, passport, TRUE);
-	}
-	else if (list_id == MSN_LIST_RL)
-	{
-		PurpleConversation *convo;
-
-		purple_debug_info("msn",
-						"%s has removed you from his or her buddy list.\n",
-						passport);
-
-		convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, passport, account);
-		if (convo) {
-			PurpleBuddy *buddy;
-			char *msg;
-
-			buddy = purple_find_buddy(account, passport);
-			msg = g_strdup_printf(
-				_("%s has removed you from his or her buddy list."),
-				buddy ? purple_buddy_get_contact_alias(buddy) : passport);
-			purple_conv_im_write(PURPLE_CONV_IM(convo), passport, msg,
-				PURPLE_MESSAGE_SYSTEM, time(NULL));
-			g_free(msg);
-		}
-	}
-
-	user->list_op &= ~(1 << list_id);
-	/* purple_user_remove_list_id (user, list_id); */
-
-	if (user->list_op == 0)
-	{
-		purple_debug_info("msn", "Buddy '%s' shall be deleted?.\n",
-						passport);
-	}
-}
-
 void
 msn_got_lst_user(MsnSession *session, MsnUser *user,
 				 int list_op, GSList *group_ids)
@@ -299,12 +150,14 @@
 	PurpleAccount *account;
 	const char *passport;
 	const char *store;
+	const char *message;
 
 	account = session->account;
 	gc = purple_account_get_connection(account);
 
 	passport = msn_user_get_passport(user);
 	store = msn_user_get_friendly_name(user);
+	message = msn_user_get_invite_message(user);
 
 	msn_user_set_op(user, list_op);
 
@@ -348,13 +201,13 @@
 
 		if (!(list_op & (MSN_LIST_AL_OP | MSN_LIST_BL_OP)))
 		{
-/*			got_new_entry(gc, passport, store); */
+/*			got_new_entry(gc, passport, store, NULL); */
 		}
 	}
 
 	if (list_op & MSN_LIST_PL_OP)
 	{
-		got_new_entry(gc, passport, store);
+		got_new_entry(gc, passport, store, message);
 	}
 }
 
--- a/libpurple/protocols/msn/userlist.h	Tue May 19 01:06:56 2009 +0000
+++ b/libpurple/protocols/msn/userlist.h	Tue May 19 03:48:18 2009 +0000
@@ -57,12 +57,7 @@
 
 gboolean msn_userlist_user_is_in_group(MsnUser *user, const char * group_id);
 gboolean msn_userlist_user_is_in_list(MsnUser *user, MsnListId list_id);
-MsnListId msn_get_list_id(const char *list);
 
-void msn_got_add_user(MsnSession *session, MsnUser *user,
-					  MsnListId list_id, const char *group_id);
-void msn_got_rem_user(MsnSession *session, MsnUser *user,
-					  MsnListId list_id, const char *group_id);
 void msn_got_lst_user(MsnSession *session, MsnUser *user,
 					  int list_op, GSList *group_ids);
 
--- a/pidgin/gtkconv.c	Tue May 19 01:06:56 2009 +0000
+++ b/pidgin/gtkconv.c	Tue May 19 03:48:18 2009 +0000
@@ -2700,7 +2700,7 @@
 	scale_width = gdk_pixbuf_get_width(buf);
 	scale_height = gdk_pixbuf_get_height(buf);
 
-	gtk_widget_get_size_request(gtkconv->infopane_hbox, NULL, &size);
+	gtk_widget_get_size_request(gtkconv->u.im->icon_container, NULL, &size);
 	size = MIN(size, MIN(scale_width, scale_height));
 	size = CLAMP(size, BUDDYICON_SIZE_MIN, BUDDYICON_SIZE_MAX);
 
@@ -2758,13 +2758,22 @@
 static void
 remove_icon(GtkWidget *widget, PidginConversation *gtkconv)
 {
+	GList *children;
+	GtkWidget *event;
 	PurpleConversation *conv = gtkconv->active_conv;
 	PidginWindow *gtkwin;
 
 	g_return_if_fail(conv != NULL);
 
-	if (gtkconv->u.im->icon_container != NULL)
-		gtk_widget_destroy(gtkconv->u.im->icon_container);
+	gtk_widget_set_size_request(gtkconv->u.im->icon_container, -1, BUDDYICON_SIZE_MIN);
+	children = gtk_container_get_children(GTK_CONTAINER(gtkconv->u.im->icon_container));
+	if (children) {
+		/* We know there's only one child here. It'd be nice to shortcut to the
+		   event box, but we can't change the PidginConversation until 3.0 */
+		event = (GtkWidget *)children->data;
+		gtk_container_remove(GTK_CONTAINER(gtkconv->u.im->icon_container), event);
+		g_list_free(children);
+	}
 
 	if (gtkconv->u.im->anim != NULL)
 		g_object_unref(G_OBJECT(gtkconv->u.im->anim));
@@ -2779,7 +2788,6 @@
 	gtkconv->u.im->icon = NULL;
 	gtkconv->u.im->anim = NULL;
 	gtkconv->u.im->iter = NULL;
-	gtkconv->u.im->icon_container = NULL;
 	gtkconv->u.im->show_icon = FALSE;
 
 	gtkwin = gtkconv->win;
@@ -2840,7 +2848,7 @@
 	PurpleConversation *conv = gtkconv->active_conv;
 	GSList *buddies;
 
-	gtk_widget_get_size_request(gtkconv->infopane_hbox, NULL, &size);
+	gtk_widget_get_size_request(gtkconv->u.im->icon_container, NULL, &size);
 
 	if (size == BUDDYICON_SIZE_MAX) {
 		size = BUDDYICON_SIZE_MIN;
@@ -2848,7 +2856,7 @@
 		size = BUDDYICON_SIZE_MAX;
 	}
 
-	gtk_widget_set_size_request(gtkconv->infopane_hbox, -1, size);
+	gtk_widget_set_size_request(gtkconv->u.im->icon_container, -1, size);
 	pidgin_conv_update_buddy_icon(conv);
 
 	buddies = purple_find_buddies(purple_conversation_get_account(conv),
@@ -4629,6 +4637,7 @@
 		gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
 		gtkchat->topic_text = gtk_entry_new();
+		gtk_widget_set_size_request(gtkchat->topic_text, -1, BUDDYICON_SIZE_MIN);
 
 		if(prpl_info->set_chat_topic == NULL) {
 			gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE);
@@ -4847,15 +4856,37 @@
 	gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(gtkconv->infopane), path);
 	gtk_tree_path_free(path);
 
-	if ((buddy = purple_find_buddy(purple_conversation_get_account(conv),
-					purple_conversation_get_name(conv))) != NULL) {
-		PurpleContact *contact = purple_buddy_get_contact(buddy);
-		if (contact) {
-			buddyicon_size = purple_blist_node_get_int((PurpleBlistNode*)contact, "pidgin-infopane-iconsize");
-		}
-	}
-	buddyicon_size = CLAMP(buddyicon_size, BUDDYICON_SIZE_MIN, BUDDYICON_SIZE_MAX);
-	gtk_widget_set_size_request(gtkconv->infopane_hbox, -1, buddyicon_size);
+	if (chat) {
+		/* This empty widget is used to ensure that the infopane is consistently
+		   sized for chat windows. The correct fix is to put an icon in the chat
+		   window as well, because that would make "Set Custom Icon" consistent
+		   for both the buddy list and the chat window, but PidginConversation
+		   is pretty much stuck until 3.0. */
+		GtkWidget *sizing_vbox;
+		sizing_vbox = gtk_vbox_new(FALSE, 0);
+		gtk_widget_set_size_request(sizing_vbox, -1, BUDDYICON_SIZE_MIN);
+		gtk_box_pack_start(GTK_BOX(gtkconv->infopane_hbox), sizing_vbox, FALSE, FALSE, 0);
+		gtk_widget_show(sizing_vbox);
+	}
+	else {
+		gtkconv->u.im->icon_container = gtk_vbox_new(FALSE, 0);
+
+		if ((buddy = purple_find_buddy(purple_conversation_get_account(conv),
+						purple_conversation_get_name(conv))) != NULL) {
+			PurpleContact *contact = purple_buddy_get_contact(buddy);
+			if (contact) {
+				buddyicon_size = purple_blist_node_get_int((PurpleBlistNode*)contact, "pidgin-infopane-iconsize");
+			}
+		}
+		buddyicon_size = CLAMP(buddyicon_size, BUDDYICON_SIZE_MIN, BUDDYICON_SIZE_MAX);
+		gtk_widget_set_size_request(gtkconv->u.im->icon_container, -1, buddyicon_size);
+
+		gtk_box_pack_start(GTK_BOX(gtkconv->infopane_hbox),
+				   gtkconv->u.im->icon_container, FALSE, FALSE, 0);
+
+		gtk_widget_show(gtkconv->u.im->icon_container);
+	}
+
 	gtk_widget_show(gtkconv->infopane);
 
 	rend = gtk_cell_renderer_pixbuf_new();
@@ -6909,6 +6940,7 @@
 
 	GdkPixbuf *buf;
 
+	GList *children;
 	GtkWidget *event;
 	GdkPixbuf *scale;
 	int scale_width, scale_height;
@@ -6936,9 +6968,14 @@
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
 
 	/* Remove the current icon stuff */
-	if (gtkconv->u.im->icon_container != NULL)
-		gtk_widget_destroy(gtkconv->u.im->icon_container);
-	gtkconv->u.im->icon_container = NULL;
+	children = gtk_container_get_children(GTK_CONTAINER(gtkconv->u.im->icon_container));
+	if (children) {
+		/* We know there's only one child here. It'd be nice to shortcut to the
+		   event box, but we can't change the PidginConversation until 3.0 */
+		event = (GtkWidget *)children->data;
+		gtk_container_remove(GTK_CONTAINER(gtkconv->u.im->icon_container), event);
+		g_list_free(children);
+	}
 
 	if (gtkconv->u.im->anim != NULL)
 		g_object_unref(G_OBJECT(gtkconv->u.im->anim));
@@ -7026,7 +7063,7 @@
 	scale_width = gdk_pixbuf_get_width(buf);
 	scale_height = gdk_pixbuf_get_height(buf);
 
-	gtk_widget_get_size_request(gtkconv->infopane_hbox, NULL, &size);
+	gtk_widget_get_size_request(gtkconv->u.im->icon_container, NULL, &size);
 	size = MIN(size, MIN(scale_width, scale_height));
 
 	/* Some sanity checks */
@@ -7045,7 +7082,6 @@
 	g_object_unref(buf);
 	if (pidgin_gdk_pixbuf_is_opaque(scale))
 		pidgin_gdk_pixbuf_make_round(scale);
-	gtkconv->u.im->icon_container = gtk_vbox_new(FALSE, 0);
 
 	event = gtk_event_box_new();
 	gtk_container_add(GTK_CONTAINER(gtkconv->u.im->icon_container), event);
@@ -7066,11 +7102,6 @@
 
 	g_object_unref(G_OBJECT(scale));
 
-	gtk_box_pack_start(GTK_BOX(gtkconv->infopane_hbox),
-			   gtkconv->u.im->icon_container, FALSE, FALSE, 0);
-
-	gtk_widget_show(gtkconv->u.im->icon_container);
-
 	/* The buddy icon code needs badly to be fixed. */
 	if(pidgin_conv_window_is_active_conversation(conv))
 	{