Migrate the accounts menu to its own set of widgets

Mon, 06 Apr 2020 22:27:40 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Mon, 06 Apr 2020 22:27:40 -0500
changeset 40379
c50c509dd028
parent 40378
9713b0ef6504
child 40380
665ba7e7acbc

Migrate the accounts menu to its own set of widgets

pidgin/glade/pidgin3.xml.in file | annotate | diff | comparison | revisions
pidgin/gtkblist.c file | annotate | diff | comparison | revisions
pidgin/meson.build file | annotate | diff | comparison | revisions
pidgin/pidginaccountactionsmenu.c file | annotate | diff | comparison | revisions
pidgin/pidginaccountactionsmenu.h file | annotate | diff | comparison | revisions
pidgin/pidginaccountsmenu.c file | annotate | diff | comparison | revisions
pidgin/pidginaccountsmenu.h file | annotate | diff | comparison | revisions
pidgin/pidginactiongroup.c file | annotate | diff | comparison | revisions
pidgin/pidginactiongroup.h file | annotate | diff | comparison | revisions
pidgin/pidginbuddylistmenu.c file | annotate | diff | comparison | revisions
pidgin/pidginpluginsmenu.h file | annotate | diff | comparison | revisions
pidgin/resources/Accounts/actionsmenu.ui file | annotate | diff | comparison | revisions
pidgin/resources/Accounts/menu.ui file | annotate | diff | comparison | revisions
pidgin/resources/BuddyList/menu.ui file | annotate | diff | comparison | revisions
pidgin/resources/pidgin.gresource.xml file | annotate | diff | comparison | revisions
--- a/pidgin/glade/pidgin3.xml.in	Wed Apr 01 13:08:57 2020 -0500
+++ b/pidgin/glade/pidgin3.xml.in	Mon Apr 06 22:27:40 2020 -0500
@@ -2,6 +2,7 @@
 <glade-catalog name="pidgin" version="@PURPLE_MAJOR_VERSION@.@PURPLE_MINOR_VERSION@" library="pidgin3">
   <glade-widget-classes>
     <glade-widget-class name="PidginAccountChooser" generic-name="account_chooser" title="AccountChooser"/>
+    <glade-widget-class name="PidginAccountsMenu" generic-name="accounts_menu" title="AccountsMenu"/>
     <glade-widget-class name="PidginInviteDialog" generic-name="invite_dialog" title="InviteDialog"/>
     <glade-widget-class name="PidginMenuTray" generic-name="menu_tray" title="MenuTray"/>
     <glade-widget-class name="PidginPluginsMenu" generic-name="plugins_menu" title="PluginsMenu"/>
@@ -9,6 +10,7 @@
   </glade-widget-classes>
   <glade-widget-group name="pidgin" title="Pidgin">
     <glade-widget-class-ref name="PidginAccountChooser"/>
+    <glade-widget-class-ref name="PidginAccountsMenu"/>
     <glade-widget-class-ref name="PidginInviteDialog"/>
     <glade-widget-class-ref name="PidginMenuTray"/>
     <glade-widget-class-ref name="PidginPluginsMenu"/>
--- a/pidgin/gtkblist.c	Wed Apr 01 13:08:57 2020 -0500
+++ b/pidgin/gtkblist.c	Mon Apr 06 22:27:40 2020 -0500
@@ -137,8 +137,6 @@
 	(gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(x))) & \
 	GDK_WINDOW_STATE_MAXIMIZED)
 
-static GtkWidget *accountmenu = NULL;
-
 static guint visibility_manager_count = 0;
 static GdkVisibilityState gtk_blist_visibility = GDK_VISIBILITY_UNOBSCURED;
 static gboolean gtk_blist_focused = FALSE;
@@ -3517,13 +3515,7 @@
 /***************************************************
  *            Crap                                 *
  ***************************************************/
-/* TODO: fill out tooltips... */
 static const GtkActionEntry blist_menu_entries[] = {
-/* NOTE: Do not set any accelerator to Control+O. It is mapped by
-   gtk_blist_key_press_cb to "Get User Info" on the selected buddy. */
-	/* Accounts menu */
-	{ "AccountsMenu", NULL, N_("_Accounts"), NULL, NULL, NULL },
-
 	/* Tools */
 	{ "ToolsMenu", NULL, N_("_Tools"), NULL, NULL, NULL },
 	{ "SetMood", NULL, N_("Set _Mood"), "<control>D", NULL, set_mood_show },
@@ -3532,8 +3524,6 @@
 static const char *blist_menu =
 "<ui>"
 	"<menubar name='BList'>"
-		"<menu action='AccountsMenu'>"
-		"</menu>"
 		"<menu action='ToolsMenu'>"
 			"<menuitem action='SetMood'/>"
 		"</menu>"
@@ -4358,8 +4348,6 @@
 
 	g_return_if_fail(gtkblist != NULL);
 
-	pidgin_blist_update_accounts_menu();
-
 	sensitive = (purple_connections_get_all() != NULL);
 
 	for (i = 0; i < require_connection_size; i++)
@@ -4735,12 +4723,6 @@
 }
 
 static void
