diff --git a/pidgin/pidginaccounteditor.h b/pidgin/pidginaccounteditor.h
--- a/pidgin/pidginaccounteditor.h
+++ b/pidgin/pidginaccounteditor.h
@@ -29,6 +29,8 @@
 
 #include <gtk/gtk.h>
 
+#include <adwaita.h>
+
 #include <purple.h>
 
 /**
@@ -43,7 +45,7 @@
 
 #define PIDGIN_TYPE_ACCOUNT_EDITOR pidgin_account_editor_get_type()
 G_DECLARE_FINAL_TYPE(PidginAccountEditor, pidgin_account_editor, PIDGIN,
-                     ACCOUNT_EDITOR, GtkDialog)
+                     ACCOUNT_EDITOR, AdwPreferencesPage)
 
 /**
  * pidgin_account_editor_new:
@@ -70,6 +72,42 @@
  */
 PurpleAccount *pidgin_account_editor_get_account(PidginAccountEditor *editor);
 
+/**
+ * pidgin_account_editor_set_account:
+ * @editor: The instance.
+ * @account: (nullable): The new account to edit.
+ *
+ * Sets the account that @editor is editing to @account. You can pass %NULL
+ * to remove the current account or edit a new account.
+ *
+ * Since: 3.0.0
+ */
+void pidgin_account_editor_set_account(PidginAccountEditor *editor, PurpleAccount *account);
+
+/**
+ * pidgin_account_editor_get_is_valid:
+ * @editor: The instance.
+ *
+ * Gets whether or not the settings for the account is valid and can be saved.
+ *
+ * Returns: %TRUE if the account being edited has valid values, otherwise
+ *          %FALSE.
+ *
+ * Since: 3.0.0
+ */
+gboolean pidgin_account_editor_get_is_valid(PidginAccountEditor *editor);
+
+/**
+ * pidgin_account_editor_save:
+ * @editor: The instance.
+ *
+ * Save the account to disk. If this is a new account, it will be set to match
+ * the current global status which is "online" in most cases.
+ *
+ * Since: 3.0.0
+ */
+void pidgin_account_editor_save(PidginAccountEditor *editor);
+
 G_END_DECLS
 
 #endif /* PIDGIN_ACCOUNT_EDITOR_H */
# HG changeset patch
# Node ID 1f62cecf2450
# Parent  4de5a514b8ba
diff --git a/pidgin/pidginaccounteditor.c b/pidgin/pidginaccounteditor.c
--- a/pidgin/pidginaccounteditor.c
+++ b/pidgin/pidginaccounteditor.c
@@ -29,10 +29,12 @@
 #include "pidginprotocolchooser.h"
 
 struct _PidginAccountEditor {
-	GtkDialog parent;
+	AdwPreferencesPage parent;
 
 	PurpleAccount *account;
 
+	gboolean valid;
+
 	/* Login Options */
 	GtkWidget *login_options;
 	GtkWidget *protocol;
@@ -71,6 +73,7 @@
 enum {
 	PROP_0,
 	PROP_ACCOUNT,
+	PROP_VALID,
 	N_PROPERTIES,
 };
 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
@@ -86,6 +89,17 @@
  * Helpers
  *****************************************************************************/
 static void
+pidgin_account_editor_set_valid(PidginAccountEditor *editor, gboolean valid) {
+	g_return_if_fail(PIDGIN_IS_ACCOUNT_EDITOR(editor));
+
+	if(editor->valid != valid) {
+		editor->valid = valid;
+
+		g_object_notify_by_pspec(G_OBJECT(editor), properties[PROP_VALID]);
+	}
+}
+
+static void
 pidgin_account_editor_add_user_split(gpointer data, gpointer user_data) {
 	PurpleAccountUserSplit *split = data;
 	PidginAccountEditor *editor = user_data;
@@ -652,8 +666,7 @@
 	pidgin_account_editor_update_advanced_options(editor, protocol);
 	pidgin_account_editor_update_proxy_options(editor);
 
-	gtk_dialog_set_response_sensitive(GTK_DIALOG(editor), GTK_RESPONSE_APPLY,
-	                                  sensitive);
+	pidgin_account_editor_set_valid(editor, sensitive);
 }
 
 static void
@@ -706,23 +719,6 @@
 	gtk_widget_set_sensitive(editor->require_password, editable);
 }
 
-static void
-pidgin_account_editor_set_account(PidginAccountEditor *editor,
-                                  PurpleAccount *account)
-{
-	if(g_set_object(&editor->account, account)) {
-		if(PURPLE_IS_ACCOUNT(account)) {
-			g_signal_connect_object(account, "notify::connection",
-			                        G_CALLBACK(pidgin_account_editor_connection_changed_cb),
-			                        editor, 0);
-		}
-
-		g_object_notify_by_pspec(G_OBJECT(editor), properties[PROP_ACCOUNT]);
-	}
-
-	pidgin_account_editor_update(editor);
-}
-
 static gboolean
 pidgin_account_editor_save_login_options(PidginAccountEditor *editor) {
 	PurpleProtocol *protocol = NULL;
@@ -912,35 +908,6 @@
 	purple_proxy_info_set_password(info, svalue);
 }
 
