--- a/ChangeLog.API Fri Jan 06 02:10:17 2023 -0600
+++ b/ChangeLog.API Fri Jan 06 02:12:12 2023 -0600
@@ -326,6 +326,8 @@
+ * account-actions-changed signal. Use + PurpleProtocolActions::actions-changed instead. * account-added signal. Use PurpleAccountManager::added instead.
* account-alias-changed signal
* account-authorization-denied, account-authorization-granted,
@@ -663,6 +665,7 @@
+ * purple_protocol_got_account_actions * purple_protocol_got_account_idle
* purple_protocol_got_account_status
* purple_protocol_got_account_status_with_attributes
--- a/doc/reference/libpurple/signals_account.md Fri Jan 06 02:10:17 2023 -0600
+++ b/doc/reference/libpurple/signals_account.md Fri Jan 06 02:12:12 2023 -0600
@@ -6,7 +6,6 @@
* [account-status-changed](#account-status-changed)
-* [account-actions-changed](#account-actions-changed)
* [account-signed-on](#account-signed-on)
* [account-signed-off](#account-signed-off)
@@ -75,24 +74,6 @@
-#### account-actions-changed
-void user_function(PurpleAccount *account, gpointer user_data);
-Emitted when the account actions are changed after initial connection.
-: The account whose actions changed.
-: User data set when the signal handler was connected.
-----
--- a/libpurple/accounts.c Fri Jan 06 02:10:17 2023 -0600
+++ b/libpurple/accounts.c Fri Jan 06 02:12:12 2023 -0600
@@ -649,10 +649,6 @@
G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT,
PURPLE_TYPE_STATUS, PURPLE_TYPE_STATUS);
- purple_signal_register(handle, "account-actions-changed",
- purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
purple_signal_register(handle, "account-signed-on",
purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
--- a/libpurple/protocols.c Fri Jan 06 02:10:17 2023 -0600
+++ b/libpurple/protocols.c Fri Jan 06 02:12:12 2023 -0600
@@ -42,17 +42,6 @@
/**************************************************************************/
-purple_protocol_got_account_actions(PurpleAccount *account)
- g_return_if_fail(account != NULL);
- g_return_if_fail(purple_account_is_connected(account));
- purple_signal_emit(purple_accounts_get_handle(), "account-actions-changed",
purple_protocol_got_user_idle(PurpleAccount *account, const char *name,
gboolean idle, time_t idle_time)
--- a/libpurple/protocols.h Fri Jan 06 02:10:17 2023 -0600
+++ b/libpurple/protocols.h Fri Jan 06 02:12:12 2023 -0600
@@ -41,20 +41,6 @@
/**************************************************************************/
- * purple_protocol_got_account_actions:
- * @account: The account.
- * Notifies Purple that our account's actions have changed. This is only
- * called after the initial connection. Emits the account-actions-changed
- * This is meant to be called from protocols.
- * See <link linkend="accounts-account-actions-changed"><literal>"account-actions-changed"</literal></link>
-void purple_protocol_got_account_actions(PurpleAccount *account);
* purple_protocol_got_user_idle:
* @account: The account the user is on.
* @name: The name of the buddy.
--- a/libpurple/protocols/demo/purpledemoprotocol.c Fri Jan 06 02:10:17 2023 -0600
+++ b/libpurple/protocols/demo/purpledemoprotocol.c Fri Jan 06 02:12:12 2023 -0600
@@ -39,7 +39,7 @@
purple_demo_protocol_create_connection(PurpleProtocol *protocol,
+ G_GNUC_UNUSED GError **error) g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
--- a/libpurple/protocols/jabber/adhoccommands.c Fri Jan 06 02:10:17 2023 -0600
+++ b/libpurple/protocols/jabber/adhoccommands.c Fri Jan 06 02:12:12 2023 -0600
@@ -266,8 +266,12 @@
js->commands = g_list_append(js->commands,cmd);
- if (js->state == JABBER_STREAM_CONNECTED)
- purple_protocol_got_account_actions(purple_connection_get_account(js->gc));
+ if (js->state == JABBER_STREAM_CONNECTED) { + PurpleProtocol *protocol = purple_connection_get_protocol(js->gc); + purple_protocol_actions_changed(PURPLE_PROTOCOL_ACTIONS(protocol), + purple_connection_get_account(js->gc)); --- a/libpurple/purpleprotocolactions.c Fri Jan 06 02:10:17 2023 -0600
+++ b/libpurple/purpleprotocolactions.c Fri Jan 06 02:12:12 2023 -0600
@@ -22,6 +22,12 @@
#include "purpleprotocolactions.h"
+static guint signals[N_SIGNALS] = {0, }; /******************************************************************************
*****************************************************************************/
@@ -29,8 +35,28 @@
-purple_protocol_actions_default_init(G_GNUC_UNUSED PurpleProtocolActionsInterface *iface)
+purple_protocol_actions_default_init(PurpleProtocolActionsInterface *iface) { + * PurpleProtocolActions::actions-changed: + * @account: The [class@Account] whose actions changed. + * A signal that is emitted to tell interested parties that the actions + signals[SIG_ACTIONS_CHANGED] = g_signal_new_class_handler( + G_TYPE_FROM_INTERFACE(iface), /******************************************************************************
@@ -86,3 +112,13 @@
+purple_protocol_actions_changed(PurpleProtocolActions *actions, + PurpleAccount *account) + g_return_if_fail(PURPLE_IS_PROTOCOL_ACTIONS(actions)); + g_return_if_fail(PURPLE_IS_ACCOUNT(account)); + g_signal_emit(actions, signals[SIG_ACTIONS_CHANGED], 0, account); --- a/libpurple/purpleprotocolactions.h Fri Jan 06 02:10:17 2023 -0600
+++ b/libpurple/purpleprotocolactions.h Fri Jan 06 02:12:12 2023 -0600
@@ -119,6 +119,19 @@
GMenu *purple_protocol_actions_get_menu(PurpleProtocolActions *actions, PurpleConnection *connection);
+ * purple_protocol_actions_changed: + * @actions: The instance. + * @account: The [class@Account] whose actions changed. + * Emits the [signal@ProtocolActions::actions-changed] signal. This is meant to + * be called by [iface@ProtocolActions] implementations when actions have +void purple_protocol_actions_changed(PurpleProtocolActions *actions, PurpleAccount *account); #endif /* PURPLE_PROTOCOL_ACTIONS_H */
--- a/libpurple/purpleprotocolmanager.c Fri Jan 06 02:10:17 2023 -0600
+++ b/libpurple/purpleprotocolmanager.c Fri Jan 06 02:12:12 2023 -0600
@@ -21,9 +21,12 @@
#include "purpleprotocolmanager.h"
#include "purpleprivate.h"
+#include "purpleprotocolactions.h" + SIG_ACCOUNT_ACTIONS_CHANGED, static guint signals[N_SIGNALS] = {0, };
@@ -38,6 +41,19 @@
static PurpleProtocolManager *default_manager = NULL;
/******************************************************************************
+ *****************************************************************************/ +purple_protocol_manager_actions_changed_cb(PurpleProtocolActions *actions, + PurpleAccount *account, + /* Propagate the actions-changed signal. */ + g_signal_emit(data, signals[SIG_ACCOUNT_ACTIONS_CHANGED], 0, actions, +/****************************************************************************** * GListModel Implementation
*****************************************************************************/
@@ -145,6 +161,31 @@
+ * PurpleProtocolManager::account-actions-changed: + * @manager: The instance. + * @protocol: The [class@Protocol] whose actions changed. + * @account: The [class@Account] whose actions changed. + * This is a propagation of the [signal@ProtocolActions::actions-changed] + * signal and will only be emitted for protocols that implement + * [iface@ProtocolActions]. + signals[SIG_ACCOUNT_ACTIONS_CHANGED] = g_signal_new_class_handler( + "account-actions-changed", + G_OBJECT_CLASS_TYPE(klass), /******************************************************************************
@@ -194,6 +235,13 @@
g_signal_emit(G_OBJECT(manager), signals[SIG_REGISTERED], 0, protocol);
+ /* Connect the signals we want to propagate. */ + if(PURPLE_IS_PROTOCOL_ACTIONS(protocol)) { + g_signal_connect_object(protocol, "actions-changed", + G_CALLBACK(purple_protocol_manager_actions_changed_cb), @@ -218,9 +266,19 @@
if(g_hash_table_remove(manager->protocols, id)) {
if(g_ptr_array_find(manager->list, protocol, &position)) {
g_ptr_array_remove_index(manager->list, position);
g_list_model_items_changed(G_LIST_MODEL(manager), position, 1, 0);
+ /* Disconnect our signal handlers for tracking changes if this is a + * PurpleProtocolActions implementation. + if(PURPLE_IS_PROTOCOL_ACTIONS(protocol)) { + g_signal_handlers_disconnect_by_func(protocol, + purple_protocol_manager_actions_changed_cb, g_signal_emit(G_OBJECT(manager), signals[SIG_UNREGISTERED], 0,
--- a/pidgin/pidginaccountsenabledmenu.c Fri Jan 06 02:10:17 2023 -0600
+++ b/pidgin/pidginaccountsenabledmenu.c Fri Jan 06 02:12:12 2023 -0600
@@ -38,6 +38,43 @@
/******************************************************************************
+ *****************************************************************************/ +pidgin_accounts_enabled_menu_update(PidginAccountsEnabledMenu *menu, + PurpleAccount *account) + PurpleProtocol *protocol = NULL; + index = g_queue_index(menu->accounts, account); + /* Tell the model that the account needs to be updated. */ + g_menu_model_items_changed(G_MENU_MODEL(menu), index, 0, 0); + /* If the protocol has actions add them to the application windows. */ + protocol = purple_account_get_protocol(account); + if(PURPLE_IS_PROTOCOL_ACTIONS(protocol)) { + PurpleProtocolActions *actions = PURPLE_PROTOCOL_ACTIONS(protocol); + PurpleConnection *connection = NULL; + GActionGroup *action_group = NULL; + connection = purple_account_get_connection(account); + action_group = purple_protocol_actions_get_action_group(actions, + if(G_IS_ACTION_GROUP(action_group)) { + GApplication *application = g_application_get_default(); + const gchar *prefix = purple_protocol_actions_get_prefix(actions); + pidgin_application_add_action_group(PIDGIN_APPLICATION(application), + g_object_unref(action_group); +/****************************************************************************** *****************************************************************************/
@@ -72,35 +109,7 @@
pidgin_accounts_enabled_menu_connected_cb(PurpleAccount *account, gpointer data)
- PidginAccountsEnabledMenu *menu = data;
- PurpleProtocol *protocol = NULL;
- index = g_queue_index(menu->accounts, account);
- /* Tell the model that the account needs to be updated. */
- g_menu_model_items_changed(G_MENU_MODEL(menu), index, 0, 0);
- /* If the protocol has actions add them to the application windows. */
- protocol = purple_account_get_protocol(account);
- if(PURPLE_IS_PROTOCOL_ACTIONS(protocol)) {
- PurpleProtocolActions *actions = PURPLE_PROTOCOL_ACTIONS(protocol);
- PurpleConnection *connection = NULL;
- GActionGroup *action_group = NULL;
- connection = purple_account_get_connection(account);
- action_group = purple_protocol_actions_get_action_group(actions,
- if(G_IS_ACTION_GROUP(action_group)) {
- GApplication *application = g_application_get_default();
- const gchar *prefix = purple_protocol_actions_get_prefix(actions);
- pidgin_application_add_action_group(PIDGIN_APPLICATION(application),
- g_object_unref(action_group);
+ pidgin_accounts_enabled_menu_update(data, account); @@ -152,6 +161,15 @@
+pidgin_accounts_enabled_menu_actions_changed_cb(G_GNUC_UNUSED PurpleProtocolManager *manager, + G_GNUC_UNUSED PurpleProtocol *protocol, + PurpleAccount *account, + pidgin_accounts_enabled_menu_update(data, account); /******************************************************************************
* GMenuModel Implementation
*****************************************************************************/
@@ -313,6 +331,7 @@
pidgin_accounts_enabled_menu_init(PidginAccountsEnabledMenu *menu) {
PurpleAccountManager *manager = NULL;
+ PurpleProtocolManager *protocol_manager = NULL; menu->accounts = g_queue_new();
@@ -334,6 +353,12 @@
purple_signal_connect(handle, "account-signed-off", menu,
G_CALLBACK(pidgin_accounts_enabled_menu_disconnected_cb),
+ /* We also need to know when the protocol actions have changed. */ + protocol_manager = purple_protocol_manager_get_default(); + g_signal_connect_object(protocol_manager, "account-actions-changed", + G_CALLBACK(pidgin_accounts_enabled_menu_actions_changed_cb),