--- a/libpurple/purpleconversation.c Wed Apr 24 01:02:13 2024 -0500
+++ b/libpurple/purpleconversation.c Thu Apr 25 21:07:46 2024 -0500
@@ -184,9 +184,9 @@
-purple_conversation_send_message_async_cb(GObject *protocol,
+purple_conversation_send_message_async_old_cb(GObject *protocol, PurpleProtocolConversation *protocol_conversation = NULL;
PurpleMessage *message = data;
@@ -206,6 +206,54 @@
+purple_conversation_send_message_async_cb(GObject *source, + PurpleMessage *message = NULL; + PurpleProtocolConversation *protocol = NULL; + gboolean success = FALSE; + /* task and result share a cancellable, so we just need to clear task to + * make sure its callback gets called. + if(g_task_return_error_if_cancelled(G_TASK(task))) { + protocol = PURPLE_PROTOCOL_CONVERSATION(source); + message = g_task_get_task_data(G_TASK(task)); + success = purple_protocol_conversation_send_message_finish(protocol, + error = g_error_new(PURPLE_CONVERSATION_DOMAIN, 0, + purple_message_set_error(message, error); + g_task_return_error(task, error); + /* If the protocol didn't set delivered, set it now. */ + if(!purple_message_get_delivered(message)) { + purple_message_set_delivered(message, TRUE); + g_task_return_boolean(task, TRUE); common_send(PurpleConversation *conversation, const char *message,
PurpleMessageFlags msgflags)
@@ -260,7 +308,7 @@
purple_protocol_conversation_send_message_async(protocol_conversation,
- purple_conversation_send_message_async_cb,
+ purple_conversation_send_message_async_old_cb, g_clear_pointer(&displayed, g_free);
@@ -1181,6 +1229,59 @@
+purple_conversation_send_message_async(PurpleConversation *conversation, + PurpleMessage *message, + GCancellable *cancellable, + GAsyncReadyCallback callback, + PurpleAccount *account = NULL; + PurpleProtocol *protocol = NULL; + g_return_if_fail(PURPLE_IS_CONVERSATION(conversation)); + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + task = g_task_new(conversation, cancellable, callback, data); + g_task_set_source_tag(task, purple_conversation_send_message_async); + g_task_set_task_data(task, g_object_ref(message), g_object_unref); + account = purple_conversation_get_account(conversation); + protocol = purple_account_get_protocol(account); + if(!PURPLE_IS_PROTOCOL_CONVERSATION(protocol)) { + g_task_return_new_error(task, PURPLE_CONVERSATION_DOMAIN, 0, + "protocol does not implement " + "PurpleProtocolConversation"); + purple_protocol_conversation_send_message_async(PURPLE_PROTOCOL_CONVERSATION(protocol), + purple_conversation_send_message_async_cb, +purple_conversation_send_message_finish(PurpleConversation *conversation, + g_return_val_if_fail(PURPLE_IS_CONVERSATION(conversation), FALSE); + g_return_val_if_fail(G_IS_ASYNC_RESULT(result), FALSE); + g_return_val_if_fail(g_task_get_source_tag(G_TASK(result)) != + purple_conversation_send_message_async, FALSE); + return g_task_propagate_boolean(G_TASK(result), error); purple_conversation_send(PurpleConversation *conversation,
--- a/libpurple/purpleconversation.h Wed Apr 24 01:02:13 2024 -0500
+++ b/libpurple/purpleconversation.h Thu Apr 25 21:07:46 2024 -0500
@@ -32,6 +32,17 @@
#include "purpleversion.h"
+ * PURPLE_CONVERSATION_DOMAIN: + * A GError domain for PurpleConversation. +#define PURPLE_CONVERSATION_DOMAIN \ + (g_quark_from_static_string("purple-conversatin")) \ + PURPLE_AVAILABLE_MACRO_IN_3_0 #define PURPLE_TYPE_CONVERSATION (purple_conversation_get_type())
@@ -326,6 +337,42 @@
void purple_conversation_write_system_message(PurpleConversation *conversation, const char *message, PurpleMessageFlags flags);
+ * purple_conversation_send_message_async: + * @conversation: The conversation. + * @message: The message to send. + * @cancellable: (nullable): optional GCancellable object, %NULL to ignore. + * @callback: (nullable) (scope async): The callback to call after the + * conversation has been created. + * @data: (nullable): Optional user data to pass to @callback. + * Sends @message to @conversation. + * This will lookup the account and protocol plugin that @conversation belongs + * to and call [method@ProtocolConversation.send_message_async] for @message. + * You will need to call [method@Conversation.send_message_finish] from +void purple_conversation_send_message_async(PurpleConversation *conversation, PurpleMessage *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer data); + * purple_conversation_send_message_finish: + * @conversation: The instance. + * @error: Return address for a #GError, or %NULL. + * Finishes a previous call to [method@Conversation.send_message_async]. + * Returns: %TRUE on success, otherwise %FALSE with error set. +gboolean purple_conversation_send_message_finish(PurpleConversation *conversation, GAsyncResult *result, GError **error); * purple_conversation_send:
* @conversation: The conversation.
* @message: The message to send.
--- a/libpurple/purplemessage.c Wed Apr 24 01:02:13 2024 -0500
+++ b/libpurple/purplemessage.c Thu Apr 25 21:07:46 2024 -0500
@@ -683,7 +683,7 @@
g_clear_error(&message->error);
- g_propagate_error(&message->error, error);
+ message->error = g_error_copy(error); g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_ERROR]);
--- a/libpurple/purplemessage.h Wed Apr 24 01:02:13 2024 -0500
+++ b/libpurple/purplemessage.h Thu Apr 25 21:07:46 2024 -0500
@@ -369,7 +369,7 @@
* purple_message_set_error:
* @message: The instance.
- * @error: (nullable) (transfer full): The error to set.
+ * @error: (nullable) (transfer none): The error to set. * Sets the error of @message to @error. Primarily this will be used for