# HG changeset patch
# Node ID b7647361f7d22a534c74f450ba8d5cc27aaf59da
# Parent  7621ef6ea06aff5e53b711f729ec1b59c7b5c8fe
diff --git a/im.pidgin.Pidgin3.yml b/im.pidgin.Pidgin3.yml
--- a/im.pidgin.Pidgin3.yml
+++ b/im.pidgin.Pidgin3.yml
@@ -63,8 +63,8 @@
     sources:
       - type: archive
         archive-type: tar-xz
-        url: https://sourceforge.net/projects/pidgin/files/ibis/0.9.0/ibis-0.9.0.tar.xz/download
-        sha256: 43251c44fc97205804fd28b79b355ff27659f172a7b542de24aa596cbde3d852
+        url: https://sourceforge.net/projects/pidgin/files/ibis/0.10.1/ibis-0.10.1.tar.xz/download
+        sha256: 3c6a43a5cbbf80efa91e90e5b62e19e37258e788734feee76ab6fb6b7e13bb8c
   - name: xeme
     buildsystem: meson
     config-opts:
diff --git a/protocols/ircv3/meson.build b/protocols/ircv3/meson.build
--- a/protocols/ircv3/meson.build
+++ b/protocols/ircv3/meson.build
@@ -20,7 +20,7 @@
 	subdir_done()
 endif
 
-ibis_dep = dependency('ibis', version : '>= 0.9.0')
+ibis_dep = dependency('ibis', version : '>= 0.10.1')
 
 ircv3_filebase = f'purple-@purple_api_major_version@-ircv3'
 ircv3_filebase = f'purple-@purple_api_major_version@-ircv3'
diff --git a/protocols/ircv3/purpleircv3connection.c b/protocols/ircv3/purpleircv3connection.c
--- a/protocols/ircv3/purpleircv3connection.c
+++ b/protocols/ircv3/purpleircv3connection.c
@@ -482,6 +482,9 @@
 	g_signal_connect_object(client, "message::" IBIS_MSG_QUIT,
 	                        G_CALLBACK(purple_ircv3_message_handler_quit),
 	                        connection, G_CONNECT_DEFAULT);
+	g_signal_connect_object(client, "message::" IBIS_MSG_ERROR,
+	                        G_CALLBACK(purple_ircv3_message_handler_error),
+	                        connection, G_CONNECT_DEFAULT);
 	g_signal_connect_object(client, "message::" IBIS_RPL_NAMREPLY,
 	                        G_CALLBACK(purple_ircv3_message_handler_namreply),
 	                        connection, G_CONNECT_DEFAULT);
