Mercurial > pidgin.yaz
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); |