pidgin/pidgin

Parents 2c15f6e30f20
Children 39e595f7d056
Propagate the PurpleAccount::notify signal via PurpleAccountManager::account-changed

This new signal supports details and works just like notify does on the account
instances, but it will be emitted for any account that the manager instance
knows about which means we can remove the old purple signals.

Testing Done:
Enabled and disabled accounts in Pidgin via the menus to make sure things were working right, and verified via the console that the accounts were being enabled and disabled.
Ran Finch, but I ran into the infinite loop bug in the buddy list clean when disabling an account which is a known issue.

Reviewed at https://reviews.imfreedom.org/r/2032/
--- a/ChangeLog.API Fri Nov 04 23:55:30 2022 -0500
+++ b/ChangeLog.API Fri Nov 04 23:58:18 2022 -0500
@@ -328,6 +328,10 @@
* _XMLNodeType
* account-added signal. Use PurpleAccountManager::added
instead.
+ * account-disabled signal. Use
+ PurpleAccountManager::account-changed::enabled instead.
+ * account-enabled signal. Use
+ PurpleAccountManager::account-changed::enabled instead.
* account-alias-changed signal
* account-authorization-denied, account-authorization-granted,
account-authorization-requested,
--- a/doc/reference/libpurple/signals_account.md Fri Nov 04 23:55:30 2022 -0500
+++ b/doc/reference/libpurple/signals_account.md Fri Nov 04 23:58:18 2022 -0500
@@ -7,8 +7,6 @@
* [account-created](#account-created)
* [account-destroying](#account-destroying)
-* [account-disabled](#account-disabled)
-* [account-enabled](#account-enabled)
* [account-status-changed](#account-status-changed)
* [account-actions-changed](#account-actions-changed)
* [account-error-changed](#account-error-changed)
@@ -53,42 +51,6 @@
----
-#### account-disabled
-
-```c
-void user_function(PurpleAccount *account, gpointer user_data);
-```
-
-Emitted when an account is disabled.
-
-**Parameters:**
-
-**account**
-: The account that was disabled.
-
-**user_data**
-: User data set when the signal handler was connected.
-
-----
-
-#### account-enabled
-
-```c
-void user_function(PurpleAccount *account, gpointer user_data);
-```
-
-Emitted when an account is enabled.
-
-**Parameters**:
-
-**account**
-: The account that was enabled.
-
-**user_data**
-: User data set when the signal handler was connected.
-
-----
-
#### account-status-changed
```c
--- a/finch/gntaccount.c Fri Nov 04 23:55:30 2022 -0500
+++ b/finch/gntaccount.c Fri Nov 04 23:58:18 2022 -0500
@@ -861,14 +861,6 @@
edit_account(account);
}
-static gpointer
-finch_accounts_get_handle(void)
-{
- static int handle;
-
- return &handle;
-}
-
static void
account_added_callback(G_GNUC_UNUSED PurpleAccountManager *manager,
PurpleAccount *account, G_GNUC_UNUSED gpointer data)
@@ -890,12 +882,16 @@
}
static void
-account_abled_cb(PurpleAccount *account, gpointer user_data)
+account_abled_cb(G_GNUC_UNUSED PurpleAccountManager *manager,
+ PurpleAccount *account,
+ G_GNUC_UNUSED gpointer data)
{
- if (accounts.window == NULL)
+ if(accounts.window == NULL) {
return;
+ }
+
gnt_tree_set_choice(GNT_TREE(accounts.tree), account,
- GPOINTER_TO_INT(user_data));
+ purple_account_get_enabled(account));
}
void
@@ -903,23 +899,17 @@
{
PurpleAccountManager *manager = NULL;
GListModel *manager_model = NULL;
- gpointer account_handle = NULL;
guint n_items = 0;
manager = purple_account_manager_get_default();
manager_model = G_LIST_MODEL(manager);
- account_handle = purple_accounts_get_handle();
g_signal_connect(manager, "added", G_CALLBACK(account_added_callback),
NULL);
g_signal_connect(manager, "removed", G_CALLBACK(account_removed_callback),
NULL);
- purple_signal_connect(account_handle, "account-disabled",
- finch_accounts_get_handle(),
- G_CALLBACK(account_abled_cb), GINT_TO_POINTER(FALSE));
- purple_signal_connect(account_handle, "account-enabled",
- finch_accounts_get_handle(),
- G_CALLBACK(account_abled_cb), GINT_TO_POINTER(TRUE));
+ g_signal_connect(manager, "account-changed::enabled",
+ G_CALLBACK(account_abled_cb), NULL);
n_items = g_list_model_get_n_items(manager_model);
if(n_items != 0) {
--- a/libpurple/account.c Fri Nov 04 23:55:30 2022 -0500
+++ b/libpurple/account.c Fri Nov 04 23:58:18 2022 -0500
@@ -1500,15 +1500,11 @@
was_enabled = account->enabled;
account->enabled = value;
+ if(was_enabled != value) {
+ g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_ENABLED]);
+ }
gc = purple_account_get_connection(account);
- if(was_enabled && !value)
- purple_signal_emit(purple_accounts_get_handle(), "account-disabled", account);
- else if(!was_enabled && value)
- purple_signal_emit(purple_accounts_get_handle(), "account-enabled", account);
-
- g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_ENABLED]);
-
if ((gc != NULL) && (_purple_connection_wants_to_die(gc)))
return;
--- a/libpurple/accounts.c Fri Nov 04 23:55:30 2022 -0500
+++ b/libpurple/accounts.c Fri Nov 04 23:58:18 2022 -0500
@@ -680,14 +680,6 @@
void *handle = purple_accounts_get_handle();
void *conn_handle = purple_connections_get_handle();
- purple_signal_register(handle, "account-disabled",
- purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
- PURPLE_TYPE_ACCOUNT);
-
- purple_signal_register(handle, "account-enabled",
- purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
- PURPLE_TYPE_ACCOUNT);
-
purple_signal_register(handle, "account-created",
purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
PURPLE_TYPE_ACCOUNT);
--- a/libpurple/purpleaccountmanager.c Fri Nov 04 23:55:30 2022 -0500
+++ b/libpurple/purpleaccountmanager.c Fri Nov 04 23:58:18 2022 -0500
@@ -26,6 +26,7 @@
enum {
SIG_ADDED,
SIG_REMOVED,
+ SIG_ACCOUNT_CHANGED,
N_SIGNALS,
};
static guint signals[N_SIGNALS] = {0, };
@@ -39,6 +40,24 @@
static PurpleAccountManager *default_manager = NULL;
/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+/* This is the callback for the notify signal on accounts. It re-emits the
+ * signal as coming from the manager and passes the account as a parameter to
+ * the callback. It supports details as well so you can use
+ * g_signal_connect(manager, "account-changed::enabled", ...) to just get
+ * called when an account's enabled property changes.
+ */
+static void
+purple_account_manager_account_notify_cb(GObject *source, GParamSpec *pspec,
+ gpointer data)
+{
+ g_signal_emit(data, signals[SIG_ACCOUNT_CHANGED],
+ g_param_spec_get_name_quark(pspec),
+ source);
+}
+
+/******************************************************************************
* GListModel Implementation
*****************************************************************************/
static GType
@@ -144,6 +163,33 @@
G_TYPE_NONE,
1,
PURPLE_TYPE_ACCOUNT);
+
+ /**
+ * PurpleAccountManager::account-changed:
+ * @manager: The account manager instance.
+ * @account: The account that was changed.
+ *
+ * This is a propagation of the notify signal from @account. This means
+ * that your callback will be called for any account that @manager knows
+ * about.
+ *
+ * This also supports details, so you can specify the signal name as
+ * something like `account-changed::enabled` and your callback will only
+ * be called when the enabled property of @account has been changed.
+ *
+ * Since: 3.0.0
+ */
+ signals[SIG_ACCOUNT_CHANGED] = g_signal_new_class_handler(
+ "account-changed",
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 1,
+ PURPLE_TYPE_ACCOUNT);
}
/******************************************************************************
@@ -193,6 +239,11 @@
*/
g_ptr_array_insert(manager->accounts, 0, account);
+ /* Connect to the signals of the account that we want to propagate. */
+ g_signal_connect_object(account, "notify",
+ G_CALLBACK(purple_account_manager_account_notify_cb),
+ manager, 0);
+
purple_accounts_schedule_save();
g_signal_emit(manager, signals[SIG_ADDED], 0, account);
--- a/pidgin/pidginaccountsdisabledmenu.c Fri Nov 04 23:55:30 2022 -0500
+++ b/pidgin/pidginaccountsdisabledmenu.c Fri Nov 04 23:58:18 2022 -0500
@@ -62,7 +62,8 @@
}
static void
-pidgin_accounts_disabled_menu_changed_cb(G_GNUC_UNUSED PurpleAccount *account,
+pidgin_accounts_disabled_menu_changed_cb(G_GNUC_UNUSED PurpleAccountManager *manager,
+ G_GNUC_UNUSED PurpleAccount *account,
gpointer data)
{
PidginAccountsDisabledMenu *menu = data;
@@ -182,16 +183,11 @@
static void
pidgin_accounts_disabled_menu_init(PidginAccountsDisabledMenu *menu) {
- gpointer handle = NULL;
+ PurpleAccountManager *manager = purple_account_manager_get_default();
- /* Wire up the purple signals we care about. */
- handle = purple_accounts_get_handle();
- purple_signal_connect(handle, "account-enabled", menu,
- G_CALLBACK(pidgin_accounts_disabled_menu_changed_cb),
- menu);
- purple_signal_connect(handle, "account-disabled", menu,
- G_CALLBACK(pidgin_accounts_disabled_menu_changed_cb),
- menu);
+ g_signal_connect_object(manager, "account-changed::enabled",
+ G_CALLBACK(pidgin_accounts_disabled_menu_changed_cb),
+ menu, 0);
}
static void
--- a/pidgin/pidginaccountsenabledmenu.c Fri Nov 04 23:55:30 2022 -0500
+++ b/pidgin/pidginaccountsenabledmenu.c Fri Nov 04 23:58:18 2022 -0500
@@ -41,30 +41,30 @@
* Callbacks
*****************************************************************************/
static void
-pidgin_accounts_enabled_menu_enabled_cb(PurpleAccount *account, gpointer data) {
+pidgin_accounts_enabled_menu_changed_cb(G_GNUC_UNUSED PurpleAccountManager *manager,
+ PurpleAccount *account,
+ gpointer data)
+{
PidginAccountsEnabledMenu *menu = data;
- /* Add the account to the start of the list. */
- g_queue_push_head(menu->accounts, g_object_ref(account));
+ if(purple_account_get_enabled(account)) {
+ /* Add the account to the start of the list. */
+ g_queue_push_head(menu->accounts, g_object_ref(account));
- /* Tell everyone our model added a new item at position 0. */
- g_menu_model_items_changed(G_MENU_MODEL(menu), 0, 0, 1);
-}
+ /* Tell everyone our model added a new item at position 0. */
+ g_menu_model_items_changed(G_MENU_MODEL(menu), 0, 0, 1);
+ } else {
+ gint index = g_queue_index(menu->accounts, account);
-static void
-pidgin_accounts_enabled_menu_disabled_cb(PurpleAccount *account, gpointer data)
-{
- PidginAccountsEnabledMenu *menu = data;
- gint index = -1;
+ if(index >= 0) {
+ g_queue_pop_nth(menu->accounts, index);
- index = g_queue_index(menu->accounts, account);
- if(index >= 0) {
- g_queue_pop_nth(menu->accounts, index);
+ /* Tell the model that we removed one item at the given index. */
+ g_menu_model_items_changed(G_MENU_MODEL(menu), index, 1, 0);
- /* Tell the model that we removed one item at the given index. */
- g_menu_model_items_changed(G_MENU_MODEL(menu), index, 1, 0);
-
- g_object_unref(account);
+ /* Remove the reference to the account that we were holding. */
+ g_object_unref(account);
+ }
}
}
@@ -311,18 +311,18 @@
static void
pidgin_accounts_enabled_menu_init(PidginAccountsEnabledMenu *menu) {
+ PurpleAccountManager *manager = NULL;
gpointer handle = NULL;
menu->accounts = g_queue_new();
+ manager = purple_account_manager_get_default();
+ g_signal_connect_object(manager, "account-changed::enabled",
+ G_CALLBACK(pidgin_accounts_enabled_menu_changed_cb),
+ menu, 0);
+
/* Wire up the purple signals we care about. */
handle = purple_accounts_get_handle();
- purple_signal_connect(handle, "account-enabled", menu,
- G_CALLBACK(pidgin_accounts_enabled_menu_enabled_cb),
- menu);
- purple_signal_connect(handle, "account-disabled", menu,
- G_CALLBACK(pidgin_accounts_enabled_menu_disabled_cb),
- menu);
/* For the account actions, we also need to know when an account is online
* or offline.