diff -r 0c5e17e46226 -r 51c9575bbdd2 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Sat Sep 28 05:54:50 2019 -0400 +++ b/pidgin/gtkconv.c Sun Sep 29 00:58:53 2019 -0400 @@ -2236,30 +2236,31 @@ custom_icon_sel_cb(const char *filename, gpointer data) { if (filename) { - const gchar *name; - PurpleBuddy *buddy; - PurpleContact *contact; - PidginConversation *gtkconv = data; - PurpleConversation *conv = gtkconv->active_conv; - PurpleAccount *account = purple_conversation_get_account(conv); - - name = purple_conversation_get_name(conv); - buddy = purple_blist_find_buddy(account, name); - if (!buddy) { - purple_debug_info("custom-icon", "You can only set custom icons for people on your buddylist.\n"); - return; - } - contact = purple_buddy_get_contact(buddy); + PurpleContact *contact = data; purple_buddy_icons_node_set_custom_icon_from_file((PurpleBlistNode*)contact, filename); } -} - -static void -set_custom_icon_cb(GtkWidget *widget, PidginConversation *gtkconv) -{ - GtkWidget *win = pidgin_buddy_icon_chooser_new(GTK_WINDOW(gtkconv->win->window), - custom_icon_sel_cb, gtkconv); + g_object_set_data(G_OBJECT(data), "buddy-icon-chooser", NULL); +} + +static void +set_custom_icon_cb(GtkWidget *widget, PurpleContact *contact) +{ + GtkWidget *win = NULL; + + /* Should not happen as menu item should be disabled. */ + g_return_if_fail(contact != NULL); + + win = g_object_get_data(G_OBJECT(contact), "buddy-icon-chooser"); + if (win == NULL) { + GtkMenu *menu = GTK_MENU(gtk_widget_get_parent(widget)); + GtkWidget *toplevel = + gtk_widget_get_toplevel(gtk_menu_get_attach_widget(menu)); + win = pidgin_buddy_icon_chooser_new(GTK_WINDOW(toplevel), + custom_icon_sel_cb, contact); + g_object_set_data_full(G_OBJECT(contact), "buddy-icon-chooser", win, + (GDestroyNotify)gtk_widget_destroy); + } gtk_widget_show_all(win); } @@ -2355,7 +2356,8 @@ static gboolean icon_menu(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv) { - static GtkWidget *menu = NULL; + GtkWidget *menu = NULL; + GList *old_menus = NULL; PurpleConversation *conv; PurpleBuddy *buddy; @@ -2372,10 +2374,14 @@ * If a menu already exists, destroy it before creating a new one, * thus freeing-up the memory it occupied. */ - if (menu != NULL) + while ((old_menus = gtk_menu_get_for_attach_widget(widget)) != NULL) { + menu = old_menus->data; + gtk_menu_detach(GTK_MENU(menu)); gtk_widget_destroy(menu); + } menu = gtk_menu_new(); + gtk_menu_attach_to_widget(GTK_MENU(menu), widget, NULL); if (gtkconv->u.im->anim && !(gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim))) @@ -2385,22 +2391,31 @@ gtkconv->u.im->icon_timer); } + conv = gtkconv->active_conv; + buddy = purple_blist_find_buddy(purple_conversation_get_account(conv), + purple_conversation_get_name(conv)); + pidgin_new_menu_item(menu, _("Hide Icon"), NULL, G_CALLBACK(remove_icon), gtkconv); pidgin_new_menu_item(menu, _("Save Icon As..."), GTK_STOCK_SAVE_AS, G_CALLBACK(icon_menu_save_cb), gtkconv); - pidgin_new_menu_item(menu, _("Set Custom Icon..."), NULL, - G_CALLBACK(set_custom_icon_cb), gtkconv); + if (buddy) { + PurpleContact *contact = purple_buddy_get_contact(buddy); + pidgin_new_menu_item(menu, _("Set Custom Icon..."), NULL, + G_CALLBACK(set_custom_icon_cb), contact); + } else { + GtkWidget *item = + pidgin_new_menu_item(menu, _("Set Custom Icon..."), NULL, + G_CALLBACK(set_custom_icon_cb), NULL); + gtk_widget_set_sensitive(item, FALSE); + } pidgin_new_menu_item(menu, _("Change Size"), NULL, G_CALLBACK(change_size_cb), gtkconv); /* Is there a custom icon for this person? */ - conv = gtkconv->active_conv; - buddy = purple_blist_find_buddy(purple_conversation_get_account(conv), - purple_conversation_get_name(conv)); if (buddy) { PurpleContact *contact = purple_buddy_get_contact(buddy);