Make Purple.ProtocolConversation.join_channel_finish return a conversation

Mon, 21 Apr 2025 23:09:08 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Mon, 21 Apr 2025 23:09:08 -0500
changeset 43235
42e7b89033fe
parent 43234
85be702275e6
child 43236
ce4987105a4e

Make Purple.ProtocolConversation.join_channel_finish return a conversation

This allows us to automatically present the conversation after it is
successfully created from the channel join dialog.

I also added a shortcut to open the channel join dialog.

Testing Done:
Used the keyboard to join a channel and have it automatically presented.

Reviewed at https://reviews.imfreedom.org/r/3982/

libpurple/purpleprotocolconversation.c file | annotate | diff | comparison | revisions
libpurple/purpleprotocolconversation.h file | annotate | diff | comparison | revisions
libpurple/tests/test_protocol_conversation.c file | annotate | diff | comparison | revisions
pidgin/pidginapplication.c file | annotate | diff | comparison | revisions
pidgin/pidginchanneljoindialog.c file | annotate | diff | comparison | revisions
protocols/ircv3/purpleircv3protocolconversation.c file | annotate | diff | comparison | revisions
--- a/libpurple/purpleprotocolconversation.c	Mon Apr 21 22:43:29 2025 -0500
+++ b/libpurple/purpleprotocolconversation.c	Mon Apr 21 23:09:08 2025 -0500
@@ -405,20 +405,20 @@
 	}
 }
 
-gboolean
+PurpleConversation *
 purple_protocol_conversation_join_channel_finish(PurpleProtocolConversation *protocol,
                                                  GAsyncResult *result,
                                                  GError **error)
 {
 	PurpleProtocolConversationInterface *iface = NULL;
 
-	g_return_val_if_fail(PURPLE_IS_PROTOCOL_CONVERSATION(protocol), FALSE);
-	g_return_val_if_fail(G_IS_ASYNC_RESULT(result), FALSE);
+	g_return_val_if_fail(PURPLE_IS_PROTOCOL_CONVERSATION(protocol), NULL);
+	g_return_val_if_fail(G_IS_ASYNC_RESULT(result), NULL);
 
 	if(g_async_result_is_tagged(result,
 	                            purple_protocol_conversation_join_channel_async))
 	{
-		return g_task_propagate_boolean(G_TASK(result), error);
+		return g_task_propagate_pointer(G_TASK(result), error);
 	}
 
 	iface = PURPLE_PROTOCOL_CONVERSATION_GET_IFACE(protocol);
@@ -430,7 +430,7 @@
 	          "without calling "
 	          "purple_protocol_conversation_join_channel_async");
 
-	return FALSE;
+	return NULL;
 }
 
 gboolean
--- a/libpurple/purpleprotocolconversation.h	Mon Apr 21 22:43:29 2025 -0500
+++ b/libpurple/purpleprotocolconversation.h	Mon Apr 21 23:09:08 2025 -0500
@@ -88,7 +88,7 @@
 
 	PurpleChannelJoinDetails *(*get_channel_join_details)(PurpleProtocolConversation *protocol, PurpleAccount *account);
 	void (*join_channel_async)(PurpleProtocolConversation *protocol, PurpleAccount *account, PurpleChannelJoinDetails *details, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer data);
-	gboolean (*join_channel_finish)(PurpleProtocolConversation *protocol, GAsyncResult *result, GError **error);
+	PurpleConversation *(*join_channel_finish)(PurpleProtocolConversation *protocol, GAsyncResult *result, GError **error);
 
 	void (*set_avatar_async)(PurpleProtocolConversation *protocol, PurpleConversation *conversation, PurpleAvatar *avatar, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer data);
 	gboolean (*set_avatar_finish)(PurpleProtocolConversation *protocol, GAsyncResult *result, GError **error);
@@ -396,13 +396,13 @@
  * the callback of that function to get the result of whether or not the
  * channel was joined successfully.
  *
- * Returns: %TRUE if the channel was joined successfully, otherwise %FALSE with
- *          @error possibly set.
+ * Returns: (transfer full) (nullable): The conversation if one was joined,
+ *          otherwise %NULL with @error possibly set.
  *
  * Since: 3.0
  */
 PURPLE_AVAILABLE_IN_3_0