-static void
-pidgin_account_editor_save_account(PidginAccountEditor *editor) {
-	gboolean new_account = FALSE;
-
-	new_account = pidgin_account_editor_save_login_options(editor);
-	pidgin_account_editor_save_user_options(editor);
-	pidgin_account_editor_save_advanced_options(editor);
-	pidgin_account_editor_save_proxy(editor, new_account);
-
-	/* If this is a new account, add it to the account manager and bring it
-	 * online.
-	 */
-	if(new_account) {
-		PurpleAccountManager *manager = NULL;
-		const PurpleSavedStatus *saved_status;
-
-		manager = purple_account_manager_get_default();
-
-		purple_account_manager_add(manager, editor->account);
-
-		saved_status = purple_savedstatus_get_current();
-		if (saved_status != NULL) {
-			purple_savedstatus_activate_for_account(saved_status,
-			                                        editor->account);
-			purple_account_set_enabled(editor->account, TRUE);
-		}
-	}
-}
-
 /******************************************************************************
  * Callbacks
  *****************************************************************************/
@@ -959,7 +926,7 @@
                                   G_GNUC_UNUSED gpointer data)
 {
 	if(response_id == GTK_RESPONSE_APPLY) {
-		pidgin_account_editor_save_account(PIDGIN_ACCOUNT_EDITOR(dialog));
+		pidgin_account_editor_save(PIDGIN_ACCOUNT_EDITOR(dialog));
 	}
 
 	gtk_window_destroy(GTK_WINDOW(dialog));
@@ -983,8 +950,7 @@
 		sensitive = TRUE;
 	}
 
-	gtk_dialog_set_response_sensitive(GTK_DIALOG(editor), GTK_RESPONSE_APPLY,
-	                                  sensitive);
+	pidgin_account_editor_set_valid(editor, sensitive);
 }
 
 static void
@@ -1103,7 +1069,8 @@
 /******************************************************************************
  * GObject Implementation
  *****************************************************************************/
-G_DEFINE_TYPE(PidginAccountEditor, pidgin_account_editor, GTK_TYPE_DIALOG)
+G_DEFINE_TYPE(PidginAccountEditor, pidgin_account_editor,
+              ADW_TYPE_PREFERENCES_PAGE)
 
 static void
 pidgin_account_editor_get_property(GObject *obj, guint param_id, GValue *value,
@@ -1116,6 +1083,10 @@
 			g_value_set_object(value,
 			                   pidgin_account_editor_get_account(editor));
 			break;
+		case PROP_VALID:
+			g_value_set_boolean(value,
+			                    pidgin_account_editor_get_is_valid(editor));
+			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
 			break;
@@ -1208,7 +1179,19 @@
 		"account", "account",
 		"The account to modify",
 		PURPLE_TYPE_ACCOUNT,
-		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	/**
+	 * PidginAccountEditor::valid:
+	 *
+	 * Whether or not the account settings are valid and it is okay to save the
+	 * account.
+	 */
+	properties[PROP_VALID] = g_param_spec_boolean(
+		"valid", "valid",
+		"Whether or not the account settings are valid",
+		FALSE,
+		G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
 
 	g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
 
@@ -1293,3 +1276,71 @@
 
 	return editor->account;
 }
+
+void
+pidgin_account_editor_set_account(PidginAccountEditor *editor,
+                                  PurpleAccount *account)
+{
+	g_return_if_fail(PIDGIN_IS_ACCOUNT_EDITOR(editor));
+
+	/* Disconnect the notify handler from the previous account. */
+	if(PURPLE_IS_ACCOUNT(editor->account)) {
+		g_signal_handlers_disconnect_by_func(editor->account,
+		                                     G_CALLBACK(pidgin_account_editor_connection_changed_cb),
+		                                     editor);
+	}
+
+	if(g_set_object(&editor->account, account)) {
+		if(PURPLE_IS_ACCOUNT(account)) {
+			pidgin_protocol_chooser_set_protocol(PIDGIN_PROTOCOL_CHOOSER(editor->protocol),
+			                                     purple_account_get_protocol(editor->account));
+
+			g_signal_connect_object(account, "notify::connection",
+			                        G_CALLBACK(pidgin_account_editor_connection_changed_cb),
+			                        editor, 0);
+		}
+
+		g_object_notify_by_pspec(G_OBJECT(editor), properties[PROP_ACCOUNT]);
+	}
+
+	pidgin_account_editor_update(editor);
+}
+
+gboolean
+pidgin_account_editor_get_is_valid(PidginAccountEditor *editor) {
+	g_return_val_if_fail(PIDGIN_IS_ACCOUNT_EDITOR(editor), FALSE);
+
+	return editor->valid;
+}
+
+void
+pidgin_account_editor_save(PidginAccountEditor *editor) {
+	gboolean new_account = FALSE;
+
+	g_return_if_fail(PIDGIN_IS_ACCOUNT_EDITOR(editor));
+	g_return_if_fail(editor->valid == TRUE);
+
+	new_account = pidgin_account_editor_save_login_options(editor);
+	pidgin_account_editor_save_user_options(editor);
+	pidgin_account_editor_save_advanced_options(editor);
+	pidgin_account_editor_save_proxy(editor, new_account);
+
+	/* If this is a new account, add it to the account manager and bring it
+	 * online.
+	 */
+	if(new_account) {
+		PurpleAccountManager *manager = NULL;
+		const PurpleSavedStatus *saved_status;
+
+		manager = purple_account_manager_get_default();
+
+		purple_account_manager_add(manager, editor->account);
+
+		saved_status = purple_savedstatus_get_current();
+		if(saved_status != NULL) {
+			purple_savedstatus_activate_for_account(saved_status,
+			                                        editor->account);
+			purple_account_set_enabled(editor->account, TRUE);
+		}
+	}
+}
diff --git a/pidgin/pidginaccountmanager.h b/pidgin/pidginaccountmanager.h
--- a/pidgin/pidginaccountmanager.h
+++ b/pidgin/pidginaccountmanager.h
@@ -54,6 +54,28 @@
  */
 GtkWidget *pidgin_account_manager_new(void);
 
+/**
+ * pidgin_account_managet_show_overview:
+ * @manager: The instance.
+ *
+ * Switches @manager to the overview page. This is useful as @manager might
+ * already be visible but editing an account.
+ *
+ * Since: 3.0.0
+ */
+void pidgin_account_manager_show_overview(PidginAccountManager *manager);
+
+/**
+ * pidgin_account_manager_edit_account:
+ * @manager: The instance.
+ * @account: The account to edit.
+ *
+ * Opens the account editor in @manager for the given account.
+ *
+ * Since: 3.0.0
+ */
+void pidgin_account_manager_edit_account(PidginAccountManager *manager, PurpleAccount *account);
+
 G_END_DECLS
 
 #endif /* PIDGIN_ACCOUNT_MANAGER_H */
diff --git a/pidgin/pidginaccountmanager.c b/pidgin/pidginaccountmanager.c
--- a/pidgin/pidginaccountmanager.c
+++ b/pidgin/pidginaccountmanager.c
@@ -36,6 +36,15 @@
 
 	GtkListBox *list_box;
 	GtkWidget *add;
+
+	GtkWidget *stack;
+	GtkWidget *editor;
+
+	/* This is used to not go back to the manager when an account was edited
+	 * directly, via the `accounts->(account)->edit` menu or the
+	 * `connection error` notification.
+	 */
+	gboolean edit_only;
 };
 
 enum {
@@ -59,16 +68,32 @@
 }
 
 static void