-account_actions_changed(PurpleAccount *account, gpointer data)
-{
-	pidgin_blist_update_accounts_menu();
-}
-
-static void
 account_status_changed(PurpleAccount *account, PurpleStatus *old,
 					   PurpleStatus *new, PidginBuddyList *gtkblist)
 {
@@ -5592,9 +5574,6 @@
 	gtk_widget_show(menu);
 	gtk_box_pack_start(GTK_BOX(gtkblist->main_vbox), menu, FALSE, FALSE, 0);
 
-	menu = gtk_ui_manager_get_widget(gtkblist->ui, "/BList/AccountsMenu");
-	accountmenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu));
-
 	gtkblist->menu = pidgin_buddy_list_menu_new();
 	gtk_box_pack_start(GTK_BOX(gtkblist->main_vbox), gtkblist->menu, FALSE,
 	                   FALSE, 0);
@@ -5813,8 +5792,6 @@
 	purple_signal_connect(handle, "account-error-changed", gtkblist,
 	                      PURPLE_CALLBACK(update_account_error_state),
 	                      gtkblist);
-	purple_signal_connect(handle, "account-actions-changed", gtkblist,
-	                      PURPLE_CALLBACK(account_actions_changed), NULL);
 
 	handle = pidgin_accounts_get_handle();
 	purple_signal_connect(handle, "account-modified", gtkblist,
@@ -7254,7 +7231,6 @@
 	purple_signals_unregister_by_instance(pidgin_blist_get_handle());
 	purple_signals_disconnect_by_handle(pidgin_blist_get_handle());
 
-	accountmenu = NULL;
 	gtkblist = NULL;
 }
 
@@ -7645,224 +7621,6 @@
 	}
 }
 
