# HG changeset patch # User Stu Tomlinson # Date 1195419809 0 # Node ID 21cbdaf265f644e6a810bf64a95a452d87b932d4 # Parent b00659aa0acf7f50dac2605890dec598e9ce79ed This fixes the problem where all accounts are disabled due to connection errors, which leaves you with no enabled accounts, and therefore the buddy list flips into "Welcome to Pidgin!" mode, thereby hiding all the connection error mini dialogs. I'm amazed I haven't heard any noise about this problem. I attempted to fix up PidginScrollBook, and got part way there, but gtk_container_get_children now doesn't return any kids. I suspect this is due to the child widgets we care about already being children of the notebook. I don't know nearly enough gtk to be sure if this is good or not. There are still some buglets in how/when the buddy list notebook page is selected, and I have a feeling some of the gtkblist.c changes could be improved, but I believe this is more usable than before. This took far too much time. References #3989 diff -r b00659aa0acf -r 21cbdaf265f6 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Sun Nov 18 17:34:39 2007 +0000 +++ b/pidgin/gtkblist.c Sun Nov 18 21:03:29 2007 +0000 @@ -4226,18 +4226,44 @@ pidgin_blist_sort_method_set(val); } -static void account_modified(PurpleAccount *account, PidginBuddyList *gtkblist) -{ +static gboolean pidgin_blist_select_notebook_page_cb(gpointer user_data) +{ + PidginBuddyList *gtkblist = (PidginBuddyList *)user_data; + int errors = 0; GList *list; - if (!gtkblist) - return; - - if ((list = purple_accounts_get_all_active()) != NULL) { + PidginBuddyListPrivate *priv; + + priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); + + /* this is far too ugly thanks to me not wanting to fix #3989 properly right now */ + if (priv->error_scrollbook != NULL) { +#if GTK_CHECK_VERSION(2,2,0) + errors = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->error_scrollbook->notebook)); +#else + errors = g_list_length(GTK_NOTEBOOK(priv->error_scrollbook->notebook)->children); +#endif + } + if ((list = purple_accounts_get_all_active()) != NULL || errors || + (list = gtk_container_get_children(GTK_CONTAINER(priv->error_scrollbook)))) { gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkblist->notebook), 1); g_list_free(list); } else gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkblist->notebook), 0); + return FALSE; +} + +static void pidgin_blist_select_notebook_page(PidginBuddyList *gtkblist) +{ + purple_timeout_add(0, pidgin_blist_select_notebook_page_cb, gtkblist); +} + +static void account_modified(PurpleAccount *account, PidginBuddyList *gtkblist) +{ + if (!gtkblist) + return; + + pidgin_blist_select_notebook_page(gtkblist); update_menu_bar(gtkblist); } @@ -4248,7 +4274,7 @@ if (!gtkblist) return; - update_menu_bar(gtkblist); + account_modified(account, gtkblist); } static gboolean @@ -4429,8 +4455,10 @@ PurpleAccount *account) { GtkWidget *widget = find_child_widget_by_account(container, account); - if(widget) + if(widget) { + gtk_container_remove(container, widget); gtk_widget_destroy(widget); + } } /* Generic error buttons */ @@ -4438,12 +4466,14 @@ static void generic_error_modify_cb(PurpleAccount *account) { + purple_account_clear_current_error(account); pidgin_account_dialog_show(PIDGIN_MODIFY_ACCOUNT_DIALOG, account); } static void generic_error_enable_cb(PurpleAccount *account) { + purple_account_clear_current_error(account); purple_account_set_enabled(account, purple_core_get_ui(), TRUE); } @@ -4530,7 +4560,7 @@ { PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); remove_child_widget_by_account( - GTK_CONTAINER(priv->error_scrollbook->notebook), account); + GTK_CONTAINER(priv->error_scrollbook), account); } @@ -4712,6 +4742,7 @@ else pidgin_blist_update_account_error_state(account, NULL); + pidgin_blist_select_notebook_page(gtkblist); /* Don't bother updating the error if it hasn't changed. This stops * URGENT being repeatedly set for network errors whenever they try to * reconnect. @@ -4902,7 +4933,6 @@ GtkWidget *sw; GtkWidget *sep; GtkWidget *label; - GList *accounts; char *pretty, *tmp; GtkAccelGroup *accel_group; GtkTreeSelection *selection; @@ -4993,10 +5023,7 @@ gtkblist->vbox = gtk_vbox_new(FALSE, 0); gtk_notebook_append_page(GTK_NOTEBOOK(gtkblist->notebook), gtkblist->vbox, NULL); gtk_widget_show_all(gtkblist->notebook); - if ((accounts = purple_accounts_get_all_active())) { - g_list_free(accounts); - gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkblist->notebook), 1); - } + pidgin_blist_select_notebook_page(gtkblist); ebox = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(gtkblist->vbox), ebox, FALSE, FALSE, 0); diff -r b00659aa0acf -r 21cbdaf265f6 pidgin/gtkscrollbook.c --- a/pidgin/gtkscrollbook.c Sun Nov 18 17:34:39 2007 +0000 +++ b/pidgin/gtkscrollbook.c Sun Nov 18 21:03:29 2007 +0000 @@ -146,21 +146,74 @@ static void pidgin_scroll_book_add(GtkContainer *container, GtkWidget *widget) { + GList *children; + PidginScrollBook *scroll_book; + + g_return_if_fail(GTK_IS_WIDGET (widget)); + g_return_if_fail (widget->parent == NULL); + + scroll_book = PIDGIN_SCROLL_BOOK(container); + children = scroll_book->children; + children = g_list_append(children, widget); gtk_widget_show(widget); gtk_notebook_append_page(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container)->notebook), widget, NULL); page_count_change_cb(PIDGIN_SCROLL_BOOK(container)); } static void +pidgin_scroll_book_remove(GtkContainer *container, GtkWidget *widget) +{ + int page; + GList *children; + GtkWidget *child; + PidginScrollBook *scroll_book; + g_return_if_fail(GTK_IS_WIDGET(widget)); + + scroll_book = PIDGIN_SCROLL_BOOK(container); + children = scroll_book->children; + + while (children) { + child = children->data; + if (child == widget) { + gtk_widget_unparent (widget); + children = g_list_remove_link (scroll_book->children, children); + g_list_free(children); + break; + } + } + + page = gtk_notebook_page_num(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container)->notebook), widget); + if (page >= 0) { + gtk_notebook_remove_page(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container)->notebook), page); + } +} + +static void pidgin_scroll_book_forall(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) { - PidginScrollBook *scroll_book = PIDGIN_SCROLL_BOOK(container); - if (include_internals) + GList *children; + PidginScrollBook *scroll_book; + + g_return_if_fail(GTK_IS_CONTAINER(container)); + + scroll_book = PIDGIN_SCROLL_BOOK(container); + + if (include_internals) { (*callback)(scroll_book->hbox, callback_data); - (*callback)(scroll_book->notebook, callback_data); + (*callback)(scroll_book->notebook, callback_data); + } + + children = scroll_book->children; + + while (children) { + GtkWidget *child; + child = children->data; + children = children->next; + (*callback)(child, callback_data); + } } static void @@ -169,6 +222,7 @@ GtkContainerClass *container_class = (GtkContainerClass*)klass; container_class->add = pidgin_scroll_book_add; + container_class->remove = pidgin_scroll_book_remove; container_class->forall = pidgin_scroll_book_forall; } diff -r b00659aa0acf -r 21cbdaf265f6 pidgin/gtkscrollbook.h --- a/pidgin/gtkscrollbook.h Sun Nov 18 17:34:39 2007 +0000 +++ b/pidgin/gtkscrollbook.h Sun Nov 18 21:03:29 2007 +0000 @@ -29,10 +29,6 @@ #include -#if !GTK_CHECK_VERSION(2,4,0) -#include "pidgincombobox.h" -#endif - G_BEGIN_DECLS #define PIDGIN_TYPE_SCROLL_BOOK (pidgin_scroll_book_get_type ()) @@ -54,9 +50,9 @@ GtkWidget *label; GtkWidget *left_arrow; GtkWidget *right_arrow; + GList *children; /* Padding for future expansion */ - void (*_gtk_reserved0) (void); void (*_gtk_reserved1) (void); void (*_gtk_reserved2) (void); void (*_gtk_reserved3) (void); @@ -66,7 +62,7 @@ struct _PidginScrollBookClass { - GtkComboBoxClass parent_class; + GtkContainerClass parent_class; /* Padding for future expansion */ void (*_gtk_reserved0) (void);