Mercurial > pidgin
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; |