Mon, 21 Apr 2025 23:09:08 -0500
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/
--- 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