@@ -531,18 +534,39 @@
 {
 	PurpleConnection *connection = data;
 	IbisClient *client = IBIS_CLIENT(source);
+	gboolean connected = FALSE;
 
-	if(ibis_client_get_connected(client)) {
+	connected = ibis_client_get_connected(client);
+	if(!connected && ibis_client_get_registered(client)) {
 		purple_connection_set_state(connection,
 		                            PURPLE_CONNECTION_STATE_CONNECTED);
+	} else {
+		purple_connection_set_state(connection,
+		                            PURPLE_CONNECTION_STATE_DISCONNECTED);
+	}
+}
+
+static void
+purple_ircv3_connection_registered_cb(GObject *source,
+                                      G_GNUC_UNUSED GParamSpec *pspec,
+                                      gpointer data)
+{
+	PurpleConnection *connection = data;
+	IbisClient *client = IBIS_CLIENT(source);
+
+	if(ibis_client_get_registered(client)) {
+		PurpleAccount *account = NULL;
+
+		account = purple_connection_get_account(connection);
+		if(!purple_account_is_connected(account)) {
+			purple_connection_set_state(connection,
+			                            PURPLE_CONNECTION_STATE_CONNECTED);
+		}
 
 		/* Once reconnected, we need to rejoin any channels that the
 		 * conversation manager has for us.
 		 */
 		purple_ircv3_connection_rejoin_channels(PURPLE_IRCV3_CONNECTION(connection));
-	} else {
-		purple_connection_set_state(connection,
-		                            PURPLE_CONNECTION_STATE_DISCONNECTED);
 	}
 }
 
@@ -606,6 +630,9 @@
 	g_signal_connect_object(connection->client, "notify::connected",
 	                        G_CALLBACK(purple_ircv3_connection_connect_cb),
 	                        connection, G_CONNECT_DEFAULT);
+	g_signal_connect_object(connection->client, "notify::registered",
+	                        G_CALLBACK(purple_ircv3_connection_registered_cb),
+	                        connection, G_CONNECT_DEFAULT);
 	g_signal_connect_object(connection->client, "notify::error",
 	                        G_CALLBACK(purple_ircv3_connection_error_cb),
 	                        connection, G_CONNECT_DEFAULT);
diff --git a/protocols/ircv3/purpleircv3messagehandlers.c b/protocols/ircv3/purpleircv3messagehandlers.c
--- a/protocols/ircv3/purpleircv3messagehandlers.c
+++ b/protocols/ircv3/purpleircv3messagehandlers.c
@@ -359,7 +359,7 @@
 		target = purple_contact_info_get_id(PURPLE_CONTACT_INFO(contact));
 	}
 
-	if(!ibis_client_get_connected(client)) {
+	if(!ibis_client_get_registered(client)) {
 		conversation = purple_ircv3_connection_get_status_conversation(connection);
 	} else if(IBIS_IS_CTCP_MESSAGE(ctcp_message)) {
 		conversation = purple_ircv3_connection_get_status_conversation(connection);
@@ -623,3 +623,37 @@
 
 	return TRUE;
 }
+
+gboolean
+purple_ircv3_message_handler_error(IbisClient *client,
+                                   G_GNUC_UNUSED const char *command,
+                                   IbisMessage *ibis_message,
+                                   gpointer data)
+{
+	PurpleAccount *account = NULL;
+	PurpleConnection *connection = data;
+	GError *error = NULL;
+	GStrv params = NULL;
+	guint n_params = 0;
+	char *reason = NULL;
+
+	account = purple_connection_get_account(connection);
+
+	params = ibis_message_get_params(ibis_message);
+	n_params = g_strv_length(params);
+
+	if(n_params > 0) {
+		reason = g_strjoinv(" ", params);
+	} else {
+		reason = g_strdup(_("unknown error"));
+	}
+
+	error = g_error_new_literal(PURPLE_IRCV3_DOMAIN, 0, reason);
+	g_clear_pointer(&reason, g_free);
+
+	ibis_client_stop(client, NULL);
+
+	purple_account_disconnect_with_error(account, error);
+
+	return TRUE;
+}
diff --git a/protocols/ircv3/purpleircv3messagehandlers.h b/protocols/ircv3/purpleircv3messagehandlers.h
--- a/protocols/ircv3/purpleircv3messagehandlers.h
+++ b/protocols/ircv3/purpleircv3messagehandlers.h
@@ -46,6 +46,7 @@
 G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_topic(IbisClient *client, const char *command, IbisMessage *message, gpointer data);
 G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_quit(IbisClient *client, const char *command, IbisMessage *message, gpointer data);
 G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_nick(IbisClient *client, const char *command, IbisMessage *message, gpointer data);
+G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_error(IbisClient *client, const char *command, IbisMessage *message, gpointer data);
 
 G_END_DECLS
 
diff --git a/subprojects/ibis.wrap b/subprojects/ibis.wrap
--- a/subprojects/ibis.wrap
+++ b/subprojects/ibis.wrap
@@ -1,4 +1,4 @@
 [wrap-hg]
 directory = ibis
 url = https://keep.imfreedom.org/ibis/ibis
-revision = v0.9.0
+revision = v0.10.1
