pidgin/pidgin

Parents 441ec6ccbd93
Children ce31b5b1186f
Add a present signal to PurpleConversation and propagate it from PurpleConversationManager

Testing Done:
Ran the unit tests under valgrind.

Reviewed at https://reviews.imfreedom.org/r/3134/
--- a/libpurple/purpleconversation.c Tue Apr 16 00:41:54 2024 -0500
+++ b/libpurple/purpleconversation.c Tue Apr 16 22:27:20 2024 -0500
@@ -95,6 +95,7 @@
static GParamSpec *properties[N_PROPERTIES] = {NULL, };
enum {
+ SIG_PRESENT,
SIG_MEMBER_ADDED,
SIG_MEMBER_REMOVED,
N_SIGNALS,
@@ -910,6 +911,26 @@
g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
/**
+ * PurpleConversation::present:
+ * @conversation: The instance.
+ *
+ * Emitted by [method@Conversation.present] when something wants the
+ * conversation presented to the user.
+ *
+ * Since: 3.0
+ */
+ signals[SIG_PRESENT] = g_signal_new_class_handler(
+ "present",
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 0);
+
+ /**
* PurpleConversation::member-added:
* @conversation: The instance.
* @member: The [class@Purple.ConversationMember] instance.
@@ -992,7 +1013,10 @@
}
void
-purple_conversation_present(G_GNUC_UNUSED PurpleConversation *conversation) {
+purple_conversation_present(PurpleConversation *conversation) {
+ g_return_if_fail(PURPLE_IS_CONVERSATION(conversation));
+
+ g_signal_emit(conversation, signals[SIG_PRESENT], 0);
}
void
--- a/libpurple/purpleconversation.h Tue Apr 16 00:41:54 2024 -0500
+++ b/libpurple/purpleconversation.h Tue Apr 16 22:27:20 2024 -0500
@@ -158,8 +158,7 @@
* purple_conversation_present:
* @conversation: The conversation to present
*
- * Present a conversation to the user. This allows core code to initiate a
- * conversation by displaying the IM dialog.
+ * Emits [signal@Conversation::present].
*
* Since: 2.0
*/
--- a/libpurple/purpleconversationmanager.c Tue Apr 16 00:41:54 2024 -0500
+++ b/libpurple/purpleconversationmanager.c Tue Apr 16 22:27:20 2024 -0500
@@ -30,6 +30,7 @@
SIG_REGISTERED,
SIG_UNREGISTERED,
SIG_CONVERSATION_CHANGED,
+ SIG_PRESENT_CONVERSATION,
N_SIGNALS,
};
static guint signals[N_SIGNALS] = {0, };
@@ -105,8 +106,6 @@
/******************************************************************************
* Callbacks
*****************************************************************************/
-
-/* This callback propagates the notify signal from conversations. */
static void
purple_conversation_manager_conversation_changed_cb(GObject *source,
GParamSpec *pspec,
@@ -117,6 +116,13 @@
source, pspec);
}
+static void
+purple_conversation_manager_present_conversation_cb(PurpleConversation *conversation,
+ gpointer data)
+{
+ g_signal_emit(data, signals[SIG_PRESENT_CONVERSATION], 0, conversation);
+}
+
/******************************************************************************
* GObject Implementation
*****************************************************************************/
@@ -212,6 +218,29 @@
2,
PURPLE_TYPE_CONVERSATION,
G_TYPE_PARAM);
+
+ /**
+ * PurpleConversationManager::present-conversation:
+ * @manager: The instance.
+ * @conversation: The conversation that should be presented.
+ *
+ * This is a propagation of [signal@Conversation::present]. This means that
+ * your callback will be called for any conversation that @manager knows
+ * about.
+ *
+ * Since: 3.0
+ */
+ signals[SIG_PRESENT_CONVERSATION] = g_signal_new_class_handler(
+ "present-conversation",
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 1,
+ PURPLE_TYPE_CONVERSATION);
}
/******************************************************************************
@@ -258,6 +287,9 @@
g_signal_connect_object(conversation, "notify",
G_CALLBACK(purple_conversation_manager_conversation_changed_cb),
manager, 0);
+ g_signal_connect_object(conversation, "present",
+ G_CALLBACK(purple_conversation_manager_present_conversation_cb),
+ manager, 0);
/* Tell everyone about the new conversation. */
g_signal_emit(manager, signals[SIG_REGISTERED], 0, conversation);
@@ -284,6 +316,9 @@
g_signal_handlers_disconnect_by_func(conversation,
purple_conversation_manager_conversation_changed_cb,
manager);
+ g_signal_handlers_disconnect_by_func(conversation,
+ purple_conversation_manager_present_conversation_cb,
+ manager);
/* Tell everyone about the unregistered conversation. */
g_signal_emit(manager, signals[SIG_UNREGISTERED], 0, conversation);
--- a/libpurple/tests/test_conversation.c Tue Apr 16 00:41:54 2024 -0500
+++ b/libpurple/tests/test_conversation.c Tue Apr 16 22:27:20 2024 -0500
@@ -448,6 +448,46 @@
}
/******************************************************************************
+ * Signal tests
+ *****************************************************************************/
+static void
+test_purple_conversation_present_cb(PurpleConversation *conversation,
+ gpointer data)
+{
+ guint *counter = data;
+
+ g_assert_true(PURPLE_IS_CONVERSATION(conversation));
+
+ *counter = *counter + 1;
+}
+
+static void
+test_purple_conversation_signals_present(void) {
+ PurpleAccount *account = NULL;
+ PurpleConversation *conversation = NULL;
+ guint counter = 0;
+
+ account = purple_account_new("test", "test");
+ conversation = g_object_new(
+ PURPLE_TYPE_CONVERSATION,
+ "account", account,
+ "type", PURPLE_CONVERSATION_TYPE_DM,
+ "name", "bleh",
+ NULL);
+
+ g_signal_connect(conversation, "present",
+ G_CALLBACK(test_purple_conversation_present_cb),
+ &counter);
+
+ g_assert_cmpuint(counter, ==, 0);
+ purple_conversation_present(conversation);
+ g_assert_cmpuint(counter, ==, 1);
+
+ g_assert_finalize_object(conversation);
+ g_clear_object(&account);
+}
+
+/******************************************************************************
* Main
*****************************************************************************/
gint
@@ -477,6 +517,9 @@
g_test_add_func("/conversation/message/write-one",
test_purple_conversation_message_write_one);
+ g_test_add_func("/conversation/signals/present",
+ test_purple_conversation_signals_present);
+
ret = g_test_run();
test_ui_purple_uninit();
--- a/libpurple/tests/test_conversation_manager.c Tue Apr 16 00:41:54 2024 -0500
+++ b/libpurple/tests/test_conversation_manager.c Tue Apr 16 22:27:20 2024 -0500
@@ -26,12 +26,15 @@
* Callbacks
*****************************************************************************/
static void
-test_purple_conversation_manager_counter_cb(G_GNUC_UNUSED PurpleConversationManager *manager,
- G_GNUC_UNUSED PurpleConversation *conversation,
+test_purple_conversation_manager_counter_cb(PurpleConversationManager *manager,
+ PurpleConversation *conversation,
gpointer data)
{
guint *counter = data;
+ g_assert_true(PURPLE_IS_CONVERSATION_MANAGER(manager));
+ g_assert_true(PURPLE_IS_CONVERSATION(conversation));
+
*counter = *counter + 1;
}
@@ -163,6 +166,43 @@
g_clear_object(&manager);
}
+static void
+test_purple_conversation_manager_signal_present_conversation(void) {
+ PurpleAccount *account = NULL;
+ PurpleConversation *conversation = NULL;
+ PurpleConversationManager *manager = NULL;
+ guint counter = 0;
+ gboolean ret = FALSE;
+
+ account = purple_account_new("test", "test");
+
+ manager = g_object_new(PURPLE_TYPE_CONVERSATION_MANAGER, NULL);
+ g_signal_connect(manager, "present-conversation",
+ G_CALLBACK(test_purple_conversation_manager_counter_cb),
+ &counter);
+
+ conversation = g_object_new(
+ PURPLE_TYPE_CONVERSATION,
+ "account", account,
+ "type", PURPLE_CONVERSATION_TYPE_DM,
+ "name", "bleh",
+ NULL);
+
+ ret = purple_conversation_manager_register(manager, conversation);
+ g_assert_true(ret);
+
+ g_assert_cmpuint(counter, ==, 0);
+ purple_conversation_present(conversation);
+ g_assert_cmpuint(counter, ==, 1);
+
+ ret = purple_conversation_manager_unregister(manager, conversation);
+ g_assert_true(ret);
+
+ g_assert_finalize_object(manager);
+ g_assert_finalize_object(conversation);
+ g_clear_object(&account);
+}
+
/******************************************************************************
* find-dm tests
*****************************************************************************/
@@ -304,6 +344,8 @@
g_test_add_func("/conversation-manager/signals/conversation-changed",
test_purple_conversation_manager_signal_conversation_changed);
+ g_test_add_func("/conversation-manager/signals/present-conversation",
+ test_purple_conversation_manager_signal_present_conversation);
g_test_add_func("/conversation-manager/find-dm/empty",
test_purple_conversation_manager_find_dm_empty);