--- a/libpurple/account.c Tue Jul 05 02:03:30 2022 -0500
+++ b/libpurple/account.c Wed Jul 06 05:47:52 2022 -0500
@@ -1112,6 +1112,8 @@
g_return_if_fail(PURPLE_IS_ACCOUNT(account));
+ purple_account_clear_current_error(account); username = purple_account_get_username(account);
if (!purple_account_get_enabled(account)) {
--- a/libpurple/accounts.c Tue Jul 05 02:03:30 2022 -0500
+++ b/libpurple/accounts.c Wed Jul 06 05:47:52 2022 -0500
@@ -637,7 +637,6 @@
PurpleAccount *account = purple_connection_get_account(gc);
- purple_account_clear_current_error(account);
purple_signal_emit(purple_accounts_get_handle(), "account-signed-on",
--- a/pidgin/gtkblist.c Tue Jul 05 02:03:30 2022 -0500
+++ b/pidgin/gtkblist.c Wed Jul 06 05:47:52 2022 -0500
@@ -97,16 +97,6 @@
/* GBoxed reference count */
- /* Used to hold error minidialogs. Gets packed
- * inside PidginBuddyList.error_buttons
- PidginScrollBook *error_scrollbook;
- /* Pointer to the mini-dialog about having signed on elsewhere, if one
- * is showing; %NULL otherwise.
- PidginMiniDialog *signed_on_elsewhere;
guint select_notebook_page_timeout;
@@ -3097,453 +3087,6 @@
pidgin_blist_sort_method_set(val);
-/***********************************/
-/* Connection error handling stuff */
-/***********************************/
-#define OBJECT_DATA_KEY_ACCOUNT "account"
-#define DO_NOT_CLEAR_ERROR "do-not-clear-error"
-find_account_widget(GObject *widget,
- PurpleAccount *account)
- if (g_object_get_data(widget, OBJECT_DATA_KEY_ACCOUNT) == account)
-pack_protocol_icon_start(GtkWidget *box,
- PurpleAccount *account)
- pixbuf = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_SMALL);
- image = gtk_image_new_from_pixbuf(pixbuf);
- g_object_unref(pixbuf);
- gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0);
-add_error_dialog(PidginBuddyList *gtkblist,
- PidginBuddyListPrivate *priv =
- pidgin_buddy_list_get_instance_private(gtkblist);
- gtk_container_add(GTK_CONTAINER(priv->error_scrollbook), dialog);
-find_child_widget_by_account(GtkContainer *container,
- PurpleAccount *account)
- GList *children = NULL;
- /* XXX: Workaround for the currently incomplete implementation of PidginScrollBook */
- if(PIDGIN_IS_SCROLL_BOOK(container)) {
- PidginScrollBook *scroll_book = PIDGIN_SCROLL_BOOK(container);
- GtkWidget *notebook = pidgin_scroll_book_get_notebook(scroll_book);
- container = GTK_CONTAINER(notebook);
- children = gtk_container_get_children(container);
- l = g_list_find_custom(children, account, (GCompareFunc) find_account_widget);
- ret = GTK_WIDGET(l->data);
-remove_child_widget_by_account(GtkContainer *container,
- PurpleAccount *account)
- GtkWidget *widget = find_child_widget_by_account(container, account);
- /* Since we are destroying the widget in response to a change in
- * error, we should not clear the error.
- g_object_set_data(G_OBJECT(widget), DO_NOT_CLEAR_ERROR,
- GINT_TO_POINTER(TRUE));
- gtk_widget_destroy(widget);
-/* Generic error buttons */
-generic_account_connect_cb(G_GNUC_UNUSED PidginMiniDialog *mini_dialog,
- G_GNUC_UNUSED GtkButton *button,
- PurpleAccount *account = user_data;
- purple_account_connect(account);
-generic_error_modify_cb(G_GNUC_UNUSED PidginMiniDialog *mini_dialog,
- G_GNUC_UNUSED GtkButton *button,
- PurpleAccount *account = user_data;
- purple_account_clear_current_error(account);
- pidgin_account_dialog_show(PIDGIN_MODIFY_ACCOUNT_DIALOG, account);
-generic_error_enable_cb(G_GNUC_UNUSED PidginMiniDialog *mini_dialog,
- G_GNUC_UNUSED GtkButton *button,
- PurpleAccount *account = user_data;
- purple_account_clear_current_error(account);
- purple_account_set_enabled(account, TRUE);
-generic_error_destroy_cb(GtkWidget *dialog,
- PurpleAccount *account)
- /* If the error dialog is being destroyed in response to the
- * account-error-changed signal, we don't want to clear the current
- if (g_object_get_data(G_OBJECT(dialog), DO_NOT_CLEAR_ERROR) == NULL)
- purple_account_clear_current_error(account);
-#define SSL_FAQ_URI "https://developer.pidgin.im/wiki/FAQssl"
-ssl_faq_clicked_cb(PidginMiniDialog *mini_dialog,
- purple_notify_uri(NULL, SSL_FAQ_URI);
-add_generic_error_dialog(PurpleAccount *account,
- const PurpleConnectionErrorInfo *err)
- GtkWidget *mini_dialog;
- const char *username = purple_account_get_username(account);
- gboolean enabled = purple_account_get_enabled(account);
- primary = g_strdup_printf(_("%s disconnected"), username);
- primary = g_strdup_printf(_("%s disabled"), username);
- mini_dialog = pidgin_mini_dialog_new_with_buttons(
- primary, err->description, "dialog-error", account,
- enabled ? _("Reconnect") : _("Re-enable"),
- enabled ? generic_account_connect_cb : generic_error_enable_cb,
- _("Modify Account"), generic_error_modify_cb,
- g_object_set_data(G_OBJECT(mini_dialog), OBJECT_DATA_KEY_ACCOUNT,
- if(err->type == PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT)
- pidgin_mini_dialog_add_non_closing_button(PIDGIN_MINI_DIALOG(mini_dialog),
- _("SSL FAQs"), ssl_faq_clicked_cb, NULL);
- g_signal_connect_after(mini_dialog, "destroy",
- (GCallback)generic_error_destroy_cb,
- add_error_dialog(gtkblist, mini_dialog);
-remove_generic_error_dialog(PurpleAccount *account)
- PidginBuddyListPrivate *priv =
- pidgin_buddy_list_get_instance_private(gtkblist);
- remove_child_widget_by_account(
- GTK_CONTAINER(priv->error_scrollbook), account);
-update_generic_error_message(PurpleAccount *account,
- const char *description)
- PidginBuddyListPrivate *priv =
- pidgin_buddy_list_get_instance_private(gtkblist);
- GtkWidget *mini_dialog = find_child_widget_by_account(
- GTK_CONTAINER(priv->error_scrollbook), account);
- pidgin_mini_dialog_set_description(PIDGIN_MINI_DIALOG(mini_dialog),
-/* Notifications about accounts which were disconnected with
- * PURPLE_CONNECTION_ERROR_NAME_IN_USE
-typedef void (*AccountFunction)(PurpleAccount *);
-elsewhere_foreach_account(PidginMiniDialog *mini_dialog,
- PurpleAccount *account;
- GList *labels = gtk_container_get_children(
- GTK_CONTAINER(mini_dialog->contents));
- for (l = labels; l; l = l->next) {
- account = g_object_get_data(G_OBJECT(l->data), OBJECT_DATA_KEY_ACCOUNT);
- purple_debug_warning("gtkblist", "mini_dialog's child "
- "didn't have an account stored in it!");
-enable_account(PurpleAccount *account)
- purple_account_set_enabled(account, TRUE);
-reconnect_elsewhere_accounts(PidginMiniDialog *mini_dialog,
- elsewhere_foreach_account(mini_dialog, enable_account);
-clear_elsewhere_errors(PidginMiniDialog *mini_dialog,
- elsewhere_foreach_account(mini_dialog, purple_account_clear_current_error);
-ensure_signed_on_elsewhere_minidialog(PidginBuddyList *gtkblist)
- PidginBuddyListPrivate *priv =
- pidgin_buddy_list_get_instance_private(gtkblist);
- PidginMiniDialog *mini_dialog;
- if(priv->signed_on_elsewhere)
- mini_dialog = priv->signed_on_elsewhere =
- pidgin_mini_dialog_new(_("Welcome back!"), NULL, "pidgin-disconnect");
- pidgin_mini_dialog_add_button(mini_dialog, _("Re-enable"),
- reconnect_elsewhere_accounts, NULL);
- /* Make dismissing the dialog clear the errors. The "destroy" signal
- * does not appear to fire at quit, which is fortunate!
- g_signal_connect(G_OBJECT(mini_dialog), "destroy",
- (GCallback) clear_elsewhere_errors, NULL);
- add_error_dialog(gtkblist, GTK_WIDGET(mini_dialog));
- /* Set priv->signed_on_elsewhere to NULL when the dialog is destroyed */
- g_signal_connect(G_OBJECT(mini_dialog), "destroy",
- (GCallback) gtk_widget_destroyed, &(priv->signed_on_elsewhere));
-update_signed_on_elsewhere_minidialog_title(void)
- PidginBuddyListPrivate *priv =
- pidgin_buddy_list_get_instance_private(gtkblist);
- PidginMiniDialog *mini_dialog = priv->signed_on_elsewhere;
- if (mini_dialog == NULL)
- accounts = pidgin_mini_dialog_get_num_children(mini_dialog);
- gtk_widget_destroy(GTK_WIDGET(mini_dialog));
- title = g_strdup_printf(
- ngettext("%d account was disabled because you signed on from another location:",
- "%d accounts were disabled because you signed on from another location:",
- pidgin_mini_dialog_set_description(mini_dialog, title);
-create_account_label(PurpleAccount *account)
- GtkWidget *hbox, *label;
- const char *username = purple_account_get_username(account);
- hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
- g_object_set_data(G_OBJECT(hbox), OBJECT_DATA_KEY_ACCOUNT, account);
- pack_protocol_icon_start(hbox, account);
- label = gtk_label_new(NULL);
- markup = g_strdup_printf("<span size=\"smaller\">%s</span>", username);
- gtk_label_set_markup(GTK_LABEL(label), markup);
- gtk_label_set_xalign(GTK_LABEL(label), 0);
- gtk_label_set_yalign(GTK_LABEL(label), 0);
- g_object_set(G_OBJECT(label), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
- description = purple_account_get_current_error(account)->description;
- if (description != NULL && *description != '\0')
- gtk_widget_set_tooltip_text(label, description);
- gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
-add_to_signed_on_elsewhere(PurpleAccount *account)
- PidginBuddyListPrivate *priv =
- pidgin_buddy_list_get_instance_private(gtkblist);
- PidginMiniDialog *mini_dialog;
- GtkWidget *account_label;
- ensure_signed_on_elsewhere_minidialog(gtkblist);
- mini_dialog = priv->signed_on_elsewhere;
- if(find_child_widget_by_account(GTK_CONTAINER(mini_dialog->contents), account))
- account_label = create_account_label(account);
- gtk_box_pack_start(mini_dialog->contents, account_label, FALSE, FALSE, 0);
- gtk_widget_show_all(account_label);
- update_signed_on_elsewhere_minidialog_title();
-remove_from_signed_on_elsewhere(PurpleAccount *account)
- PidginBuddyListPrivate *priv =
- pidgin_buddy_list_get_instance_private(gtkblist);
- PidginMiniDialog *mini_dialog = priv->signed_on_elsewhere;
- if(mini_dialog == NULL)
- remove_child_widget_by_account(GTK_CONTAINER(mini_dialog->contents), account);
- update_signed_on_elsewhere_minidialog_title();
-update_signed_on_elsewhere_tooltip(PurpleAccount *account,
- const char *description)
- PidginBuddyListPrivate *priv =
- pidgin_buddy_list_get_instance_private(gtkblist);
- GtkContainer *c = GTK_CONTAINER(priv->signed_on_elsewhere->contents);
- GtkWidget *label = find_child_widget_by_account(c, account);
- gtk_widget_set_tooltip_text(label, description);
-/* Call appropriate error notification code based on error types */
-update_account_error_state(PurpleAccount *account,
- const PurpleConnectionErrorInfo *old,
- const PurpleConnectionErrorInfo *new,
- PidginBuddyList *gtkblist)
- gboolean descriptions_differ;
- if (old == NULL && new == NULL)
- if (old != NULL && new == NULL) {
- if(old->type == PURPLE_CONNECTION_ERROR_NAME_IN_USE)
- remove_from_signed_on_elsewhere(account);
- remove_generic_error_dialog(account);
- if (old == NULL && new != NULL) {
- if(new->type == PURPLE_CONNECTION_ERROR_NAME_IN_USE)
- add_to_signed_on_elsewhere(account);
- add_generic_error_dialog(account, new);
- /* else, new and old are both non-NULL */
- descriptions_differ = !purple_strequal(old->description, new->description);
- desc = new->description;
- case PURPLE_CONNECTION_ERROR_NAME_IN_USE:
- if (old->type == PURPLE_CONNECTION_ERROR_NAME_IN_USE
- && descriptions_differ) {
- update_signed_on_elsewhere_tooltip(account, desc);
- remove_generic_error_dialog(account);
- add_to_signed_on_elsewhere(account);
- if (old->type == PURPLE_CONNECTION_ERROR_NAME_IN_USE) {
- remove_from_signed_on_elsewhere(account);
- add_generic_error_dialog(account, new);
- } else if (descriptions_differ) {
- update_generic_error_message(account, desc);
-/* In case accounts are loaded before the blist (which they currently are),
- * let's call update_account_error_state ourselves on every account's current
- * state when the blist starts.
-show_initial_account_errors(PidginBuddyList *gtkblist)
- PurpleAccountManager *manager = NULL;
- PurpleAccount *account;
- const PurpleConnectionErrorInfo *err;
- manager = purple_account_manager_get_default();
- l = purple_account_manager_get_all(manager);
- for(; l; l = l->next) {
- err = purple_account_get_current_error(account);
- update_account_error_state(account, NULL, err, gtkblist);
/* This assumes there are not things like groupless buddies or multi-leveled groups.
* I'm sure other things in this code assumes that also.
@@ -3733,7 +3276,6 @@
static void pidgin_blist_show(PurpleBuddyList *list)
- PidginBuddyListPrivate *priv;
GSimpleActionGroup *action_group = NULL;
GtkTreeViewColumn *column;
@@ -3747,7 +3289,6 @@
gtkblist = PIDGIN_BUDDY_LIST(list);
- priv = pidgin_buddy_list_get_instance_private(gtkblist);
gtkblist->window = pidgin_contact_list_window_new();
g_signal_connect(G_OBJECT(gtkblist->window), "focus-in-event",
@@ -3840,10 +3381,6 @@
gtkblist->scrollbook = pidgin_scroll_book_new();
gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->scrollbook, FALSE, FALSE, 0);
- priv->error_scrollbook = PIDGIN_SCROLL_BOOK(pidgin_scroll_book_new());
- gtk_box_pack_start(GTK_BOX(gtkblist->vbox),
- GTK_WIDGET(priv->error_scrollbook), FALSE, FALSE, 0);
/* Update some dynamic things */
pidgin_blist_update_sort_methods();
@@ -3863,11 +3400,6 @@
/* Setup some purple signal handlers. */
- handle = purple_accounts_get_handle();
- purple_signal_connect(handle, "account-error-changed", gtkblist,
- G_CALLBACK(update_account_error_state),
handle = purple_conversations_get_handle();
purple_signal_connect(handle, "conversation-updated", gtkblist,
G_CALLBACK(conversation_updated_cb),
@@ -3882,8 +3414,6 @@
G_CALLBACK(conversation_created_cb),
- show_initial_account_errors(gtkblist);
/* emit our created signal */
handle = pidgin_blist_get_handle();
purple_signal_emit(handle, "gtkblist-created", list);