comparison pidgin/gtkroomlist.c @ 23651:e97ff340bbf3

Fix a race related to closing the roomlist window and do some minor cleanup. The relevant changes are in delete_win_cb(). Fixes #6134
author Daniel Atallah <daniel.atallah@gmail.com>
date Tue, 29 Jul 2008 03:40:47 +0000
parents 1690d040addd
children c1f954e51389
comparison
equal deleted inserted replaced
23650:d1d32f318ce9 23651:e97ff340bbf3
51 51
52 PurpleAccount *account; 52 PurpleAccount *account;
53 PurpleRoomlist *roomlist; 53 PurpleRoomlist *roomlist;
54 54
55 gboolean pg_needs_pulse; 55 gboolean pg_needs_pulse;
56 gboolean pg_to_active;
57 guint pg_update_to; 56 guint pg_update_to;
58 } PidginRoomlistDialog; 57 } PidginRoomlistDialog;
59 58
60 typedef struct _PidginRoomlist { 59 typedef struct _PidginRoomlist {
61 PidginRoomlistDialog *dialog; 60 PidginRoomlistDialog *dialog;
82 81
83 static GList *roomlists = NULL; 82 static GList *roomlists = NULL;
84 83
85 static gint delete_win_cb(GtkWidget *w, GdkEventAny *e, gpointer d) 84 static gint delete_win_cb(GtkWidget *w, GdkEventAny *e, gpointer d)
86 { 85 {
87 PidginRoomlistDialog *dialog; 86 PidginRoomlistDialog *dialog = d;
88
89 dialog = (PidginRoomlistDialog *) d;
90 87
91 if (dialog->roomlist && purple_roomlist_get_in_progress(dialog->roomlist)) 88 if (dialog->roomlist && purple_roomlist_get_in_progress(dialog->roomlist))
92 purple_roomlist_cancel_get_list(dialog->roomlist); 89 purple_roomlist_cancel_get_list(dialog->roomlist);
93 90
91 if (dialog->pg_update_to > 0)
92 purple_timeout_remove(dialog->pg_update_to);
93
94 if (dialog->roomlist) { 94 if (dialog->roomlist) {
95 if (dialog->pg_to_active) { 95 PidginRoomlist *rl = dialog->roomlist->ui_data;
96 purple_timeout_remove(dialog->pg_update_to); 96
97 dialog->pg_to_active = FALSE; 97 if (dialog->pg_update_to > 0)
98 /* yes, that's right, unref it twice. */ 98 /* yes, that's right, unref it twice. */
99 purple_roomlist_unref(dialog->roomlist); 99 purple_roomlist_unref(dialog->roomlist);
100 } 100
101 } 101 if (rl)
102 102 rl->dialog = NULL;
103 /* free stuff here */
104 if (dialog->roomlist)
105 purple_roomlist_unref(dialog->roomlist); 103 purple_roomlist_unref(dialog->roomlist);
104 }
105
106 dialog->progress = NULL;
106 g_free(dialog); 107 g_free(dialog);
107 108
108 return FALSE; 109 return FALSE;
109 } 110 }
110 111
111 static void dialog_select_account_cb(GObject *w, PurpleAccount *account, 112 static void dialog_select_account_cb(GObject *w, PurpleAccount *account,
112 PidginRoomlistDialog *dialog) 113 PidginRoomlistDialog *dialog)
113 { 114 {
114 dialog->account = account; 115 dialog->account = account;
115 } 116 }
116 117
117 static void list_button_cb(GtkButton *button, PidginRoomlistDialog *dialog) 118 static void list_button_cb(GtkButton *button, PidginRoomlistDialog *dialog)
184 selection_changed_cb(GtkTreeSelection *selection, PidginRoomlist *grl) { 185 selection_changed_cb(GtkTreeSelection *selection, PidginRoomlist *grl) {
185 GtkTreeIter iter; 186 GtkTreeIter iter;
186 GValue val; 187 GValue val;
187 PurpleRoomlistRoom *room; 188 PurpleRoomlistRoom *room;
188 static struct _menu_cb_info *info; 189 static struct _menu_cb_info *info;
189 PidginRoomlistDialog *dialog; 190 PidginRoomlistDialog *dialog = grl->dialog;
190
191 dialog = grl->dialog;
192 191
193 if (gtk_tree_selection_get_selected(selection, NULL, &iter)) { 192 if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
194 val.g_type = 0; 193 val.g_type = 0;
195 gtk_tree_model_get_value(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val); 194 gtk_tree_model_get_value(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
196 room = g_value_get_pointer(&val); 195 room = g_value_get_pointer(&val);
237 236
238 static void add_room_to_blist_cb(GtkButton *button, PidginRoomlistDialog *dialog) 237 static void add_room_to_blist_cb(GtkButton *button, PidginRoomlistDialog *dialog)
239 { 238 {
240 PurpleRoomlist *rl = dialog->roomlist; 239 PurpleRoomlist *rl = dialog->roomlist;
241 PidginRoomlist *grl = rl->ui_data; 240 PidginRoomlist *grl = rl->ui_data;
242 struct _menu_cb_info *info; 241 struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "room-info");
243
244 info = (struct _menu_cb_info*)g_object_get_data(G_OBJECT(button), "room-info");
245 242
246 if(info != NULL) 243 if(info != NULL)
247 do_add_room_cb(grl->tree, info); 244 do_add_room_cb(grl->tree, info);
248 } 245 }
249 246
254 251
255 static void join_button_cb(GtkButton *button, PidginRoomlistDialog *dialog) 252 static void join_button_cb(GtkButton *button, PidginRoomlistDialog *dialog)
256 { 253 {
257 PurpleRoomlist *rl = dialog->roomlist; 254 PurpleRoomlist *rl = dialog->roomlist;
258 PidginRoomlist *grl = rl->ui_data; 255 PidginRoomlist *grl = rl->ui_data;
259 struct _menu_cb_info *info; 256 struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "room-info");
260
261 info = (struct _menu_cb_info*)g_object_get_data(G_OBJECT(button), "room-info");
262 257
263 if(info != NULL) 258 if(info != NULL)
264 do_join_cb(grl->tree, info); 259 do_join_cb(grl->tree, info);
265 } 260 }
266 261
488 return TRUE; 483 return TRUE;
489 } 484 }
490 485
491 static gboolean account_filter_func(PurpleAccount *account) 486 static gboolean account_filter_func(PurpleAccount *account)
492 { 487 {
493 PurpleConnection *gc = purple_account_get_connection(account); 488 PurpleConnection *conn = purple_account_get_connection(account);
494 PurplePluginProtocolInfo *prpl_info = NULL; 489 PurplePluginProtocolInfo *prpl_info = NULL;
495 490
496 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); 491 if (conn)
497 492 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(conn->prpl);
498 return (prpl_info->roomlist_get_list != NULL); 493
494 return (prpl_info && prpl_info->roomlist_get_list != NULL);
499 } 495 }
500 496
501 gboolean 497 gboolean
502 pidgin_roomlist_is_showable() 498 pidgin_roomlist_is_showable()
503 { 499 {
516 512
517 static PidginRoomlistDialog * 513 static PidginRoomlistDialog *
518 pidgin_roomlist_dialog_new_with_account(PurpleAccount *account) 514 pidgin_roomlist_dialog_new_with_account(PurpleAccount *account)
519 { 515 {
520 PidginRoomlistDialog *dialog; 516 PidginRoomlistDialog *dialog;
521 GtkWidget *window; 517 GtkWidget *window, *vbox, *vbox2, *bbox;
522 GtkWidget *vbox;
523 GtkWidget *vbox2;
524 GtkWidget *bbox;
525 518
526 dialog = g_new0(PidginRoomlistDialog, 1); 519 dialog = g_new0(PidginRoomlistDialog, 1);
527 dialog->account = account; 520 dialog->account = account;
528 521
529 /* Create the window. */ 522 /* Create the window. */
609 return dialog; 602 return dialog;
610 } 603 }
611 604
612 void pidgin_roomlist_dialog_show_with_account(PurpleAccount *account) 605 void pidgin_roomlist_dialog_show_with_account(PurpleAccount *account)
613 { 606 {
614 PidginRoomlistDialog *dialog; 607 PidginRoomlistDialog *dialog = pidgin_roomlist_dialog_new_with_account(account);
615 608
616 dialog = pidgin_roomlist_dialog_new_with_account(account);
617 if (!dialog) 609 if (!dialog)
618 return; 610 return;
619 611
620 list_button_cb(GTK_BUTTON(dialog->list_button), dialog); 612 list_button_cb(GTK_BUTTON(dialog->list_button), dialog);
621 } 613 }
625 pidgin_roomlist_dialog_new_with_account(NULL); 617 pidgin_roomlist_dialog_new_with_account(NULL);
626 } 618 }
627 619
628 static void pidgin_roomlist_new(PurpleRoomlist *list) 620 static void pidgin_roomlist_new(PurpleRoomlist *list)
629 { 621 {
630 PidginRoomlist *rl; 622 PidginRoomlist *rl = g_new0(PidginRoomlist, 1);
631
632 rl = g_new0(PidginRoomlist, 1);
633 623
634 list->ui_data = rl; 624 list->ui_data = rl;
635 625
636 rl->cats = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)gtk_tree_row_reference_free); 626 rl->cats = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)gtk_tree_row_reference_free);
637 627
800 PurpleRoomlist *list = data; 790 PurpleRoomlist *list = data;
801 PidginRoomlist *rl = list->ui_data; 791 PidginRoomlist *rl = list->ui_data;
802 792
803 if (!rl || !rl->dialog || !rl->dialog->pg_needs_pulse) { 793 if (!rl || !rl->dialog || !rl->dialog->pg_needs_pulse) {
804 if (rl && rl->dialog) 794 if (rl && rl->dialog)
805 rl->dialog->pg_to_active = FALSE; 795 rl->dialog->pg_update_to = 0;
806 purple_roomlist_unref(list); 796 purple_roomlist_unref(list);
807 return FALSE; 797 return FALSE;
808 } 798 }
809 799
810 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(rl->dialog->progress)); 800 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(rl->dialog->progress));
825 rl->total_rooms++; 815 rl->total_rooms++;
826 if (room->type == PURPLE_ROOMLIST_ROOMTYPE_ROOM) 816 if (room->type == PURPLE_ROOMLIST_ROOMTYPE_ROOM)
827 rl->num_rooms++; 817 rl->num_rooms++;
828 818
829 if (rl->dialog) { 819 if (rl->dialog) {
830 if (!rl->dialog->pg_to_active) { 820 if (rl->dialog->pg_update_to == 0) {
831 rl->dialog->pg_to_active = TRUE;
832 purple_roomlist_ref(list); 821 purple_roomlist_ref(list);
833 rl->dialog->pg_update_to = g_timeout_add(100, pidgin_progress_bar_pulse, list); 822 rl->dialog->pg_update_to = g_timeout_add(100, pidgin_progress_bar_pulse, list);
834 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(rl->dialog->progress)); 823 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(rl->dialog->progress));
835 } else { 824 } else
836 rl->dialog->pg_needs_pulse = TRUE; 825 rl->dialog->pg_needs_pulse = TRUE;
837 } 826 }
838 } 827
839 if (room->parent) { 828 if (room->parent) {
840 parentrr = g_hash_table_lookup(rl->cats, room->parent); 829 parentrr = g_hash_table_lookup(rl->cats, room->parent);
841 path = gtk_tree_row_reference_get_path(parentrr); 830 path = gtk_tree_row_reference_get_path(parentrr);
842 if (path) { 831 if (path) {
843 PurpleRoomlistRoom *tmproom = NULL; 832 PurpleRoomlistRoom *tmproom = NULL;
879 continue; 868 continue;
880 gtk_tree_store_set(rl->model, &iter, j, l->data, -1); 869 gtk_tree_store_set(rl->model, &iter, j, l->data, -1);
881 } 870 }
882 } 871 }
883 872
884 static void pidgin_roomlist_in_progress(PurpleRoomlist *list, gboolean flag) 873 static void pidgin_roomlist_in_progress(PurpleRoomlist *list, gboolean in_progress)
885 { 874 {
886 PidginRoomlist *rl = list->ui_data; 875 PidginRoomlist *rl = list->ui_data;
887 876
888 if (!rl || !rl->dialog) 877 if (!rl || !rl->dialog)
889 return; 878 return;
890 879
891 if (flag) { 880 if (in_progress) {
892 if (rl->dialog->account_widget) 881 if (rl->dialog->account_widget)
893 gtk_widget_set_sensitive(rl->dialog->account_widget, FALSE); 882 gtk_widget_set_sensitive(rl->dialog->account_widget, FALSE);
894 gtk_widget_set_sensitive(rl->dialog->stop_button, TRUE); 883 gtk_widget_set_sensitive(rl->dialog->stop_button, TRUE);
895 gtk_widget_set_sensitive(rl->dialog->list_button, FALSE); 884 gtk_widget_set_sensitive(rl->dialog->list_button, FALSE);
896 } else { 885 } else {
903 } 892 }
904 } 893 }
905 894
906 static void pidgin_roomlist_destroy(PurpleRoomlist *list) 895 static void pidgin_roomlist_destroy(PurpleRoomlist *list)
907 { 896 {
908 PidginRoomlist *rl; 897 PidginRoomlist *rl = list->ui_data;
909 898
910 roomlists = g_list_remove(roomlists, list); 899 roomlists = g_list_remove(roomlists, list);
911
912 rl = list->ui_data;
913 900
914 g_return_if_fail(rl != NULL); 901 g_return_if_fail(rl != NULL);
915 902
916 g_hash_table_destroy(rl->cats); 903 g_hash_table_destroy(rl->cats);
917 g_free(rl); 904 g_free(rl);