-gboolean purple_protocol_conversation_join_channel_finish(PurpleProtocolConversation *protocol, GAsyncResult *result, GError **error);
+PurpleConversation *purple_protocol_conversation_join_channel_finish(PurpleProtocolConversation *protocol, GAsyncResult *result, GError **error);
 
 /**
  * purple_protocol_conversation_implements_set_avatar:
--- a/libpurple/tests/test_protocol_conversation.c	Mon Apr 21 22:43:29 2025 -0500
+++ b/libpurple/tests/test_protocol_conversation.c	Mon Apr 21 23:09:08 2025 -0500
@@ -350,17 +350,18 @@
                                                         GAsyncResult *result,
                                                         G_GNUC_UNUSED gpointer data)
 {
+	PurpleConversation *conversation = NULL;
 	PurpleProtocolConversation *protocol = NULL;
 	GError *error = NULL;
-	gboolean joined = FALSE;
 
 	protocol = PURPLE_PROTOCOL_CONVERSATION(source);
-	joined = purple_protocol_conversation_join_channel_finish(protocol, result,
-	                                                          &error);
+	conversation = purple_protocol_conversation_join_channel_finish(protocol,
+	                                                                result,
+	                                                                &error);
 
 	g_assert_error(error, PURPLE_PROTOCOL_CONVERSATION_DOMAIN, 0);
 	g_clear_error(&error);
-	g_assert_false(joined);
+	g_assert_null(conversation);
 }
 
 static void
@@ -861,13 +862,16 @@
 		                                    0, "error");
 		g_task_return_error(task, error);
 	} else {
-		g_task_return_boolean(task, TRUE);
+		PurpleConversation *conversation = NULL;
+
+		conversation = g_object_new(PURPLE_TYPE_CONVERSATION, NULL);
+		g_task_return_pointer(task, conversation, g_object_unref);
 	}
 
 	g_clear_object(&task);
 }
 
-static gboolean
+static PurpleConversation *
 test_purple_protocol_conversation_join_channel_finish(PurpleProtocolConversation *protocol,
                                                       GAsyncResult *result,
                                                       GError **error)
@@ -877,7 +881,7 @@
 	test_protocol = TEST_PURPLE_PROTOCOL_CONVERSATION(protocol);
 	test_protocol->join_channel_finish += 1;
 
-	return g_task_propagate_boolean(G_TASK(result), error);
+	return g_task_propagate_pointer(G_TASK(result), error);
 }
 
 static void
@@ -1499,23 +1503,25 @@
                                                   G_GNUC_UNUSED gpointer data)
 {
 	TestPurpleProtocolConversation *test_protocol = NULL;
+	PurpleConversation *conversation = NULL;
 	PurpleProtocolConversation *protocol = NULL;
 	GError *error = NULL;
-	gboolean result = FALSE;
 
 	protocol = PURPLE_PROTOCOL_CONVERSATION(obj);
 	test_protocol = TEST_PURPLE_PROTOCOL_CONVERSATION(obj);
 
-	result = purple_protocol_conversation_join_channel_finish(protocol, res,
-	                                                          &error);
+	conversation = purple_protocol_conversation_join_channel_finish(protocol,
+	                                                                res,
+	                                                                &error);
 
 	if(test_protocol->should_error) {
 		g_assert_error(error, TEST_PURPLE_PROTOCOL_CONVERSATION_DOMAIN, 0);
 		g_clear_error(&error);
-		g_assert_false(result);
+		g_assert_null(conversation);
 	} else {
 		g_assert_no_error(error);
-		g_assert_true(result);
+		g_assert_true(PURPLE_IS_CONVERSATION(conversation));
+		g_clear_object(&conversation);
 	}
 }
 
--- a/pidgin/pidginapplication.c	Mon Apr 21 22:43:29 2025 -0500
+++ b/pidgin/pidginapplication.c	Mon Apr 21 23:09:08 2025 -0500
@@ -603,6 +603,8 @@
 	pidgin_application_add_shortcut(application, "app.preferences",
 	                                "<Primary>comma");
 	pidgin_application_add_shortcut(application, "app.quit", "<Primary>Q");
+	pidgin_application_add_shortcut(application, "app.join-channel",
+	                                "<Primary>J");
 }
 
 /******************************************************************************
--- a/pidgin/pidginchanneljoindialog.c	Mon Apr 21 22:43:29 2025 -0500
+++ b/pidgin/pidginchanneljoindialog.c	Mon Apr 21 23:09:08 2025 -0500
@@ -198,16 +198,17 @@
                                    gpointer data)
 {
 	PidginChannelJoinDialog *dialog = data;
+	PurpleConversation *conversation = NULL;
 	PurpleProtocolConversation *protocol_conversation = NULL;
 	GError *error = NULL;
-	gboolean joined = FALSE;
 
 	protocol_conversation = PURPLE_PROTOCOL_CONVERSATION(source);
 
-	joined = purple_protocol_conversation_join_channel_finish(protocol_conversation,
-	                                                          result, &error);
+	conversation = purple_protocol_conversation_join_channel_finish(protocol_conversation,
+	                                                                result,
+	                                                                &error);
 
-	if(!joined) {
+	if(!PURPLE_IS_CONVERSATION(conversation)) {
 		const char *error_message = _("Unknown error");
 
 		if(error != NULL) {
@@ -219,6 +220,8 @@
 		gtk_widget_set_sensitive(dialog->entries, TRUE);
 		gtk_widget_set_sensitive(dialog->join, TRUE);
 	} else {
+		purple_conversation_present(conversation);
+
 		g_clear_object(&dialog->cancellable);
 		gtk_window_destroy(GTK_WINDOW(dialog));
 	}
--- a/protocols/ircv3/purpleircv3protocolconversation.c	Mon Apr 21 22:43:29 2025 -0500
+++ b/protocols/ircv3/purpleircv3protocolconversation.c	Mon Apr 21 23:09:08 2025 -0500
@@ -186,22 +186,21 @@
 		"online", TRUE,
 		NULL);
 	purple_conversation_manager_add(manager, conversation);
-	g_clear_object(&conversation);
 
 	ibis_client_write(client, message);
 
 	g_free(normalized_name);
 
-	g_task_return_boolean(task, TRUE);
+	g_task_return_pointer(task, conversation, g_object_unref);
 	g_clear_object(&task);
 }
 
-static gboolean
+static PurpleConversation *
 purple_ircv3_protocol_conversation_join_channel_finish(G_GNUC_UNUSED PurpleProtocolConversation *protocol,
                                                        GAsyncResult *result,
                                                        GError **error)
 {
-	return g_task_propagate_boolean(G_TASK(result), error);
+	return g_task_propagate_pointer(G_TASK(result), error);
 }
 
 static void

mercurial