pidgin/pidgin

Parents ae3fa963c1b3
Children 3820d0d16092
Replace the account-actions-changed signal with an actions-changed signal on PurpleProtocolActions

We also propagate the PurpleProtocolActions::actions-changed signal from the
PurpleProtocolManager::account-actions-changed signal if the protocol implements
the PurpleProtocolActions interface.

Testing Done:
Build the docs and ran the unit tests.

I also put a temporary action in the demo protocol plugin and called `purple_protocol_actions_changed` after the demo protocol connected. I will have another pull request that makes this a permenent action, but I want to convert the demo protocol plugin to subclass PurpleConnection before doing so as that will be accounting of everything *much* easier.

Reviewed at https://reviews.imfreedom.org/r/2168/
--- 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 @@
* _PurpleSoundEventID
* _PurpleSslConnection
* _XMLNodeType
+ * 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 @@
* PurplePounceEvent
* PurplePounceOption
* PurplePrefsUiOps
+ * 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 @@
### Signal List
* [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
-
-```c
-void user_function(PurpleAccount *account, gpointer user_data);
-```
-
-Emitted when the account actions are changed after initial connection.
-
-**Parameters:**
-
-**account**
-: The account whose actions changed.
-
-**user_data**
-: User data set when the signal handler was connected.
-
-----
-
#### account-signed-on
```c
--- 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_TYPE_ACCOUNT);
-
purple_signal_register(handle, "account-signed-on",
purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
PURPLE_TYPE_ACCOUNT);
--- 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 @@
/* Protocol API */
/**************************************************************************/
void
-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",
- account);
-}
-
-void
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
- * signal.
- *
- * 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,
PurpleAccount *account,
const char *password,
- GError **error)
+ 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));
+ }
}
static void
--- 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"
+enum {
+ SIG_ACTIONS_CHANGED,
+ N_SIGNALS,
+};
+static guint signals[N_SIGNALS] = {0, };
+
/******************************************************************************
* GObject Implementation
*****************************************************************************/
@@ -29,8 +35,28 @@
PURPLE_TYPE_PROTOCOL)
static void
-purple_protocol_actions_default_init(G_GNUC_UNUSED PurpleProtocolActionsInterface *iface)
-{
+purple_protocol_actions_default_init(PurpleProtocolActionsInterface *iface) {
+ /**
+ * PurpleProtocolActions::actions-changed:
+ * @self: The instance.
+ * @account: The [class@Account] whose actions changed.
+ *
+ * A signal that is emitted to tell interested parties that the actions
+ * have changed.
+ *
+ * Since: 3.0.0
+ */
+ signals[SIG_ACTIONS_CHANGED] = g_signal_new_class_handler(
+ "actions-changed",
+ G_TYPE_FROM_INTERFACE(iface),
+ G_SIGNAL_RUN_LAST,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 1,
+ PURPLE_TYPE_ACCOUNT);
}
/******************************************************************************
@@ -86,3 +112,13 @@
return NULL;
}
+
+void
+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
+ * changed.
+ *
+ * Since: 3.0.0
+ */
+void purple_protocol_actions_changed(PurpleProtocolActions *actions, PurpleAccount *account);
+
G_END_DECLS
#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"
+
enum {
SIG_REGISTERED,
SIG_UNREGISTERED,
+ SIG_ACCOUNT_ACTIONS_CHANGED,
N_SIGNALS,
};
static guint signals[N_SIGNALS] = {0, };
@@ -38,6 +41,19 @@
static PurpleProtocolManager *default_manager = NULL;
/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static void
+purple_protocol_manager_actions_changed_cb(PurpleProtocolActions *actions,
+ PurpleAccount *account,
+ gpointer data)
+{
+ /* Propagate the actions-changed signal. */
+ g_signal_emit(data, signals[SIG_ACCOUNT_ACTIONS_CHANGED], 0, actions,
+ account);
+}
+
+/******************************************************************************
* GListModel Implementation
*****************************************************************************/
static GType
@@ -145,6 +161,31 @@
G_TYPE_NONE,
1,
PURPLE_TYPE_PROTOCOL);
+
+ /**
+ * 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].
+ *
+ * Since: 3.0.0
+ */
+ signals[SIG_ACCOUNT_ACTIONS_CHANGED] = g_signal_new_class_handler(
+ "account-actions-changed",
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 2,
+ PURPLE_TYPE_PROTOCOL,
+ PURPLE_TYPE_ACCOUNT);
}
/******************************************************************************
@@ -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),
+ manager, 0);
+ }
+
return TRUE;
}
@@ -218,9 +266,19 @@
if(g_hash_table_remove(manager->protocols, id)) {
guint position;
+
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,
+ manager);
+ }
}
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 @@
G_TYPE_MENU_MODEL)
/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+pidgin_accounts_enabled_menu_update(PidginAccountsEnabledMenu *menu,
+ PurpleAccount *account)
+{
+ PurpleProtocol *protocol = NULL;
+ gint index = -1;
+
+ index = g_queue_index(menu->accounts, account);
+ if(index >= 0) {
+ /* 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,
+ connection);
+ 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),
+ prefix, action_group);
+ g_object_unref(action_group);
+ }
+ }
+}
+
+/******************************************************************************
* Callbacks
*****************************************************************************/
static void
@@ -72,35 +109,7 @@
static void
pidgin_accounts_enabled_menu_connected_cb(PurpleAccount *account, gpointer data)
{
- PidginAccountsEnabledMenu *menu = data;
- PurpleProtocol *protocol = NULL;
- gint index = -1;
-
- index = g_queue_index(menu->accounts, account);
- if(index >= 0) {
- /* 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,
- connection);
- 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),
- prefix, action_group);
- g_object_unref(action_group);
- }
- }
+ pidgin_accounts_enabled_menu_update(data, account);
}
static void
@@ -152,6 +161,15 @@
}
}
+static void
+pidgin_accounts_enabled_menu_actions_changed_cb(G_GNUC_UNUSED PurpleProtocolManager *manager,
+ G_GNUC_UNUSED PurpleProtocol *protocol,
+ PurpleAccount *account,
+ gpointer data)
+{
+ pidgin_accounts_enabled_menu_update(data, account);
+}
+
/******************************************************************************
* GMenuModel Implementation
*****************************************************************************/
@@ -313,6 +331,7 @@
static void
pidgin_accounts_enabled_menu_init(PidginAccountsEnabledMenu *menu) {
PurpleAccountManager *manager = NULL;
+ PurpleProtocolManager *protocol_manager = NULL;
gpointer handle = 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),
menu);
+
+ /* 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),
+ menu, 0);
}
static void