comparison src/buddy.c @ 3251:b3c7af7286de

[gaim-migrate @ 3269] Squashed bug that caused Gaim crashes when r-click buddy menu was used with accelerator keys struck multiple times, or accelerator keys in combination with a mouse click, on prpl menu selections. Also eliminated memory leaks resulting from the way pop-up menus are used. committer: Tailor Script <tailor@pidgin.im>
author Jim Seymour <jseymour>
date Wed, 15 May 2002 02:26:03 +0000
parents 20769d05df16
children 66445abf1736
comparison
equal deleted inserted replaced
3250:0970eabdd8df 3251:b3c7af7286de
608 } 608 }
609 609
610 static void menu_click(GtkObject *obj, char *who) 610 static void menu_click(GtkObject *obj, char *who)
611 { 611 {
612 GList *list = gtk_object_get_user_data(obj); 612 GList *list = gtk_object_get_user_data(obj);
613 GList *first = g_list_first(list);
614 struct proto_buddy_menu *pbm = list->data; 613 struct proto_buddy_menu *pbm = list->data;
615 if (pbm->callback) 614 if (pbm->callback)
616 pbm->callback(pbm->gc, who); 615 pbm->callback(pbm->gc, who);
617 g_list_foreach(first, (GFunc)g_free, NULL);
618 g_list_free(first);
619 } 616 }
620 617
621 static int handle_click_buddy(GtkWidget *widget, GdkEventButton *event, struct buddy_show *b) 618 static int handle_click_buddy(GtkWidget *widget, GdkEventButton *event, struct buddy_show *b)
622 { 619 {
623 if (!b->connlist) 620 if (!b->connlist)
634 631
635 set_convo_gc(c, b->connlist->data); 632 set_convo_gc(c, b->connlist->data);
636 if (im_options & OPT_IM_ONE_WINDOW) 633 if (im_options & OPT_IM_ONE_WINDOW)
637 raise_convo_tab(c); 634 raise_convo_tab(c);
638 } else if (event->type == GDK_BUTTON_PRESS && event->button == 3) { 635 } else if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
639 GtkWidget *menu; 636 static GtkWidget *menu = NULL;
637 static GList *mo_top = NULL;
640 GtkWidget *button; 638 GtkWidget *button;
641 GtkWidget *menuitem; 639 GtkWidget *menuitem;
642 GtkWidget *conmenu; 640 GtkWidget *conmenu;
643 GSList *cn = b->connlist; 641 GSList *cn = b->connlist;
644 struct gaim_connection *g; 642 struct gaim_connection *g;
645 /* We're gonna make us a menu right here */ 643 /* We're gonna make us a menu right here */
646 644
645 /*
646 * If a menu already exists, destroy it before creating a new one,
647 * thus freeing-up the memory it occupied. Same for its associated
648 * (prpl menu items) GList.
649 */
650 if(menu) {
651 gtk_widget_destroy(menu);
652 if(mo_top) {
653 g_list_foreach(mo_top, (GFunc)g_free, NULL);
654 g_list_free(mo_top);
655 mo_top = NULL;
656 }
657 }
658
647 menu = gtk_menu_new(); 659 menu = gtk_menu_new();
648 660
649 button = gtk_menu_item_new_with_label(_("IM")); 661 button = gtk_menu_item_new_with_label(_("IM"));
650 gtk_signal_connect(GTK_OBJECT(button), "activate", GTK_SIGNAL_FUNC(pressed_im), b); 662 gtk_signal_connect(GTK_OBJECT(button), "activate", GTK_SIGNAL_FUNC(pressed_im), b);
651 gtk_menu_append(GTK_MENU(menu), button); 663 gtk_menu_append(GTK_MENU(menu), button);
671 683
672 if (g_slist_length(cn) > 1) { 684 if (g_slist_length(cn) > 1) {
673 while (cn) { 685 while (cn) {
674 g = (struct gaim_connection *)cn->data; 686 g = (struct gaim_connection *)cn->data;
675 if (g->prpl->buddy_menu) { 687 if (g->prpl->buddy_menu) {
676 GList *mo = g->prpl->buddy_menu(g, b->name); 688 GList *mo = mo_top = g->prpl->buddy_menu(g, b->name);
677 689
678 menuitem = gtk_menu_item_new_with_label(g->username); 690 menuitem = gtk_menu_item_new_with_label(g->username);
679 gtk_menu_append(GTK_MENU(menu), menuitem); 691 gtk_menu_append(GTK_MENU(menu), menuitem);
680 gtk_widget_show(menuitem); 692 gtk_widget_show(menuitem);
681 693
700 cn = g_slist_next(cn); 712 cn = g_slist_next(cn);
701 } 713 }
702 } else { 714 } else {
703 g = (struct gaim_connection *)cn->data; 715 g = (struct gaim_connection *)cn->data;
704 if (g->prpl->buddy_menu) { 716 if (g->prpl->buddy_menu) {
705 GList *mo = g->prpl->buddy_menu(g, b->name); 717 GList *mo = mo_top = g->prpl->buddy_menu(g, b->name);
706 718
707 while (mo) { 719 while (mo) {
708 struct proto_buddy_menu *pbm = mo->data; 720 struct proto_buddy_menu *pbm = mo->data;
709 GtkWidget *button; 721 GtkWidget *button;
710 722
770 static gboolean click_edit_tree(GtkWidget *widget, GdkEventButton *event, gpointer data) 782 static gboolean click_edit_tree(GtkWidget *widget, GdkEventButton *event, gpointer data)
771 { 783 {
772 GtkCTreeNode *node; 784 GtkCTreeNode *node;
773 int *type; 785 int *type;
774 int row, column; 786 int row, column;
775 GtkWidget *menu; 787 static GtkWidget *menu = NULL;
776 GtkWidget *button; 788 GtkWidget *button;
777 789
778 if (event->button != 3 || event->type != GDK_BUTTON_PRESS) 790 if (event->button != 3 || event->type != GDK_BUTTON_PRESS)
779 return FALSE; 791 return FALSE;
780 792
781 if (!gtk_clist_get_selection_info(GTK_CLIST(edittree), event->x, event->y, &row, &column)) 793 if (!gtk_clist_get_selection_info(GTK_CLIST(edittree), event->x, event->y, &row, &column))
782 return FALSE; 794 return FALSE;
783 795
784 node = gtk_ctree_node_nth(GTK_CTREE(edittree), row); 796 node = gtk_ctree_node_nth(GTK_CTREE(edittree), row);
785 type = gtk_ctree_node_get_row_data(GTK_CTREE(edittree), node); 797 type = gtk_ctree_node_get_row_data(GTK_CTREE(edittree), node);
798
799 /*
800 * If a menu already exists, destroy it before creating a new one,
801 * thus freeing-up the memory it occupied.
802 */
803 if(menu) {
804 gtk_widget_destroy(menu);
805 menu = NULL; /* safety measure */
806 }
807
786 if (*type == EDIT_GROUP) { 808 if (*type == EDIT_GROUP) {
787 struct group *group = (struct group *)type; 809 struct group *group = (struct group *)type;
788 menu = gtk_menu_new(); 810 menu = gtk_menu_new();
789 811
790 button = gtk_menu_item_new_with_label(_("Rename")); 812 button = gtk_menu_item_new_with_label(_("Rename"));
1505 } 1527 }
1506 1528
1507 static void away_callback(GtkWidget *widget, GtkTree *tree) 1529 static void away_callback(GtkWidget *widget, GtkTree *tree)
1508 { 1530 {
1509 GSList *awy = away_messages; 1531 GSList *awy = away_messages;
1510 GtkWidget *menu; 1532 static GtkWidget *menu = NULL;
1511 GtkWidget *menuitem; 1533 GtkWidget *menuitem;
1512 1534
1513 if (!awy) 1535 if (!awy)
1514 return; 1536 return;
1537
1538 /*
1539 * If a menu already exists, destroy it before creating a new one,
1540 * thus freeing-up the memory it occupied.
1541 */
1542 if(menu)
1543 gtk_widget_destroy(menu);
1515 1544
1516 menu = gtk_menu_new(); 1545 menu = gtk_menu_new();
1517 1546
1518 while (awy) { 1547 while (awy) {
1519 struct away_message *a = awy->data; 1548 struct away_message *a = awy->data;