-pidgin_account_manager_create_account(PidginAccountManager *manager) {
-	GtkWidget *editor = pidgin_account_editor_new(NULL);
-	gtk_window_set_transient_for(GTK_WINDOW(editor),
-	                             GTK_WINDOW(manager));
-	gtk_window_present_with_time(GTK_WINDOW(editor), GDK_CURRENT_TIME);
+pidgin_account_manager_real_edit_account(PidginAccountManager *manager,
+                                         PurpleAccount *account,
+                                         gboolean edit_only)
+{
+	g_return_if_fail(PIDGIN_IS_ACCOUNT_MANAGER(manager));
+
+	manager->edit_only = edit_only;
+
+	pidgin_account_editor_set_account(PIDGIN_ACCOUNT_EDITOR(manager->editor),
+	                                  account);
+
+	gtk_stack_set_visible_child_name(GTK_STACK(manager->stack), "editor-page");
 }
 
 /******************************************************************************
  * Callbacks
  *****************************************************************************/
+/* This is used by the add button on the placeholder page. */
+static void
+pidgin_account_manager_create_account(G_GNUC_UNUSED GtkButton *self,
+                                      gpointer data)
+{
+	PidginAccountManager *manager = data;
+
+	pidgin_account_manager_real_edit_account(manager, NULL, FALSE);
+}
 
 static void
 pidgin_account_manager_refresh_add_cb(GListModel *list,
@@ -92,7 +117,7 @@
 
 	switch(response_id) {
 		case RESPONSE_ADD:
-			pidgin_account_manager_create_account(manager);
+			pidgin_account_manager_real_edit_account(manager, NULL, FALSE);
 			break;
 		case GTK_RESPONSE_CLOSE:
 		case GTK_RESPONSE_DELETE_EVENT:
@@ -106,14 +131,49 @@
 static void
 pidgin_account_manager_row_activated_cb(G_GNUC_UNUSED GtkListBox *box,
                                         GtkListBoxRow *row,
-                                        G_GNUC_UNUSED gpointer data)
+                                        gpointer data)
 {
-	GtkWidget *editor = NULL;
 	PurpleAccount *account = NULL;
+	PidginAccountManager *manager = data;
 
 	account = pidgin_account_row_get_account(PIDGIN_ACCOUNT_ROW(row));
-	editor = pidgin_account_editor_new(account);
-	gtk_widget_show(editor);
+
+	pidgin_account_manager_real_edit_account(manager, account, FALSE);
+}
+
+static void
+pidgin_account_manager_back_clicked_cb(G_GNUC_UNUSED GtkButton *self,
+                                       gpointer data)
+{
+	PidginAccountManager *manager = data;
+
+#if ADW_CHECK_VERSION(1, 3, 0)
+	/* Scroll the editor back to the top of the scrolled window. */
+	adw_preferences_page_scroll_to_top(ADW_PREFERENCES_PAGE(manager->editor));
+#endif
+
+	/* Disconnect the account which will remove all of the account options as
+	 * well.
+	 */
+	pidgin_account_editor_set_account(PIDGIN_ACCOUNT_EDITOR(manager->editor),
+	                                  NULL);
+
+	pidgin_account_manager_show_overview(manager);
+}
+
+static void
+pidgin_account_manager_save_clicked_cb(G_GNUC_UNUSED GtkButton *self,
+                                       gpointer data)
+{
+	PidginAccountManager *manager = data;
+
+	pidgin_account_editor_save(PIDGIN_ACCOUNT_EDITOR(manager->editor));
+
+	if(manager->edit_only) {
+		gtk_window_destroy(GTK_WINDOW(manager));
+	} else {
+		gtk_stack_set_visible_child_name(GTK_STACK(manager->stack), "overview");
+	}
 }
 
 /******************************************************************************
@@ -147,6 +207,10 @@
 	                                     list_box);
 	gtk_widget_class_bind_template_child(widget_class, PidginAccountManager,
 	                                     add);
+	gtk_widget_class_bind_template_child(widget_class, PidginAccountManager,
+	                                     stack);
+	gtk_widget_class_bind_template_child(widget_class, PidginAccountManager,
+	                                     editor);
 
 	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_account_manager_response_cb);
@@ -154,6 +218,10 @@
 	                                        pidgin_account_manager_row_activated_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_account_manager_create_account);
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        pidgin_account_manager_back_clicked_cb);
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        pidgin_account_manager_save_clicked_cb);
 }
 
 /******************************************************************************
@@ -163,3 +231,20 @@
 pidgin_account_manager_new(void) {
 	return g_object_new(PIDGIN_TYPE_ACCOUNT_MANAGER, NULL);
 }
+
+void
+pidgin_account_manager_show_overview(PidginAccountManager *manager) {
+	g_return_if_fail(PIDGIN_IS_ACCOUNT_MANAGER(manager));
+
+	gtk_stack_set_visible_child_name(GTK_STACK(manager->stack), "overview");
+}
+
+void
+pidgin_account_manager_edit_account(PidginAccountManager *manager,
+                                    PurpleAccount *account)
+{
+	g_return_if_fail(PIDGIN_IS_ACCOUNT_MANAGER(manager));
+	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
+
+	pidgin_account_manager_real_edit_account(manager, account, TRUE);
+}
diff --git a/pidgin/pidginapplication.c b/pidgin/pidginapplication.c
--- a/pidgin/pidginapplication.c
+++ b/pidgin/pidginapplication.c
@@ -95,6 +95,26 @@
  *****************************************************************************/
 
 /*
+ * pidgin_application_get_account_manager:
+ *
+ * The Pidgin account manager can get opened from multiple actions, so this
+ * helper manages the singleton.
+ *
+ * Since: 3.0.0
+ */
+static GtkWidget *
+pidgin_application_get_account_manager(void) {
+	static GtkWidget *manager = NULL;
+
+	if(!PIDGIN_IS_ACCOUNT_MANAGER(manager)) {
+		manager = pidgin_account_manager_new();
+		g_object_add_weak_pointer(G_OBJECT(manager), (gpointer)&manager);
+	}
+
+	return manager;
+}
+
+/*
  * pidgin_application_present_transient_window:
  * @application: The application instance.
  * @window: The [class@Gtk.Window] to present.
@@ -275,12 +295,9 @@
                             G_GNUC_UNUSED GVariant *parameter, gpointer data)
 {
 	PidginApplication *application = data;
-	static GtkWidget *manager = NULL;
+	GtkWidget *manager = pidgin_application_get_account_manager();
 
-	if(!GTK_IS_WIDGET(manager)) {
-		manager = pidgin_account_manager_new();
-		g_object_add_weak_pointer(G_OBJECT(manager), (gpointer)&manager);
-	}
+	pidgin_account_manager_show_overview(PIDGIN_ACCOUNT_MANAGER(manager));
 
 	pidgin_application_present_transient_window(application,
 	                                            GTK_WINDOW(manager));
@@ -377,16 +394,27 @@
 	PurpleAccountManager *manager = NULL;
 	const gchar *id = NULL;
 
+	if(!g_variant_is_of_type(parameter, G_VARIANT_TYPE_STRING)) {
+		g_warning("parameter is of type %s, expected %s",
+		          g_variant_get_type_string(parameter),
+		          G_VARIANT_TYPE_STRING);
+
+		return;
+	}
+
 	id = g_variant_get_string(parameter, NULL);
 
 	manager = purple_account_manager_get_default();
 
 	account = purple_account_manager_find_by_id(manager, id);
 	if(PURPLE_IS_ACCOUNT(account)) {
-		GtkWidget *editor = pidgin_account_editor_new(account);
+		GtkWidget *account_manager = pidgin_application_get_account_manager();
+
+		pidgin_account_manager_edit_account(PIDGIN_ACCOUNT_MANAGER(account_manager),
+		                                    account);
 
 		pidgin_application_present_transient_window(application,
-		                                            GTK_WINDOW(editor));
+		                                            GTK_WINDOW(account_manager));
 	}
 }
 
diff --git a/pidgin/resources/Accounts/editor.ui b/pidgin/resources/Accounts/editor.ui
--- a/pidgin/resources/Accounts/editor.ui
+++ b/pidgin/resources/Accounts/editor.ui
@@ -26,195 +26,181 @@
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <template class="PidginAccountEditor" parent="GtkDialog">
-    <property name="resizable">0</property>
-    <property name="default-height">600</property>
-    <property name="default-width">400</property>
-    <property name="title" translatable="1">Edit Account</property>
-    <signal name="response" handler="pidgin_account_editor_response_cb" swapped="no"/>
-    <child internal-child="content_area">
-      <object class="GtkBox">
-        <property name="vexpand">1</property>
+  <template class="PidginAccountEditor" parent="AdwPreferencesPage">
+    <property name="vexpand">1</property>
+    <property name="hexpand">1</property>
+    <child>
+      <object class="AdwPreferencesGroup" id="login_options">
+        <property name="title" translatable="1">Login Options</property>
         <child>
-          <object class="AdwPreferencesPage">
-            <property name="vexpand">1</property>
-            <property name="hexpand">1</property>
+          <object class="PidginProtocolChooser" id="protocol">
+            <property name="title" translatable="1">Pro_tocol</property>
+            <property name="use-underline">1</property>
+            <signal name="notify::protocol" handler="pidgin_account_editor_protocol_changed_cb" object="PidginAccountEditor" swapped="no"/>
+          </object>
+        </child>
+        <child>
+          <object class="AdwPreferencesRow">
+            <property name="focusable">0</property>
             <child>
-              <object class="AdwPreferencesGroup" id="login_options">
-                <property name="title" translatable="1">Login Options</property>
+              <object class="GtkListBox" id="user_splits">
+                <property name="focusable">0</property>
                 <child>
-                  <object class="PidginProtocolChooser" id="protocol">
-                    <property name="title" translatable="1">Pro_tocol</property>
-                    <property name="use-underline">1</property>
-                    <signal name="notify::protocol" handler="pidgin_account_editor_protocol_changed_cb" object="PidginAccountEditor" swapped="no"/>
-                  </object>
-                </child>
-                <child>
-                  <object class="AdwPreferencesRow">
+                  <object class="AdwEntryRow" id="username">
                     <property name="focusable">0</property>
-                    <child>
-                      <object class="GtkListBox" id="user_splits">
-                        <property name="focusable">0</property>
-                        <child>
-                          <object class="AdwEntryRow" id="username">
-                            <property name="focusable">0</property>
-                            <property name="title" translatable="1">_Username</property>
-                            <property name="use-underline">1</property>
-                            <signal name="changed" handler="pidgin_account_editor_username_changed_cb" object="PidginAccountEditor" swapped="no"/>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-                <child>
-                  <object class="AdwActionRow" id="require_password_row">
-                    <property name="activatable-widget">avatar</property>
-                    <property name="focusable">0</property>
-                    <property name="title" translatable="1">Require _password</property>
-                    <property name="subtitle" translatable="1">This account has an optional password, setting this will make it required</property>
+                    <property name="title" translatable="1">_Username</property>
                     <property name="use-underline">1</property>
-                    <property name="visible">0</property>
-                    <child type="suffix">
-                      <object class="GtkSwitch" id="require_password">
-                        <property name="valign">center</property>
-                      </object>
-                    </child>
+                    <signal name="changed" handler="pidgin_account_editor_username_changed_cb" object="PidginAccountEditor" swapped="no"/>
                   </object>
                 </child>
               </object>
             </child>
+          </object>
+        </child>
+        <child>
+          <object class="AdwActionRow" id="require_password_row">
+            <property name="activatable-widget">avatar</property>
+            <property name="focusable">0</property>
+            <property name="title" translatable="1">Require _password</property>
+            <property name="subtitle" translatable="1">This account has an optional password, setting this will make it required</property>
+            <property name="use-underline">1</property>
+            <property name="visible">0</property>
+            <child type="suffix">
+              <object class="GtkSwitch" id="require_password">
+                <property name="valign">center</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">User Options</property>
+        <child>
+          <object class="AdwEntryRow" id="alias">
+            <property name="focusable">0</property>
+            <property name="title" translatable="1">_Local alias</property>
+            <property name="use-underline">1</property>
+          </object>
+        </child>
+        <child>
+          <object class="AdwActionRow" id="avatar_row">
+            <property name="activatable-widget">avatar</property>
+            <property name="focusable">0</property>
+            <property name="title" translatable="1">Use custom _avatar</property>
+            <property name="use-underline">1</property>
+            <property name="visible">0</property>
+            <child type="prefix">
+              <object class="GtkSwitch" id="use_custom_avatar">
+                <property name="valign">center</property>
+              </object>
+            </child>
             <child>
-              <object class="AdwPreferencesGroup">
-                <property name="title" translatable="1">User Options</property>
+              <object class="GtkButton">
+                <property name="css-classes">flat</property>
+                <property name="valign">center</property>
+                <binding name="sensitive">
+                  <lookup name="active">use_custom_avatar</lookup>
+                </binding>
                 <child>
-                  <object class="AdwEntryRow" id="alias">
+                  <object class="GtkImage" id="avatar">
+                    <property name="icon-name">select-avatar</property>
+                    <property name="icon-size">large</property>
+                  </object>
+                </child>
+                <signal name="clicked" handler="pidgin_account_editor_avatar_set_clicked_cb" object="PidginAccountEditor" swapped="no"/>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="remove">
+                <property name="label" translatable="1">_Remove</property>
+                <property name="use-underline">1</property>
+                <property name="valign">center</property>
+                <binding name="sensitive">
+                  <lookup name="active">use_custom_avatar</lookup>
+                </binding>
+                <signal name="clicked" handler="pidgin_account_editor_avatar_remove_clicked_cb" object="PidginAccountEditor" swapped="no"/>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="AdwPreferencesGroup" id="advanced_group">
+        <property name="title" translatable="1">Advanced Options</property>
+        <property name="description" translatable="1">Additional options for this account.</property>
+        <property name="visible">0</property>
+        <child type="header-suffix">
+          <object class="GtkSwitch" id="advanced_toggle">
+            <property name="active">0</property>
+            <property name="valign">center</property>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="AdwPreferencesGroup">
+        <property name="title" translatable="1">Proxy</property>
+        <child>
+          <object class="AdwComboRow" id="proxy_type">
+            <property name="title" translatable="1">Proxy t_ype</property>
+            <property name="use-underline">1</property>
+            <property name="use-subtitle">1</property>
+            <property name="model">
+              <object class="GtkStringList">
+                <items>
+                  <item>global</item>
+                  <item>none</item>
+                  <item>socks4</item>
+                  <item>socks5</item>
+                  <item>tor</item>
+                  <item>http</item>
+                  <item>envvar</item>
+                </items>
+              </object>
+            </property>
+            <property name="expression">
+              <closure type="gchararray" function="pidgin_account_editor_proxy_type_expression_cb"/>
+            </property>
+            <signal name="notify::selected" handler="pidgin_account_editor_proxy_type_changed_cb" object="PidginAccountEditor" swapped="no"/>
+          </object>
+        </child>
+        <child>
+          <object class="AdwPreferencesRow" id="proxy_options">
+            <property name="focusable">0</property>
+            <property name="visible">0</property>
+            <child>
+              <object class="GtkListBox">
+                <property name="focusable">0</property>
+                <child>
+                  <object class="AdwEntryRow" id="proxy_host">
                     <property name="focusable">0</property>
-                    <property name="title" translatable="1">_Local alias</property>
+                    <property name="title" translatable="1">_Host</property>
                     <property name="use-underline">1</property>
                   </object>
                 </child>
                 <child>
-                  <object class="AdwActionRow" id="avatar_row">
-                    <property name="activatable-widget">avatar</property>
+                  <object class="AdwEntryRow" id="proxy_port">
                     <property name="focusable">0</property>
-                    <property name="title" translatable="1">Use custom _avatar</property>
+                    <property name="title" translatable="1">P_ort</property>
                     <property name="use-underline">1</property>
-                    <property name="visible">0</property>
-                    <child type="prefix">
-                      <object class="GtkSwitch" id="use_custom_avatar">
-                        <property name="valign">center</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton">
-                        <property name="css-classes">flat</property>
-                        <property name="valign">center</property>
-                        <binding name="sensitive">
-                          <lookup name="active">use_custom_avatar</lookup>
-                        </binding>
-                        <child>
-                          <object class="GtkImage" id="avatar">
-                            <property name="icon-name">select-avatar</property>
-                            <property name="icon-size">large</property>
-                          </object>
-                        </child>
-                        <signal name="clicked" handler="pidgin_account_editor_avatar_set_clicked_cb" object="PidginAccountEditor" swapped="no"/>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="remove">
-                        <property name="label" translatable="1">_Remove</property>
-                        <property name="use-underline">1</property>
-                        <property name="valign">center</property>
-                        <binding name="sensitive">
-                          <lookup name="active">use_custom_avatar</lookup>
-                        </binding>
-                        <signal name="clicked" handler="pidgin_account_editor_avatar_remove_clicked_cb" object="PidginAccountEditor" swapped="no"/>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child>
-              <object class="AdwPreferencesGroup" id="advanced_group">
-                <property name="title" translatable="1">Advanced Options</property>
-                <property name="description" translatable="1">Additional options for this account.</property>
-                <property name="visible">0</property>
-                <child type="header-suffix">
-                  <object class="GtkSwitch" id="advanced_toggle">
-                    <property name="active">0</property>
-                    <property name="valign">center</property>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child>
-              <object class="AdwPreferencesGroup">
-                <property name="title" translatable="1">Proxy</property>
-                <child>
-                  <object class="AdwComboRow" id="proxy_type">
-                    <property name="title" translatable="1">Proxy t_ype</property>
-                    <property name="use-underline">1</property>
-                    <property name="use-subtitle">1</property>
-                    <property name="model">
-                      <object class="GtkStringList">
-                        <items>
-                          <item>global</item>
-                          <item>none</item>
-                          <item>socks4</item>
-                          <item>socks5</item>
-                          <item>tor</item>
-                          <item>http</item>
-                          <item>envvar</item>
-                        </items>
-                      </object>
-                    </property>
-                    <property name="expression">
-                      <closure type="gchararray" function="pidgin_account_editor_proxy_type_expression_cb"/>
-                    </property>
-                    <signal name="notify::selected" handler="pidgin_account_editor_proxy_type_changed_cb" object="PidginAccountEditor" swapped="no"/>
+                    <property name="input-purpose">number</property>
                   </object>
                 </child>
                 <child>
-                  <object class="AdwPreferencesRow" id="proxy_options">
+                  <object class="AdwEntryRow" id="proxy_username">
                     <property name="focusable">0</property>
-                    <property name="visible">0</property>
-                    <child>
-                      <object class="GtkListBox">
-                        <property name="focusable">0</property>
-                        <child>
-                          <object class="AdwEntryRow" id="proxy_host">
-                            <property name="focusable">0</property>
-                            <property name="title" translatable="1">_Host</property>
-                            <property name="use-underline">1</property>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="AdwEntryRow" id="proxy_port">
-                            <property name="focusable">0</property>
-                            <property name="title" translatable="1">P_ort</property>
-                            <property name="use-underline">1</property>
-                            <property name="input-purpose">number</property>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="AdwEntryRow" id="proxy_username">
-                            <property name="focusable">0</property>
-                            <property name="title" translatable="1">User_name</property>
-                            <property name="use-underline">1</property>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="AdwPasswordEntryRow" id="proxy_password">
-                            <property name="focusable">0</property>
-                            <property name="title" translatable="1">Pa_ssword</property>
-                            <property name="use-underline">1</property>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
+                    <property name="title" translatable="1">User_name</property>
+                    <property name="use-underline">1</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="AdwPasswordEntryRow" id="proxy_password">
+                    <property name="focusable">0</property>
+                    <property name="title" translatable="1">Pa_ssword</property>
+                    <property name="use-underline">1</property>
                   </object>
                 </child>
               </object>
@@ -223,25 +209,5 @@
         </child>
       </object>
     </child>
-    <child type="action">
-      <object class="GtkButton" id="button1">
-        <property name="label" translatable="1">_Cancel</property>
-        <property name="receives-default">1</property>
-        <property name="use-underline">1</property>
-      </object>
-    </child>
-    <child type="action">
-      <object class="GtkButton" id="button2">
-        <property name="css-classes">suggested-action</property>
-        <property name="label" translatable="1">_Save</property>
-        <property name="receives-default">1</property>
-        <property name="sensitive">0</property>
-        <property name="use-underline">1</property>
-      </object>
-    </child>
-    <action-widgets>
-      <action-widget response="cancel">button1</action-widget>
-      <action-widget response="apply">button2</action-widget>
-    </action-widgets>
   </template>
 </interface>
diff --git a/pidgin/resources/Accounts/manager.ui b/pidgin/resources/Accounts/manager.ui
--- a/pidgin/resources/Accounts/manager.ui
+++ b/pidgin/resources/Accounts/manager.ui
@@ -32,64 +32,122 @@
     <child internal-child="content_area">
       <object class="GtkBox">
         <child>
-          <object class="GtkScrolledWindow">
-            <property name="vexpand">1</property>
-            <property name="child">
-              <object class="AdwClamp">
-                <property name="margin-bottom">24</property>
-                <property name="margin-end">24</property>
-                <property name="margin-start">24</property>
-                <property name="margin-top">24</property>
-                <property name="orientation">horizontal</property>
-                <child>
-                  <object class="GtkListBox" id="list_box">
-                    <property name="css-classes">boxed-list
-rich-list</property>
-                    <property name="selection-mode">none</property>
-                    <property name="show-separators">1</property>
-                    <signal name="row-activated" handler="pidgin_account_manager_row_activated_cb" swapped="no"/>
-                    <child type="placeholder">
-                      <object class="GtkBox">
-                        <property name="margin-bottom">48</property>
-                        <property name="margin-top">48</property>
-                        <property name="orientation">vertical</property>
-                        <property name="spacing">12</property>
-                        <property name="valign">center</property>
-                        <property name="vexpand">1</property>
+          <object class="GtkStack" id="stack">
+            <property name="transition-type">slide-left-right</property>
+            <property name="vhomogeneous">0</property>
+            <child>
+              <object class="GtkStackPage">
+                <property name="name">overview</property>
+                <property name="child">
+                  <object class="GtkScrolledWindow">
+                    <property name="hscrollbar_policy">never</property>
+                    <property name="vexpand">1</property>
+                    <property name="child">
+                      <object class="AdwClamp">
+                        <property name="margin-bottom">24</property>
+                        <property name="margin-end">24</property>
+                        <property name="margin-start">24</property>
+                        <property name="margin-top">24</property>
+                        <property name="orientation">horizontal</property>
                         <child>
-                          <object class="GtkImage">
-                            <property name="css-classes">dim-label</property>
-                            <property name="icon-name">view-list-symbolic</property>
-                            <property name="pixel-size">128</property>
+                          <object class="GtkListBox" id="list_box">
+                            <property name="css-classes">boxed-list
+        rich-list</property>
+                            <property name="selection-mode">none</property>
+                            <property name="show-separators">1</property>
+                            <signal name="row-activated" handler="pidgin_account_manager_row_activated_cb" swapped="no"/>
+                            <child type="placeholder">
+                              <object class="GtkBox">
+                                <property name="margin-bottom">48</property>
+                                <property name="margin-top">48</property>
+                                <property name="orientation">vertical</property>
+                                <property name="spacing">12</property>
+                                <property name="valign">center</property>
+                                <property name="vexpand">1</property>
+                                <child>
+                                  <object class="GtkImage">
+                                    <property name="css-classes">dim-label</property>
+                                    <property name="icon-name">view-list-symbolic</property>
+                                    <property name="pixel-size">128</property>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel">
+                                    <property name="css-classes">title-1</property>
+                                    <property name="label" translatable="1">No Accounts</property>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkButton">
+                                    <property name="css-classes">pill
+suggested-action</property>
+                                    <property name="halign">center</property>
+                                    <signal name="clicked" handler="pidgin_account_manager_create_account"/>
+                                    <property name="child">
+                                      <object class="AdwButtonContent">
+                                        <property name="icon-name">list-add-symbolic</property>
+                                        <property name="label" translatable="1">_Add…</property>
+                                        <property name="use-underline">1</property>
+                                      </object>
+                                    </property>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
                           </object>
                         </child>
+                      </object>
+                    </property>
+                  </object>
+                </property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkStackPage">
+                <property name="name">editor-page</property>
+                <property name="child">
+                  <object class="GtkBox">
+                    <property name="margin-bottom">24</property>
+                    <property name="margin-end">24</property>
+                    <property name="margin-start">24</property>
+                    <property name="margin-top">24</property>
+                    <property name="orientation">horizontal</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkBox">
+                        <property name="orientation">vertical</property>
                         <child>
-                          <object class="GtkLabel">
-                            <property name="css-classes">title-1</property>
-                            <property name="label" translatable="1">No Accounts</property>
+                          <object class="GtkButton">
+                            <property name="css-classes">flat</property>
+                            <property name="halign">start</property>
+                            <property name="valign">start</property>
+                            <property name="icon-name">go-previous-symbolic</property>
+                            <property name="tooltip-text" translatable="1">Back</property>
+                            <signal name="clicked" handler="pidgin_account_manager_back_clicked_cb"/>
                           </object>
                         </child>
                         <child>
                           <object class="GtkButton">
-                            <property name="css-classes">pill
-suggested-action</property>
-                            <property name="halign">center</property>
-                            <signal name="clicked" handler="pidgin_account_manager_create_account" swapped="yes"/>
-                            <property name="child">
-                              <object class="AdwButtonContent">
-                                <property name="icon-name">list-add-symbolic</property>
-                                <property name="label" translatable="1">_Add…</property>
-                                <property name="use-underline">1</property>
-                              </object>
-                            </property>
+                            <property name="css-classes">flat</property>
+                            <property name="halign">start</property>
+                            <property name="valign">start</property>
+                            <property name="icon-name">document-save-symbolic</property>
+                            <property name="tooltip-text" translatable="1">Save</property>
+                            <binding name="sensitive">
+                              <lookup name="valid">editor</lookup>
+                            </binding>
+                            <signal name="clicked" handler="pidgin_account_manager_save_clicked_cb"/>
                           </object>
                         </child>
                       </object>
                     </child>
+                    <child>
+                      <object class="PidginAccountEditor" id="editor"/>
+                    </child>
                   </object>
-                </child>
+                </property>
               </object>
-            </property>
+            </child>
           </object>
         </child>
       </object>
@@ -108,17 +166,8 @@
         </property>
       </object>
     </child>
-    <child type="action">
-      <object class="GtkButton" id="button2">
-        <property name="label" translatable="1">_Close</property>
-        <property name="focusable">1</property>
-        <property name="receives-default">1</property>
-        <property name="use-underline">1</property>
-      </object>
-    </child>
     <action-widgets>
       <action-widget response="0">add</action-widget>
-      <action-widget response="close">button2</action-widget>
     </action-widgets>
   </template>
 </interface>
