--- a/pidgin/pidginapplication.c Sun Nov 19 00:36:19 2023 -0600
+++ b/pidgin/pidginapplication.c Sun Nov 19 00:37:50 2023 -0600
@@ -247,8 +247,8 @@
- * pidgin_action_group_actions_set_enable:
+ * pidgin_action_group_actions_set_enable: (skip) * @group: The #PidginActionGroup instance.
* @actions: The action names.
* @n_actions: The number of @actions.
@@ -259,10 +259,10 @@
pidgin_application_actions_set_enabled(PidginApplication *application,
const gchar *const *actions,
for(i = 0; i < n_actions; i++) {
@@ -640,34 +640,24 @@
* Purple Signal Callbacks
*****************************************************************************/
-pidgin_application_online_cb(gpointer data) {
- gint n_actions = G_N_ELEMENTS(pidgin_application_online_actions);
+pidgin_application_connected_cb(G_GNUC_UNUSED PurpleAccountManager *manager, + PurpleAccount *account, + PidginApplication *application = data; + PurpleProtocol *protocol = NULL; + gboolean should_enable_channel = FALSE; + gboolean should_enable_chat = FALSE; + gboolean should_enable_room_list = FALSE; + n_actions = G_N_ELEMENTS(pidgin_application_online_actions); pidgin_application_actions_set_enabled(PIDGIN_APPLICATION(data),
pidgin_application_online_actions,
-pidgin_application_offline_cb(gpointer data) {
- gint n_actions = G_N_ELEMENTS(pidgin_application_online_actions);
- pidgin_application_actions_set_enabled(PIDGIN_APPLICATION(data),
- pidgin_application_online_actions,
-pidgin_application_signed_on_cb(PurpleAccount *account, gpointer data) {
- PidginApplication *application = PIDGIN_APPLICATION(data);
- PurpleProtocol *protocol = NULL;
- gboolean should_enable_channel = FALSE;
- gboolean should_enable_chat = FALSE;
- gboolean should_enable_room_list = FALSE;
+ /* Now figure out what menus items should be enabled. */ protocol = purple_account_get_protocol(account);
/* We assume that the current state is correct, so we don't bother changing
@@ -708,45 +698,64 @@
-pidgin_application_signed_off_cb(G_GNUC_UNUSED PurpleAccount *account,
+pidgin_application_disconnected_cb(PurpleAccountManager *manager, + G_GNUC_UNUSED PurpleAccount *account, - PidginApplication *application = PIDGIN_APPLICATION(data);
- gboolean should_disable_chat = TRUE, should_disable_room_list = TRUE;
- GList *connections = NULL, *l = NULL;
+ PidginApplication *application = data; + GList *connected = NULL; + gboolean should_disable_actions = TRUE; + gboolean should_disable_chat = TRUE; + gboolean should_disable_channel = TRUE; + gboolean should_disable_room_list = TRUE; - /* walk through all the connections, looking for online ones that implement
- * the chat interface. We don't bother checking the account that this
- * signal was emitted for, because it's already offline and will be
- * filtered out by the online check.
- connections = purple_connections_get_all();
- for(l = connections; l != NULL; l = l->next) {
- PurpleConnection *connection = PURPLE_CONNECTION(l->data);
+ connected = purple_account_manager_get_connected(manager); + while(connected != NULL) { + PurpleAccount *account = connected->data; PurpleProtocol *protocol = NULL;
- /* if the connection isn't online, we don't care about it */
- if(!PURPLE_CONNECTION_IS_CONNECTED(connection)) {
+ /* We have at least one account connected so we're online. */ + should_disable_actions = FALSE; - protocol = purple_connection_get_protocol(connection);
+ protocol = purple_account_get_protocol(account); - /* check if the protocol implements the chat interface */
+ /* Check if the protocol implements the chat interface. */ if(PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, info)) {
should_disable_chat = FALSE;
- /* check if the protocol implements the room list interface */
+ /* Check if the protocol implements joining channels. */ + if(PURPLE_PROTOCOL_IMPLEMENTS(protocol, CONVERSATION, + get_channel_join_details)) + should_disable_channel = FALSE; + /* Check if the protocol implements the room list interface. */ if(PURPLE_PROTOCOL_IMPLEMENTS(protocol, ROOMLIST, get_list)) {
should_disable_room_list = FALSE;
- /* if we can't disable both, we can bail out of the loop */
- if(!should_disable_chat && !should_disable_room_list) {
+ /* If we can't disable anything we can exit the loop early. */ + if(!should_disable_chat && !should_disable_channel && + !should_disable_room_list) + g_clear_list(&connected, NULL); + connected = g_list_delete_link(connected, connected); + if(should_disable_actions) { + n_actions = G_N_ELEMENTS(pidgin_application_online_actions); + pidgin_application_actions_set_enabled(PIDGIN_APPLICATION(data), + pidgin_application_online_actions, if(should_disable_chat) {
@@ -757,6 +766,14 @@
+ if(should_disable_channel) { + n_actions = G_N_ELEMENTS(pidgin_application_channel_actions); + pidgin_application_actions_set_enabled(application, + pidgin_application_channel_actions, if(should_disable_room_list) {
n_actions = G_N_ELEMENTS(pidgin_application_room_list_actions);
pidgin_application_actions_set_enabled(application,
@@ -810,7 +827,6 @@
PurpleAccountManager *manager = NULL;
GList *active_accounts = NULL;
- gpointer handle = NULL;
G_APPLICATION_CLASS(pidgin_application_parent_class)->startup(application);
@@ -924,28 +940,15 @@
/* Populate our dynamic menus. */
pidgin_application_populate_dynamic_menus(PIDGIN_APPLICATION(application));
- /* connect to the online and offline signals in purple connections. This
- * is used to toggle states of actions that require being online.
+ /* Connect to the connected and disconnected signals to manage which menus - handle = purple_connections_get_handle();
- purple_signal_connect(handle, "online", application,
- G_CALLBACK(pidgin_application_online_cb),
- purple_signal_connect(handle, "offline", application,
- G_CALLBACK(pidgin_application_offline_cb),
- /* connect to account-signed-on and account-signed-off to toggle actions
- * that depend on specific interfaces in accounts.
- handle = purple_accounts_get_handle();
- purple_signal_connect(handle, "account-signed-on", application,
- G_CALLBACK(pidgin_application_signed_on_cb),
- purple_signal_connect(handle, "account-signed-off", application,
- G_CALLBACK(pidgin_application_signed_off_cb),
+ g_signal_connect_object(manager, "account-connected", + G_CALLBACK(pidgin_application_connected_cb), + g_signal_connect_object(manager, "account-disconnected", + G_CALLBACK(pidgin_application_disconnected_cb),