-static void
-modify_account_cb(GtkWidget *widget, gpointer data)
-{
-	pidgin_account_dialog_show(PIDGIN_MODIFY_ACCOUNT_DIALOG, data);
-}
-
-static void
-enable_account_cb(GtkCheckMenuItem *widget, gpointer data)
-{
-	PurpleAccount *account = data;
-	const PurpleSavedStatus *saved_status;
-
-	saved_status = purple_savedstatus_get_current();
-	purple_savedstatus_activate_for_account(saved_status, account);
-
-	purple_account_set_enabled(account, PIDGIN_UI, TRUE);
-}
-
-static void
-disable_account_cb(GtkCheckMenuItem *widget, gpointer data)
-{
-	PurpleAccount *account = data;
-
-	purple_account_set_enabled(account, PIDGIN_UI, FALSE);
-}
-
-static void
-protocol_act(GtkWidget *obj, PurpleProtocolAction *pam)
-{
-	if (pam && pam->callback)
-		pam->callback(pam);
-}
-
-void
-pidgin_blist_update_accounts_menu(void)
-{
-	GtkWidget *menuitem, *submenu;
-	GtkAccelGroup *accel_group;
-	GList *l, *accounts;
-	gboolean disabled_accounts = FALSE;
-	gboolean enabled_accounts = FALSE;
-
-	if (accountmenu == NULL)
-		return;
-
-	/* Clear the old Accounts menu */
-	for (l = gtk_container_get_children(GTK_CONTAINER(accountmenu)); l; l = g_list_delete_link(l, l)) {
-		menuitem = l->data;
-
-		if (menuitem != gtk_ui_manager_get_widget(gtkblist->ui, "/BList/AccountsMenu/ManageAccounts"))
-			gtk_widget_destroy(menuitem);
-	}
-
-	accel_group = gtk_menu_get_accel_group(GTK_MENU(accountmenu));
-
-	for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
-		char *buf = NULL;
-		GtkWidget *image = NULL;
-		PurpleAccount *account = NULL;
-		GdkPixbuf *pixbuf = NULL;
-
-		account = accounts->data;
-
-		if (!purple_account_get_enabled(account, PIDGIN_UI)) {
-			if (!disabled_accounts) {
-				menuitem = gtk_menu_item_new_with_label(_("Enable Account"));
-				gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
-
-				submenu = gtk_menu_new();
-				gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
-				gtk_menu_set_accel_path(GTK_MENU(submenu), "<Actions>/BListActions/EnableAccount");
-				gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-
-				disabled_accounts = TRUE;
-			}
-
-			buf = g_strconcat(purple_account_get_username(account), " (",
-				purple_account_get_protocol_name(account), ")", NULL);
-			menuitem = gtk_image_menu_item_new_with_label(buf);
-			g_free(buf);
-
-			pixbuf = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_SMALL);
-			if (pixbuf != NULL) {
-				if (!purple_account_is_connected(account))
-					gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
-				image = gtk_image_new_from_pixbuf(pixbuf);
-				g_object_unref(G_OBJECT(pixbuf));
-				gtk_widget_show(image);
-				gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
-			}
-
-			g_signal_connect(G_OBJECT(menuitem), "activate",
-				G_CALLBACK(enable_account_cb), account);
-			gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-
-		} else {
-			enabled_accounts = TRUE;
-		}
-	}
-
-	if (!enabled_accounts) {
-		gtk_widget_show_all(accountmenu);
-		return;
-	}
-
-	pidgin_separator(accountmenu);
-
-	for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
-		char *buf = NULL;
-		char *accel_path_buf = NULL;
-		GtkWidget *image = NULL;
-		PurpleConnection *gc = NULL;
-		PurpleAccount *account = NULL;
-		GdkPixbuf *pixbuf = NULL;
-		PurpleProtocol *protocol;
-
-		account = accounts->data;
-
-		if (!purple_account_get_enabled(account, PIDGIN_UI))
-			continue;
-
-		buf = g_strconcat(purple_account_get_username(account), " (",
-				purple_account_get_protocol_name(account), ")", NULL);
-		menuitem = gtk_image_menu_item_new_with_label(buf);
-		accel_path_buf = g_strconcat("<Actions>/AccountActions/", buf, NULL);
-		g_free(buf);
-
-		pixbuf = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_SMALL);
-		if (pixbuf != NULL) {
-			if (!purple_account_is_connected(account))
-				gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf,
-						0.0, FALSE);
-			image = gtk_image_new_from_pixbuf(pixbuf);
-			g_object_unref(G_OBJECT(pixbuf));
-			gtk_widget_show(image);
-			gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
-		}
-
-		gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
-
-		submenu = gtk_menu_new();
-		gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
-		gtk_menu_set_accel_path(GTK_MENU(submenu), accel_path_buf);
-		g_free(accel_path_buf);
-		gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-
-		menuitem = gtk_menu_item_new_with_mnemonic(_("_Edit Account"));
-		g_signal_connect(G_OBJECT(menuitem), "activate",
-				G_CALLBACK(modify_account_cb), account);
-		gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-
-		pidgin_separator(submenu);
-
-		gc = purple_account_get_connection(account);
-		protocol = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ?
-				purple_connection_get_protocol(gc) : NULL;
-
-		if (protocol &&
-		    (PURPLE_PROTOCOL_IMPLEMENTS(protocol, CLIENT, get_moods) ||
-			 PURPLE_PROTOCOL_IMPLEMENTS(protocol, CLIENT, get_actions))) {
-			if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, CLIENT, get_moods) &&
-			    (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_SUPPORT_MOODS)) {
-
-				if (purple_account_get_status(account, "mood")) {
-					menuitem = gtk_menu_item_new_with_mnemonic(_("Set _Mood..."));
-					g_signal_connect(G_OBJECT(menuitem), "activate",
-					         	G_CALLBACK(set_mood_cb), account);
-					gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-				}
-			}
-
-			if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, CLIENT, get_actions)) {
-				GtkWidget *menuitem;
-				PurpleProtocolAction *action = NULL;
-				GList *actions, *l;
-
-				actions = purple_protocol_client_iface_get_actions(protocol, gc);
-
-				for (l = actions; l != NULL; l = l->next)
-				{
-					if (l->data)
-					{
-						action = (PurpleProtocolAction *) l->data;
-						action->connection = gc;
-
-						menuitem = gtk_menu_item_new_with_label(action->label);
-						gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-
-						g_signal_connect(G_OBJECT(menuitem), "activate",
-								G_CALLBACK(protocol_act), action);
-						g_object_set_data_full(G_OBJECT(menuitem), "protocol_action",
-											   action,
-											   (GDestroyNotify)purple_protocol_action_free);
-						gtk_widget_show(menuitem);
-					}
-					else
-						pidgin_separator(submenu);
-				}
-
-				g_list_free(actions);
-			}
-		} else {
-			menuitem = gtk_menu_item_new_with_label(_("No actions available"));
-			gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-			gtk_widget_set_sensitive(menuitem, FALSE);
-		}
-
-		pidgin_separator(submenu);
-
-		menuitem = gtk_menu_item_new_with_mnemonic(_("_Disable"));
-		g_signal_connect(G_OBJECT(menuitem), "activate",
-				G_CALLBACK(disable_account_cb), account);
-		gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-	}
-
-	gtk_widget_show_all(accountmenu);
-}
-
 void
 pidgin_blist_update_sort_methods(void)
 {
--- a/pidgin/meson.build	Wed Apr 01 13:08:57 2020 -0500
+++ b/pidgin/meson.build	Mon Apr 06 22:27:40 2020 -0500
@@ -34,7 +34,9 @@
 	'libpidgin.c',
 	'minidialog.c',
 	'pidginabout.c',
+	'pidginaccountactionsmenu.c',
 	'pidginaccountchooser.c',
+	'pidginaccountsmenu.c',
 	'pidginactiongroup.c',
 	'pidginbuddylistmenu.c',
 	'pidgincontactcompletion.c',
@@ -90,7 +92,9 @@
 	'gtkxfer.h',
 	'minidialog.h',
 	'pidginabout.h',
+	'pidginaccountactionsmenu.c',
 	'pidginaccountchooser.h',
+	'pidginaccountsmenu.c',
 	'pidginactiongroup.h',
 	'pidginbuddylistmenu.h',
 	'pidgincontactcompletion.h',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountactionsmenu.c	Mon Apr 06 22:27:40 2020 -0500
@@ -0,0 +1,284 @@
+/*
+ * pidgin
+ *
+ * Pidgin is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+
+#include "pidginaccountactionsmenu.h"
+
+#include <purple.h>
+
+#include "internal.h"
+
+#include "pidgin/pidgin.h"
+#include "pidgin/gtkaccount.h"
+
+struct _PidginAccountActionsMenu {
+	GtkMenu parent;
+
+	GtkWidget *separator;
+
+	PurpleAccount *account;
+};
+
+enum {
+	PROP_ZERO,
+	PROP_ACCOUNT,
+	N_PROPERTIES
+};
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
+/******************************************************************************
+ * GSignal Handlers
+ *****************************************************************************/
+static void
+pidgin_account_actions_menu_edit_cb(GtkMenuItem *item, gpointer data) {
+	PidginAccountActionsMenu *menu = PIDGIN_ACCOUNT_ACTIONS_MENU(data);
+
+	pidgin_account_dialog_show(PIDGIN_MODIFY_ACCOUNT_DIALOG, menu->account);
+}
+
+static void
+pidgin_account_actions_menu_disable_cb(GtkMenuItem *item, gpointer data) {
+	PidginAccountActionsMenu *menu = PIDGIN_ACCOUNT_ACTIONS_MENU(data);
+
+	purple_account_set_enabled(menu->account, PIDGIN_UI, FALSE);
+}
+
+static void
+pidgin_account_actions_menu_action(GtkMenuItem *item, gpointer data) {
+	PurpleProtocolAction *action = (PurpleProtocolAction *)data;
+
+	if(action && action->callback) {
+		action->callback(action);
+	}
+}
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+pidgin_account_actions_menu_set_account(PidginAccountActionsMenu *menu,
+                                        PurpleAccount *account)
+{
+	PurpleConnection *connection = NULL;
+	PurpleProtocol *protocol = NULL;
+	GList *children = NULL, *l = NULL;
+	gboolean items_added = FALSE;
+	gint position = 0;
+
+	g_clear_object(&menu->account);
+
+	if(!PURPLE_IS_ACCOUNT(account)) {
+		return;
+	}
+
+	menu->account = PURPLE_ACCOUNT(g_object_ref(G_OBJECT(account)));
+
+	connection = purple_account_get_connection(account);
+	if(connection == NULL) {
+		return;
+	}
+
+	if(!PURPLE_CONNECTION_IS_CONNECTED(connection)) {
+		return;
+	}
+
+	/* we're pretty sure we're going to insert some items into the menu, so we
+	 * need to figure out where to put them.  GtkMenu stores its children in
+	 * order, so we just need to walk them to find the proper position.
+	 */
+	children = gtk_container_get_children(GTK_CONTAINER(menu));
+	for(l = children, position = 0; l != NULL; l = l->next, position++) {
+		/* check if the widget is our separator and if so, bail out of the
+		 * loop.
+		 */
+		if(l->data == menu->separator) {
+			/* and push position past the separator */
+			position++;
+
+			break;
+		}
+	}
+	g_list_free(children);
+
+	protocol = purple_connection_get_protocol(connection);
+	if(PURPLE_PROTOCOL_IMPLEMENTS(protocol, CLIENT, get_actions)) {
+		GtkWidget *item = NULL;
+		GList *actions = NULL, *l = NULL;
+
+		actions = purple_protocol_client_iface_get_actions(protocol,
+		                                                   connection);
+
+		for(l = actions; l; l = l->next) {
+			PurpleProtocolAction *action = (PurpleProtocolAction *)l->data;
+
+			if(action == NULL) {
+				item = gtk_separator_menu_item_new();
+				gtk_menu_shell_insert(GTK_MENU_SHELL(menu), item, position++);
+				gtk_widget_show(item);
+
+				continue;
+			}
+
+			if(action->label == NULL) {
+				purple_protocol_action_free(action);
+
+				continue;
+			}
+
+			/* now add the action */
+			item = gtk_menu_item_new_with_label(action->label);
+			g_signal_connect_data(G_OBJECT(item), "activate",
+			                      G_CALLBACK(pidgin_account_actions_menu_action),
+			                      action,
+			                      (GClosureNotify)purple_protocol_action_free,
+			                      0);
+			gtk_menu_shell_insert(GTK_MENU_SHELL(menu), item, position++);
+			gtk_widget_show(item);
+
+			/* since we added an item, make sure items_added is true */
+			items_added = TRUE;
+		}
+
+		g_list_free(actions);
+	}
+
+	/* if we added any items, make our separator visible. */
+	if(items_added) {
+		gtk_widget_show(menu->separator);
+	}
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+G_DEFINE_TYPE(PidginAccountActionsMenu, pidgin_account_actions_menu,
+              GTK_TYPE_MENU)
+
+static void
+pidgin_account_actions_menu_get_property(GObject *obj, guint param_id,
+                                         GValue *value, GParamSpec *pspec)
+{
+	PidginAccountActionsMenu *menu = PIDGIN_ACCOUNT_ACTIONS_MENU(obj);
+
+	switch(param_id) {
+		case PROP_ACCOUNT:
+			g_value_set_object(value,
+			                   pidgin_account_actions_menu_get_account(menu));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+			break;
+	}
+}
+
+static void
+pidgin_account_actions_menu_set_property(GObject *obj, guint param_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec)
+{
+	PidginAccountActionsMenu *menu = PIDGIN_ACCOUNT_ACTIONS_MENU(obj);
+
+	switch(param_id) {
+		case PROP_ACCOUNT:
+			pidgin_account_actions_menu_set_account(menu,
+			                                        g_value_get_object(value));
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+			break;
+	}
+}
+
+static void
+pidgin_account_actions_menu_finalize(GObject *obj) {
+	PidginAccountActionsMenu *menu = PIDGIN_ACCOUNT_ACTIONS_MENU(obj);
+
+	g_clear_object(&menu->account);
+
+	G_OBJECT_CLASS(pidgin_account_actions_menu_parent_class)->finalize(obj);
+}
+
+static void
+pidgin_account_actions_menu_init(PidginAccountActionsMenu *menu) {
+	/* initialize our template */
+	gtk_widget_init_template(GTK_WIDGET(menu));
+};
+
+static void
+pidgin_account_actions_menu_class_init(PidginAccountActionsMenuClass *klass) {
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+    gtk_widget_class_set_template_from_resource(
+        widget_class,
+        "/im/pidgin/Pidgin/Accounts/actionsmenu.ui"
+    );
+
+	obj_class->get_property = pidgin_account_actions_menu_get_property;
+	obj_class->set_property = pidgin_account_actions_menu_set_property;
+	obj_class->finalize = pidgin_account_actions_menu_finalize;
+
+	/**
+	 * PidginAccountActionsMenu::account:
+	 *
+	 * The #PurpleAccount that this menu was created for.
+	 */
+	properties[PROP_ACCOUNT] =
+		g_param_spec_object("account", "account",
+		                    "The account this menu is for",
+		                    PURPLE_TYPE_ACCOUNT,
+		                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+		                    G_PARAM_STATIC_STRINGS);
+
+	g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+
+	gtk_widget_class_bind_template_child(widget_class, PidginAccountActionsMenu,
+	                                     separator);
+
+   	gtk_widget_class_bind_template_callback(widget_class,
+   	                                        pidgin_account_actions_menu_edit_cb);
+   	gtk_widget_class_bind_template_callback(widget_class,
+   	                                        pidgin_account_actions_menu_disable_cb);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+GtkWidget *
+pidgin_account_actions_menu_new(PurpleAccount *account) {
+	GObject *obj = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
+
+	obj = g_object_new(PIDGIN_TYPE_ACCOUNT_ACTIONS_MENU,
+	                   "account", account,
+	                   NULL);
+
+	return GTK_WIDGET(obj);
+}
+
+PurpleAccount *
+pidgin_account_actions_menu_get_account(PidginAccountActionsMenu *menu) {
+	g_return_val_if_fail(PIDGIN_IS_ACCOUNT_ACTIONS_MENU(menu), NULL);
+
+	return menu->account;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountactionsmenu.h	Mon Apr 06 22:27:40 2020 -0500
@@ -0,0 +1,67 @@
+/*
+ * pidgin
+ *
+ * Pidgin is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+#ifndef PIDGIN_ACCOUNT_ACTIONS_MENU_H
+#define PIDGIN_ACCOUNT_ACTIONS_MENU_H
+
+/**
+ * SECTION:pidginaccountactionsmenu
+ * @section_id: pidgin-account-actions-menu
+ * @short_description: A menu for managing account actions
+ * @title: Accounts Actions Menu
+ *
+ * #PidginAccountActionsMenu is a #GtkMenu that provides an interface to users
+ * edit accounts and activate its actions.
+ */
+
+#include <gtk/gtk.h>
+
+#include <purple.h>
+
+G_BEGIN_DECLS
+
+#define PIDGIN_TYPE_ACCOUNT_ACTIONS_MENU (pidgin_account_actions_menu_get_type())
+G_DECLARE_FINAL_TYPE(PidginAccountActionsMenu, pidgin_account_actions_menu,
+                     PIDGIN, ACCOUNT_ACTIONS_MENU, GtkMenu)
+
+/**
+ * pidgin_account_actions_menu_new:
+ * @account: The #PurpleAccount that this menu is for.
+ *
+ * Creates a new #PidginAccountActionsMenu for @account.
+ *
+ * Returns: (transfer full): The new #PidginAccountActionsMenu instance.
+ */
+GtkWidget *pidgin_account_actions_menu_new(PurpleAccount *account);
+
+/**
+ * pidgin_account_actions_menu_get_account:
+ * @menu: The #PidginAccountActionsMenu instance.
+ *
+ * Gets the #PurpleAccount associated with @menu.
+ *
+ * Returns: (transfer none): The #PurpleAccount associated with @menu.
+ */
+PurpleAccount *pidgin_account_actions_menu_get_account(PidginAccountActionsMenu *menu);
+
+G_END_DECLS
+
+#endif /* PIDGIN_ACCOUNT_ACTIONS_MENU_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountsmenu.c	Mon Apr 06 22:27:40 2020 -0500
@@ -0,0 +1,248 @@
+/*
+ * pidgin
+ *
+ * Pidgin is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+
+#include "pidginaccountsmenu.h"
+
+#include <purple.h>
+
+#include "internal.h"
+
+#include "pidgin/gtkaccount.h"
+#include "pidgin/pidgin.h"
+#include "pidgin/pidginaccountactionsmenu.h"
+
+struct _PidginAccountsMenu {
+	GtkMenu parent;
+
+	GtkWidget *disabled_menu;
+	GtkWidget *separator;
+
+	GHashTable *account_items;
+	GHashTable *disabled_items;
+};
+
+/******************************************************************************
+ * GSignal Handlers
+ *****************************************************************************/
+static void
+pidgin_accounts_menu_open_manager_cb(GtkMenuItem *item, gpointer data) {
+	pidgin_accounts_window_show();
+}
+
+static void
+pidgin_accounts_menu_enable_account(GtkMenuItem *item, gpointer data) {
+	PurpleAccount *account = PURPLE_ACCOUNT(data);
+
+	purple_account_set_enabled(account, PIDGIN_UI, TRUE);
+}
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static GtkWidget *
+pidgin_accounts_menu_create_account_menu_item(PidginAccountsMenu *menu,
+                                              PurpleAccount *account)
+{
+	GtkWidget *item = NULL;
+	const gchar *account_name = purple_account_get_username(account);
+	const gchar *protocol_name = purple_account_get_protocol_name(account);
+	gchar *label = g_strdup_printf("%s (%s)", account_name, protocol_name);
+
+	item = gtk_menu_item_new_with_label(label);
+	g_free(label);
+	gtk_widget_show(item);
+
+	return item;
+}
+
+static void
+pidgin_accounts_menu_add_enabled_account(PidginAccountsMenu *menu,
+                                         PurpleAccount *account)
+{
+	GtkWidget *item = NULL, *submenu = NULL;
+	gpointer data = NULL;
+
+	/* if the account is in the disabled list, delete its widget */
+	data = g_hash_table_lookup(menu->disabled_items, account);
+	if(data != NULL) {
+		gtk_widget_destroy(GTK_WIDGET(data));
+	}
+
+	item = pidgin_accounts_menu_create_account_menu_item(menu, account);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+	g_hash_table_insert(menu->account_items,
+	                    g_object_ref(G_OBJECT(account)),
+	                    item);
+
+	/* create the submenu and attach it to item right away, this allows us to
+	 * reuse item for the submenu items.
+	 */
+	submenu = pidgin_account_actions_menu_new(account);
+	gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
+}
+
+static void
+pidgin_accounts_menu_add_disabled_account(PidginAccountsMenu *menu,
+                                          PurpleAccount *account)
+{
+	GtkWidget *item = NULL;
+	gpointer data = NULL;
+
+	/* if the account is in the enabled list, delete its widget */
+	data = g_hash_table_lookup(menu->account_items, account);
+	if(data != NULL) {
+		gtk_widget_destroy(GTK_WIDGET(data));
+	}
+
+	item = pidgin_accounts_menu_create_account_menu_item(menu, account);
+	g_signal_connect(G_OBJECT(item), "activate",
+	                 G_CALLBACK(pidgin_accounts_menu_enable_account), account);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu->disabled_menu), item);
+
+	g_hash_table_insert(menu->disabled_items,
+	                    g_object_ref(G_OBJECT(account)),
+	                    item);
+}
+
+static void
+pidgin_accounts_menu_add_current(PidginAccountsMenu *menu) {
+	GList *accounts = NULL, *l = NULL;
+
+	accounts = purple_accounts_get_all();
+	for(l = accounts; l != NULL; l = l->next) {
+		PurpleAccount *account = PURPLE_ACCOUNT(l->data);
+
+		if(purple_account_get_enabled(account, PIDGIN_UI)) {
+			pidgin_accounts_menu_add_enabled_account(menu, account);
+		} else {
+			pidgin_accounts_menu_add_disabled_account(menu, account);
+		}
+	}
+}
+
+/******************************************************************************
+ * Purple Signal Callbacks
+ *****************************************************************************/
+static void
+pidgin_accounts_menu_account_status_changed(PurpleAccount *account,
+                                            gpointer d)
+{
+	PidginAccountsMenu *menu = PIDGIN_ACCOUNTS_MENU(d);
+	gpointer data = NULL;
+
+	data = g_hash_table_lookup(menu->account_items, account);
+	if(GTK_IS_WIDGET(data)) {
+		gtk_menu_item_set_submenu(GTK_MENU_ITEM(data),
+		                          pidgin_account_actions_menu_new(account));
+	}
+}
+
+static void
+pidgin_accounts_menu_account_enabled(PurpleAccount *account, gpointer data) {
+	pidgin_accounts_menu_add_enabled_account(PIDGIN_ACCOUNTS_MENU(data),
+	                                         account);
+}
+
+static void
+pidgin_accounts_menu_account_disabled(PurpleAccount *account, gpointer data) {
+	pidgin_accounts_menu_add_disabled_account(PIDGIN_ACCOUNTS_MENU(data),
+	                                          account);
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+G_DEFINE_TYPE(PidginAccountsMenu, pidgin_accounts_menu, GTK_TYPE_MENU)
+
+static void
+pidgin_accounts_menu_init(PidginAccountsMenu *menu) {
+	gpointer handle;
+
+	/* initialize our template */
+	gtk_widget_init_template(GTK_WIDGET(menu));
+
+	/* create our storage for the items */
+	menu->account_items = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+	                                            g_object_unref,
+	                                            (GDestroyNotify)gtk_widget_destroy);
+	menu->disabled_items = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+	                                             g_object_unref,
+	                                             (GDestroyNotify)gtk_widget_destroy);
+
+	/* add all of the existing accounts */
+	pidgin_accounts_menu_add_current(menu);
+
+	/* finally connect to the purple signals to stay up to date */
+	handle = purple_accounts_get_handle();
+	purple_signal_connect(handle, "account-signed-on", menu,
+	                      G_CALLBACK(pidgin_accounts_menu_account_status_changed),
+	                      menu);
+	purple_signal_connect(handle, "account-signed-off", menu,
+	                      G_CALLBACK(pidgin_accounts_menu_account_status_changed),
+	                      menu);
+	purple_signal_connect(handle, "account-actions-changed", menu,
+	                      G_CALLBACK(pidgin_accounts_menu_account_status_changed),
+	                      menu);
+	purple_signal_connect(handle, "account-enabled", menu,
+	                      G_CALLBACK(pidgin_accounts_menu_account_enabled),
+	                      menu);
+	purple_signal_connect(handle, "account-disabled", menu,
+	                      G_CALLBACK(pidgin_accounts_menu_account_disabled),
+	                      menu);
+};
+
+static void
+pidgin_accounts_menu_finalize(GObject *obj) {
+	purple_signals_disconnect_by_handle(obj);
+
+	G_OBJECT_CLASS(pidgin_accounts_menu_parent_class)->finalize(obj);
+}
+
+static void
+pidgin_accounts_menu_class_init(PidginAccountsMenuClass *klass) {
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+	obj_class->finalize = pidgin_accounts_menu_finalize;
+
+    gtk_widget_class_set_template_from_resource(
+        widget_class,
+        "/im/pidgin/Pidgin/Accounts/menu.ui"
+    );
+
+   	gtk_widget_class_bind_template_child(widget_class, PidginAccountsMenu,
+   	                                     disabled_menu);
+   	gtk_widget_class_bind_template_child(widget_class, PidginAccountsMenu,
+   	                                     separator);
+
+   	gtk_widget_class_bind_template_callback(widget_class,
+   	                                        pidgin_accounts_menu_open_manager_cb);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+GtkWidget *
+pidgin_accounts_menu_new(void) {
+	return GTK_WIDGET(g_object_new(PIDGIN_TYPE_ACCOUNTS_MENU, NULL));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountsmenu.h	Mon Apr 06 22:27:40 2020 -0500
@@ -0,0 +1,57 @@
+/*
+ * pidgin
+ *
+ * Pidgin is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+#ifndef PIDGIN_ACCOUNTS_MENU_H
+#define PIDGIN_ACCOUNTS_MENU_H
+
+/**
+ * SECTION:pidginaccountsmenu
+ * @section_id: pidgin-accounts-menu
+ * @short_description: A menu for managing accounts and their actions
+ * @title: Accounts Menu
+ *
+ * #PidginAccountMenu is a #GtkMenu that provides an interface to users to open
+ * the account manager as well as activate account actions.
+ *
+ * It manages itself as accounts are created/deleted and enabled/disabled and
+ * can be added as a submenu to any #GtkMenuItem.
+ */
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define PIDGIN_TYPE_ACCOUNTS_MENU (pidgin_accounts_menu_get_type())
+G_DECLARE_FINAL_TYPE(PidginAccountsMenu, pidgin_accounts_menu, PIDGIN,
+                     ACCOUNTS_MENU, GtkMenu)
+
+/**
+ * pidgin_accounts_menu_new:
+ *
+ * Creates a new #PidginAccountsMenu instance that keeps itself up to date.
+ *
+ * Returns: (transfer full): The new #PidginAccountsMenu instance.
+ */
+GtkWidget *pidgin_accounts_menu_new(void);
+
+G_END_DECLS
+
+#endif /* PIDGIN_ACCOUNTS_MENU_H */
--- a/pidgin/pidginactiongroup.c	Wed Apr 01 13:08:57 2020 -0500
+++ b/pidgin/pidginactiongroup.c	Mon Apr 06 22:27:40 2020 -0500
@@ -26,7 +26,6 @@
 
 #include "internal.h"
 
-#include "pidgin/gtkaccount.h"
 #include "pidgin/gtkblist.h"
 #include "pidgin/gtkdialogs.h"
 #include "pidgin/gtkpounce.h"
@@ -408,13 +407,6 @@
 }
 
 static void
-pidgin_action_group_manage_accounts(GSimpleAction *simple, GVariant *parameter,
-                                    gpointer data)
-{
-	pidgin_accounts_window_show();
-}
-
-static void
 pidgin_action_group_mute_sounds(GSimpleAction *action, GVariant *value,
                                 gpointer data)
 {
@@ -570,9 +562,6 @@
 			.name = PIDGIN_ACTION_JOIN_CHAT,
 			.activate = pidgin_action_group_join_chat,
 		}, {
-			.name = PIDGIN_ACTION_MANAGE_ACCOUNTS,
-			.activate = pidgin_action_group_manage_accounts,
-		}, {
 			.name = PIDGIN_ACTION_MUTE_SOUNDS,
 			.state = "false",
 			.change_state = pidgin_action_group_mute_sounds,
--- a/pidgin/pidginactiongroup.h	Wed Apr 01 13:08:57 2020 -0500
+++ b/pidgin/pidginactiongroup.h	Mon Apr 06 22:27:40 2020 -0500
@@ -103,14 +103,6 @@
 #define PIDGIN_ACTION_JOIN_CHAT ("join-chat")
 
 /**
- * PIDGIN_ACTION_MANAGE_ACCOUNTS:
- *
- * A constatnt that represents the manage-accounts action to displays the
- * manage accounts window.
- */
-#define PIDGIN_ACTION_MANAGE_ACCOUNTS ("manage-accounts")
-
-/**
  * PIDGIN_ACTION_MUTE_SOUNDS:
  *
  * A constatnt that represents the mute-sounds action.
--- a/pidgin/pidginbuddylistmenu.c	Wed Apr 01 13:08:57 2020 -0500
+++ b/pidgin/pidginbuddylistmenu.c	Mon Apr 06 22:27:40 2020 -0500
@@ -26,6 +26,10 @@
 	GtkMenuBar parent;
 
 	GtkWidget *sort_buddies;
+
+	GtkWidget *accounts;
+	GtkWidget *accounts_menu;
+
 	GtkWidget *plugins;
 	GtkWidget *plugins_menu;
 };
@@ -39,6 +43,8 @@
 pidgin_buddy_list_menu_init(PidginBuddyListMenu *menu) {
 	gtk_widget_init_template(GTK_WIDGET(menu));
 
+	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu->accounts),
+	                          menu->accounts_menu);
 	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu->plugins),
 	                          menu->plugins_menu);
 }
@@ -55,6 +61,10 @@
    	gtk_widget_class_bind_template_child(widget_class, PidginBuddyListMenu,
    	                                     sort_buddies);
    	gtk_widget_class_bind_template_child(widget_class, PidginBuddyListMenu,
+   	                                     accounts);
+   	gtk_widget_class_bind_template_child(widget_class, PidginBuddyListMenu,
+   	                                     accounts_menu);
+   	gtk_widget_class_bind_template_child(widget_class, PidginBuddyListMenu,
    	                                     plugins);
    	gtk_widget_class_bind_template_child(widget_class, PidginBuddyListMenu,
    	                                     plugins_menu);
--- a/pidgin/pidginpluginsmenu.h	Wed Apr 01 13:08:57 2020 -0500
+++ b/pidgin/pidginpluginsmenu.h	Mon Apr 06 22:27:40 2020 -0500
@@ -35,7 +35,6 @@
  * submenu to any #GtkMenuItem.
  */
 
-
 #include <gtk/gtk.h>
 
 G_BEGIN_DECLS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/resources/Accounts/actionsmenu.ui	Mon Apr 06 22:27:40 2020 -0500
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.2 
+
+Pidgin - Internet Messenger
+Copyright (C) Pidgin Developers <devel@pidgin.im>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+-->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <!-- interface-license-type gplv2 -->
+  <!-- interface-name Pidgin -->
+  <!-- interface-description Internet Messenger -->
+  <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
+  <template class="PidginAccountActionsMenu" parent="GtkMenu">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkMenuItem">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">_Edit Account</property>
+        <property name="use_underline">True</property>
+        <signal name="activate" handler="pidgin_account_actions_menu_edit_cb" object="PidginAccountActionsMenu" swapped="no"/>
+      </object>
+    </child>
+    <child>
+      <object class="GtkSeparatorMenuItem" id="separator">
+        <property name="can_focus">False</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkSeparatorMenuItem">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">_Disable</property>
+        <property name="use_underline">True</property>
+        <signal name="activate" handler="pidgin_account_actions_menu_disable_cb" object="PidginAccountActionsMenu" swapped="no"/>
+      </object>
+    </child>
+  </template>
+</interface>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/resources/Accounts/menu.ui	Mon Apr 06 22:27:40 2020 -0500
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.2 
+
+Pidgin - Internet Messenger
+Copyright (C) Pidgin Developers <devel@pidgin.im>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+-->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <!-- interface-license-type gplv2 -->
+  <!-- interface-name Pidgin -->
+  <!-- interface-description Internet Messenger -->
+  <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
+  <template class="PidginAccountsMenu" parent="GtkMenu">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="menu_type_hint">dnd</property>
+    <child>
+      <object class="GtkMenuItem">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Account _Manager</property>
+        <property name="use_underline">True</property>
+        <signal name="activate" handler="pidgin_accounts_menu_open_manager_cb" object="PidginAccountsMenu" swapped="no"/>
+        <accelerator key="a" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">_Enable Account</property>
+        <property name="use_underline">True</property>
+        <child type="submenu">
+          <object class="GtkMenu" id="disabled_menu">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="GtkSeparatorMenuItem" id="separator">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+    </child>
+  </template>
+</interface>
--- a/pidgin/resources/BuddyList/menu.ui	Wed Apr 01 13:08:57 2020 -0500
+++ b/pidgin/resources/BuddyList/menu.ui	Mon Apr 06 22:27:40 2020 -0500
@@ -184,27 +184,11 @@
       </object>
     </child>
     <child>
-      <object class="GtkMenuItem">
+      <object class="GtkMenuItem" id="accounts">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="label" translatable="yes">_Accounts</property>
         <property name="use_underline">True</property>
-        <child type="submenu">
-          <object class="GtkMenu">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <child>
-              <object class="GtkMenuItem" id="manage_accounts">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="action_name">blist.manage-accounts</property>
-                <property name="label" translatable="yes">Manage Accounts</property>
-                <property name="use_underline">True</property>
-                <accelerator key="a" signal="activate" modifiers="GDK_CONTROL_MASK"/>
-              </object>
-            </child>
-          </object>
-        </child>
       </object>
     </child>
     <child>
@@ -369,6 +353,10 @@
       </object>
     </child>
   </template>
+  <object class="PidginAccountsMenu" id="accounts_menu">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+  </object>
   <object class="PidginPluginsMenu" id="plugins_menu">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
--- a/pidgin/resources/pidgin.gresource.xml	Wed Apr 01 13:08:57 2020 -0500
+++ b/pidgin/resources/pidgin.gresource.xml	Mon Apr 06 22:27:40 2020 -0500
@@ -6,6 +6,8 @@
     <file compressed="true">About/about.md</file>
     <file compressed="true">About/credits.json</file>
     <file compressed="true">Accounts/chooser.ui</file>
+    <file compressed="true">Accounts/actionsmenu.ui</file>
+    <file compressed="true">Accounts/menu.ui</file>
     <file compressed="true">BuddyList/menu.ui</file>
     <file compressed="true">Conversations/invite_dialog.ui</file>
     <file compressed="true">Debug/debug.ui</file>

mercurial