From 46c8129bf57a3df3e0a2db27e6611ca4210614be Mon Sep 17 00:00:00 2001
From: Ac_K <Acoustik666@gmail.com>
Date: Fri, 29 Jul 2022 00:41:34 +0200
Subject: [PATCH] Avalonia: Another Cleanup (#3494)

* Avalonia: Another Cleanup

This PR is a cleanup to the avalonia code recently added:

- Some XAML file are autoformatted like a previous PR.
- Dlc is renamed to DownloadableContent (Locale exclude).
- DownloadableContentManagerWindow is a bit improved (Fixes #3491).
- Some nits here and there.

* Fix GTK

* Remove AttachDebugDevTools

* Fix last warning

* Fix JSON fields
---
 Ryujinx.Ava/Ui/Controls/GameGridView.axaml    |   2 +-
 Ryujinx.Ava/Ui/Controls/GameListView.axaml    |   2 +-
 .../Ui/Controls/UpdateWaitWindow.axaml.cs     |   3 -
 Ryujinx.Ava/Ui/Models/CheatModel.cs           |   7 +-
 Ryujinx.Ava/Ui/Models/CheatsList.cs           |  32 +--
 Ryujinx.Ava/Ui/Models/DlcModel.cs             |  18 --
 .../Ui/Models/DownloadableContentModel.cs     |  18 ++
 .../Ui/ViewModels/AmiiboWindowViewModel.cs    |   4 +-
 .../Ui/ViewModels/MainWindowViewModel.cs      |   6 +-
 Ryujinx.Ava/Ui/Windows/AboutWindow.axaml.cs   |   4 -
 Ryujinx.Ava/Ui/Windows/AmiiboWindow.axaml.cs  |   9 +-
 Ryujinx.Ava/Ui/Windows/CheatWindow.axaml      |  73 ++---
 Ryujinx.Ava/Ui/Windows/CheatWindow.axaml.cs   |  13 +-
 .../Windows/ControllerSettingsWindow.axaml.cs |  10 -
 .../Ui/Windows/DlcManagerWindow.axaml.cs      | 254 -----------------
 ...=> DownloadableContentManagerWindow.axaml} |  10 +-
 .../DownloadableContentManagerWindow.axaml.cs | 266 ++++++++++++++++++
 Ryujinx.Ava/Ui/Windows/MainWindow.axaml       |   2 +-
 Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs    |  19 +-
 .../Ui/Windows/MotionSettingsWindow.axaml.cs  |   1 -
 .../Ui/Windows/RumbleSettingsWindow.axaml.cs  |   1 -
 .../Ui/Windows/SettingsWindow.axaml.cs        |  15 -
 Ryujinx.Ava/Ui/Windows/StyleableWindow.cs     |   1 -
 .../Ui/Windows/TitleUpdateWindow.axaml.cs     |  67 +++--
 Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml.cs |   5 +-
 Ryujinx.Common/Configuration/DlcContainer.cs  |  10 -
 Ryujinx.Common/Configuration/DlcNca.cs        |   9 -
 .../DownloadableContentContainer.cs           |  13 +
 .../Configuration/DownloadableContentNca.cs   |  14 +
 Ryujinx.HLE/HOS/ApplicationLoader.cs          |  12 +-
 Ryujinx/Ui/Windows/DlcWindow.cs               |  46 +--
 31 files changed, 456 insertions(+), 490 deletions(-)
 delete mode 100644 Ryujinx.Ava/Ui/Models/DlcModel.cs
 create mode 100644 Ryujinx.Ava/Ui/Models/DownloadableContentModel.cs
 delete mode 100644 Ryujinx.Ava/Ui/Windows/DlcManagerWindow.axaml.cs
 rename Ryujinx.Ava/Ui/Windows/{DlcManagerWindow.axaml => DownloadableContentManagerWindow.axaml} (94%)
 create mode 100644 Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml.cs
 delete mode 100644 Ryujinx.Common/Configuration/DlcContainer.cs
 delete mode 100644 Ryujinx.Common/Configuration/DlcNca.cs
 create mode 100644 Ryujinx.Common/Configuration/DownloadableContentContainer.cs
 create mode 100644 Ryujinx.Common/Configuration/DownloadableContentNca.cs

diff --git a/Ryujinx.Ava/Ui/Controls/GameGridView.axaml b/Ryujinx.Ava/Ui/Controls/GameGridView.axaml
index 431bcf00f1..bcf38e7a0e 100644
--- a/Ryujinx.Ava/Ui/Controls/GameGridView.axaml
+++ b/Ryujinx.Ava/Ui/Controls/GameGridView.axaml
@@ -37,7 +37,7 @@
                 Header="{locale:Locale GameListContextMenuManageTitleUpdates}"
                 ToolTip.Tip="{locale:Locale GameListContextMenuManageTitleUpdatesToolTip}" />
             <MenuItem
-                Command="{Binding OpenDlcManager}"
+                Command="{Binding OpenDownloadableContentManager}"
                 Header="{locale:Locale GameListContextMenuManageDlc}"
                 ToolTip.Tip="{locale:Locale GameListContextMenuManageDlcToolTip}" />
             <MenuItem
diff --git a/Ryujinx.Ava/Ui/Controls/GameListView.axaml b/Ryujinx.Ava/Ui/Controls/GameListView.axaml
index 6fe0b1620a..2c6022bded 100644
--- a/Ryujinx.Ava/Ui/Controls/GameListView.axaml
+++ b/Ryujinx.Ava/Ui/Controls/GameListView.axaml
@@ -37,7 +37,7 @@
                 Header="{locale:Locale GameListContextMenuManageTitleUpdates}"
                 ToolTip.Tip="{locale:Locale GameListContextMenuManageTitleUpdatesToolTip}" />
             <MenuItem
-                Command="{Binding OpenDlcManager}"
+                Command="{Binding OpenDownloadableContentManager}"
                 Header="{locale:Locale GameListContextMenuManageDlc}"
                 ToolTip.Tip="{locale:Locale GameListContextMenuManageDlcToolTip}" />
             <MenuItem
diff --git a/Ryujinx.Ava/Ui/Controls/UpdateWaitWindow.axaml.cs b/Ryujinx.Ava/Ui/Controls/UpdateWaitWindow.axaml.cs
index eff15c7ba3..19d6f98b50 100644
--- a/Ryujinx.Ava/Ui/Controls/UpdateWaitWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Controls/UpdateWaitWindow.axaml.cs
@@ -17,9 +17,6 @@ namespace Ryujinx.Ava.Ui.Controls
         public UpdateWaitWindow()
         {
             InitializeComponent();
-#if DEBUG
-            this.AttachDevTools();
-#endif
         }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Models/CheatModel.cs b/Ryujinx.Ava/Ui/Models/CheatModel.cs
index cdab27cd84..5011d3981b 100644
--- a/Ryujinx.Ava/Ui/Models/CheatModel.cs
+++ b/Ryujinx.Ava/Ui/Models/CheatModel.cs
@@ -11,8 +11,8 @@ namespace Ryujinx.Ava.Ui.Models
 
         public CheatModel(string name, string buildId, bool isEnabled)
         {
-            Name = name;
-            BuildId = buildId;
+            Name      = name;
+            BuildId   = buildId;
             IsEnabled = isEnabled;
         }
 
@@ -22,7 +22,9 @@ namespace Ryujinx.Ava.Ui.Models
             set
             {
                 _isEnabled = value;
+
                 EnableToggled?.Invoke(this, _isEnabled);
+
                 OnPropertyChanged();
             }
         }
@@ -30,6 +32,7 @@ namespace Ryujinx.Ava.Ui.Models
         public string BuildId { get; }
 
         public string BuildIdKey => $"{BuildId}-{Name}";
+
         public string Name { get; }
 
         public string CleanName => Name.Substring(1, Name.Length - 8);
diff --git a/Ryujinx.Ava/Ui/Models/CheatsList.cs b/Ryujinx.Ava/Ui/Models/CheatsList.cs
index f2b0592e97..8231e5211e 100644
--- a/Ryujinx.Ava/Ui/Models/CheatsList.cs
+++ b/Ryujinx.Ava/Ui/Models/CheatsList.cs
@@ -10,26 +10,13 @@ namespace Ryujinx.Ava.Ui.Models
         public CheatsList(string buildId, string path)
         {
             BuildId = buildId;
-            Path = path;
+            Path    = path;
+
             CollectionChanged += CheatsList_CollectionChanged;
         }
 
-        private void CheatsList_CollectionChanged(object sender,
-            NotifyCollectionChangedEventArgs e)
-        {
-            if (e.Action == NotifyCollectionChangedAction.Add)
-            {
-                (e.NewItems[0] as CheatModel).EnableToggled += Item_EnableToggled;
-            }
-        }
-
-        private void Item_EnableToggled(object sender, bool e)
-        {
-            OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsEnabled)));
-        }
-
         public string BuildId { get; }
-        public string Path { get; }
+        public string Path    { get; }
 
         public bool IsEnabled
         {
@@ -47,5 +34,18 @@ namespace Ryujinx.Ava.Ui.Models
                 OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsEnabled)));
             }
         }
+
+        private void CheatsList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+        {
+            if (e.Action == NotifyCollectionChangedAction.Add)
+            {
+                (e.NewItems[0] as CheatModel).EnableToggled += Item_EnableToggled;
+            }
+        }
+
+        private void Item_EnableToggled(object sender, bool e)
+        {
+            OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsEnabled)));
+        }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Models/DlcModel.cs b/Ryujinx.Ava/Ui/Models/DlcModel.cs
deleted file mode 100644
index 7e5f4a62fc..0000000000
--- a/Ryujinx.Ava/Ui/Models/DlcModel.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Ryujinx.Ava.Ui.Models
-{
-    public class DlcModel
-    {
-        public bool IsEnabled { get; set; }
-        public string TitleId { get; }
-        public string ContainerPath { get; }
-        public string FullPath { get; }
-
-        public DlcModel(string titleId, string containerPath, string fullPath, bool isEnabled)
-        {
-            TitleId = titleId;
-            ContainerPath = containerPath;
-            FullPath = fullPath;
-            IsEnabled = isEnabled;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Models/DownloadableContentModel.cs b/Ryujinx.Ava/Ui/Models/DownloadableContentModel.cs
new file mode 100644
index 0000000000..67530f62c4
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Models/DownloadableContentModel.cs
@@ -0,0 +1,18 @@
+namespace Ryujinx.Ava.Ui.Models
+{
+    public class DownloadableContentModel
+    {
+        public bool   Enabled       { get; set; }
+        public string TitleId       { get; }
+        public string ContainerPath { get; }
+        public string FullPath      { get; }
+
+        public DownloadableContentModel(string titleId, string containerPath, string fullPath, bool enabled)
+        {
+            TitleId       = titleId;
+            ContainerPath = containerPath;
+            FullPath      = fullPath;
+            Enabled       = enabled;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/ViewModels/AmiiboWindowViewModel.cs b/Ryujinx.Ava/Ui/ViewModels/AmiiboWindowViewModel.cs
index 7015df44e6..fc809e52ba 100644
--- a/Ryujinx.Ava/Ui/ViewModels/AmiiboWindowViewModel.cs
+++ b/Ryujinx.Ava/Ui/ViewModels/AmiiboWindowViewModel.cs
@@ -382,9 +382,9 @@ namespace Ryujinx.Ava.Ui.ViewModels
             {
                 string amiiboJsonString = await response.Content.ReadAsStringAsync();
 
-                using (FileStream dlcJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough))
+                using (FileStream amiiboJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough))
                 {
-                    dlcJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString));
+                    amiiboJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString));
                 }
 
                 return amiiboJsonString;
diff --git a/Ryujinx.Ava/Ui/ViewModels/MainWindowViewModel.cs b/Ryujinx.Ava/Ui/ViewModels/MainWindowViewModel.cs
index 7e6452f989..bd9242e7ca 100644
--- a/Ryujinx.Ava/Ui/ViewModels/MainWindowViewModel.cs
+++ b/Ryujinx.Ava/Ui/ViewModels/MainWindowViewModel.cs
@@ -1261,15 +1261,15 @@ namespace Ryujinx.Ava.Ui.ViewModels
             }
         }
 
-        public async void OpenDlcManager()
+        public async void OpenDownloadableContentManager()
         {
             var selection = SelectedApplication;
 
             if (selection != null)
             {
-                DlcManagerWindow dlcManager = new(_owner.VirtualFileSystem, ulong.Parse(selection.TitleId, NumberStyles.HexNumber), selection.TitleName);
+                DownloadableContentManagerWindow downloadableContentManager = new(_owner.VirtualFileSystem, ulong.Parse(selection.TitleId, NumberStyles.HexNumber), selection.TitleName);
 
-                await dlcManager.ShowDialog(_owner);
+                await downloadableContentManager.ShowDialog(_owner);
             }
         }
 
diff --git a/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml.cs
index 75e9901b02..90b870aafa 100644
--- a/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/AboutWindow.axaml.cs
@@ -2,7 +2,6 @@
 using Avalonia.Controls;
 using Avalonia.Input;
 using Avalonia.Interactivity;
-using Avalonia.Markup.Xaml;
 using Avalonia.Threading;
 using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Common.Utilities;
@@ -27,9 +26,6 @@ namespace Ryujinx.Ava.Ui.Windows
             DataContext = this;
 
             InitializeComponent();
-#if DEBUG
-            this.AttachDevTools();
-#endif
 
             _ = DownloadPatronsJson();
         }
diff --git a/Ryujinx.Ava/Ui/Windows/AmiiboWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/AmiiboWindow.axaml.cs
index 5ed845710d..9333a40e28 100644
--- a/Ryujinx.Ava/Ui/Windows/AmiiboWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/AmiiboWindow.axaml.cs
@@ -1,6 +1,5 @@
 using Avalonia;
 using Avalonia.Interactivity;
-using Avalonia.Markup.Xaml;
 using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Ava.Ui.Models;
 using Ryujinx.Ava.Ui.ViewModels;
@@ -18,9 +17,7 @@ namespace Ryujinx.Ava.Ui.Windows
             DataContext = ViewModel;
 
             InitializeComponent();
-#if DEBUG
-            this.AttachDevTools();
-#endif
+
             Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["Amiibo"];
         }
 
@@ -31,9 +28,7 @@ namespace Ryujinx.Ava.Ui.Windows
             DataContext = ViewModel;
 
             InitializeComponent();
-#if DEBUG
-            this.AttachDevTools();
-#endif
+
             if (Program.PreviewerDetached)
             {
                 Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["Amiibo"];
diff --git a/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml b/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml
index a5a4b0eeb1..8d91161161 100644
--- a/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml
+++ b/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml
@@ -1,21 +1,24 @@
-<window:StyleableWindow x:Class="Ryujinx.Ava.Ui.Windows.CheatWindow"
-                        xmlns="https://github.com/avaloniaui"
-                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-                        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-                        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-                        xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
-                        xmlns:model="clr-namespace:Ryujinx.Ava.Ui.Models"
-                        xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
-                        mc:Ignorable="d"
-                        Width="500" MinHeight="500" Height="500"
-                        WindowStartupLocation="CenterOwner"
-                        MinWidth="500">
+<window:StyleableWindow
+    x:Class="Ryujinx.Ava.Ui.Windows.CheatWindow"
+    xmlns="https://github.com/avaloniaui"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+    xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    xmlns:model="clr-namespace:Ryujinx.Ava.Ui.Models"
+    xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
+    Width="500"
+    Height="500"
+    MinWidth="500"
+    MinHeight="500"
+    WindowStartupLocation="CenterOwner"
+    mc:Ignorable="d">
     <Window.Styles>
         <Style Selector="TreeViewItem">
             <Setter Property="IsExpanded" Value="True" />
         </Style>
     </Window.Styles>
-    <Grid Name="DlcGrid" Margin="15">
+    <Grid Name="CheatGrid" Margin="15">
         <Grid.RowDefinitions>
             <RowDefinition Height="Auto" />
             <RowDefinition Height="Auto" />
@@ -24,14 +27,14 @@
         </Grid.RowDefinitions>
         <TextBlock
             Grid.Row="1"
+            MaxWidth="500"
             Margin="20,15,20,20"
             HorizontalAlignment="Center"
             VerticalAlignment="Center"
-            MaxWidth="500"
             LineHeight="18"
-            TextWrapping="Wrap"
             Text="{Binding Heading}"
-            TextAlignment="Center" />
+            TextAlignment="Center"
+            TextWrapping="Wrap" />
         <Border
             Grid.Row="2"
             Margin="5"
@@ -39,32 +42,38 @@
             VerticalAlignment="Stretch"
             BorderBrush="Gray"
             BorderThickness="1">
-            <TreeView Items="{Binding LoadedCheats}"
-                      HorizontalAlignment="Stretch"
-                      VerticalAlignment="Stretch"
-                      Name="CheatsView"
-                      MinHeight="300">
+            <TreeView
+                Name="CheatsView"
+                MinHeight="300"
+                HorizontalAlignment="Stretch"
+                VerticalAlignment="Stretch"
+                Items="{Binding LoadedCheats}">
                 <TreeView.Styles>
                     <Styles>
                         <Style Selector="TreeViewItem:empty /template/ ItemsPresenter">
-                            <Setter Property="IsVisible" Value="False"/>
+                            <Setter Property="IsVisible" Value="False" />
                         </Style>
                     </Styles>
                 </TreeView.Styles>
                 <TreeView.DataTemplates>
                     <TreeDataTemplate DataType="model:CheatsList" ItemsSource="{Binding}">
                         <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
-                            <CheckBox IsChecked="{Binding IsEnabled}" MinWidth="20" />
-                            <TextBlock Width="150"
-                                       Text="{Binding BuildId}" />
-                            <TextBlock
-                                Text="{Binding Path}" />
+                            <CheckBox MinWidth="20" IsChecked="{Binding IsEnabled}" />
+                            <TextBlock Width="150" Text="{Binding BuildId}" />
+                            <TextBlock Text="{Binding Path}" />
                         </StackPanel>
                     </TreeDataTemplate>
                     <DataTemplate x:DataType="model:CheatModel">
-                        <StackPanel Orientation="Horizontal" Margin="0" HorizontalAlignment="Left">
-                            <CheckBox IsChecked="{Binding IsEnabled}" Padding="0" Margin="5,0" MinWidth="20" />
-                            <TextBlock Text="{Binding CleanName}" VerticalAlignment="Center" />
+                        <StackPanel
+                            Margin="0"
+                            HorizontalAlignment="Left"
+                            Orientation="Horizontal">
+                            <CheckBox
+                                MinWidth="20"
+                                Margin="5,0"
+                                Padding="0"
+                                IsChecked="{Binding IsEnabled}" />
+                            <TextBlock VerticalAlignment="Center" Text="{Binding CleanName}" />
                         </StackPanel>
                     </DataTemplate>
                 </TreeView.DataTemplates>
@@ -79,8 +88,8 @@
                     Name="SaveButton"
                     MinWidth="90"
                     Margin="5"
-                    IsVisible="{Binding !NoCheatsFound}"
-                    Command="{Binding Save}">
+                    Command="{Binding Save}"
+                    IsVisible="{Binding !NoCheatsFound}">
                     <TextBlock Text="{locale:Locale SettingsButtonSave}" />
                 </Button>
                 <Button
diff --git a/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml.cs
index e3cccdd3bc..13c2f20a8b 100644
--- a/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/CheatWindow.axaml.cs
@@ -1,6 +1,5 @@
 using Avalonia;
 using Avalonia.Collections;
-using Avalonia.Markup.Xaml;
 using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Ava.Ui.Models;
 using Ryujinx.HLE.FileSystem;
@@ -26,8 +25,7 @@ namespace Ryujinx.Ava.Ui.Windows
             DataContext = this;
 
             InitializeComponent();
-            AttachDebugDevTools();
-            
+
             Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["CheatWindowTitle"];
         }
 
@@ -38,9 +36,6 @@ namespace Ryujinx.Ava.Ui.Windows
             Heading = string.Format(LocaleManager.Instance["CheatWindowHeading"], titleName, titleId.ToUpper());
 
             InitializeComponent();
-#if DEBUG
-            this.AttachDevTools();
-#endif
 
             string modsBasePath = virtualFileSystem.ModLoader.GetModsBasePath();
             string titleModsPath = virtualFileSystem.ModLoader.GetTitleDir(modsBasePath, titleId);
@@ -96,12 +91,6 @@ namespace Ryujinx.Ava.Ui.Windows
             Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["CheatWindowTitle"];
         }
 
-        [Conditional("DEBUG")]
-        private void AttachDebugDevTools()
-        {
-            this.AttachDevTools();
-        }
-
         public void Save()
         {
             if (NoCheatsFound)
diff --git a/Ryujinx.Ava/Ui/Windows/ControllerSettingsWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/ControllerSettingsWindow.axaml.cs
index 45262bcd5d..82ef75ca55 100644
--- a/Ryujinx.Ava/Ui/Windows/ControllerSettingsWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/ControllerSettingsWindow.axaml.cs
@@ -3,24 +3,14 @@ using Avalonia.Controls.Primitives;
 using Avalonia.Input;
 using Avalonia.Interactivity;
 using Avalonia.LogicalTree;
-using Avalonia.Markup.Xaml;
-using Avalonia.Threading;
-using Avalonia.VisualTree;
 using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Ava.Ui.Controls;
 using Ryujinx.Ava.Ui.Models;
 using Ryujinx.Ava.Ui.ViewModels;
-using Ryujinx.Common.Configuration.Hid;
 using Ryujinx.Common.Configuration.Hid.Controller;
 using Ryujinx.Input;
 using Ryujinx.Input.Assigner;
-using Ryujinx.Ui.Common.Configuration;
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Key = Ryujinx.Input.Key;
 
 namespace Ryujinx.Ava.Ui.Windows
 {
diff --git a/Ryujinx.Ava/Ui/Windows/DlcManagerWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/DlcManagerWindow.axaml.cs
deleted file mode 100644
index 09b221e3fc..0000000000
--- a/Ryujinx.Ava/Ui/Windows/DlcManagerWindow.axaml.cs
+++ /dev/null
@@ -1,254 +0,0 @@
-using Avalonia;
-using Avalonia.Collections;
-using Avalonia.Controls;
-using Avalonia.Threading;
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Fsa;
-using LibHac.FsSystem;
-using LibHac.Tools.Fs;
-using LibHac.Tools.FsSystem;
-using LibHac.Tools.FsSystem.NcaUtils;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.Ui.Controls;
-using Ryujinx.Ava.Ui.Models;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Utilities;
-using Ryujinx.HLE.FileSystem;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Path = System.IO.Path;
-
-namespace Ryujinx.Ava.Ui.Windows
-{
-    public partial class DlcManagerWindow : StyleableWindow
-    {
-        private readonly List<DlcContainer> _dlcContainerList;
-        private readonly string _dlcJsonPath;
-
-        public VirtualFileSystem VirtualFileSystem { get; }
-
-        public AvaloniaList<DlcModel> Dlcs { get; set; }
-        public ulong TitleId { get; }
-        public string TitleName { get; }
-
-        public string Heading => string.Format(LocaleManager.Instance["DlcWindowHeading"], TitleName, TitleId.ToString("X16"));
-
-        public DlcManagerWindow()
-        {
-            DataContext = this;
-
-            InitializeComponent();
-            AttachDebugDevTools();
-
-            Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["DlcWindowTitle"];
-        }
-
-        public DlcManagerWindow(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName)
-        {
-            VirtualFileSystem = virtualFileSystem;
-            TitleId = titleId;
-            TitleName = titleName;
-
-            _dlcJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId.ToString("x16"), "dlc.json");
-
-            try
-            {
-                _dlcContainerList = JsonHelper.DeserializeFromFile<List<DlcContainer>>(_dlcJsonPath);
-            }
-            catch
-            {
-                _dlcContainerList = new List<DlcContainer>();
-            }
-
-            DataContext = this;
-
-            InitializeComponent();
-            AttachDebugDevTools();
-
-            Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["DlcWindowTitle"];
-
-            LoadDlcs();
-        }
-
-        [Conditional("DEBUG")]
-        private void AttachDebugDevTools()
-        {
-            this.AttachDevTools();
-        }
-
-        private void LoadDlcs()
-        {
-            foreach (DlcContainer dlcContainer in _dlcContainerList)
-            {
-                using FileStream containerFile = File.OpenRead(dlcContainer.Path);
-
-                PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage());
-
-                VirtualFileSystem.ImportTickets(pfs);
-
-                foreach (DlcNca dlcNca in dlcContainer.DlcNcaList)
-                {
-                    using var ncaFile = new UniqueRef<IFile>();
-                    pfs.OpenFile(ref ncaFile.Ref(), dlcNca.Path.ToU8Span(), OpenMode.Read).ThrowIfFailure();
-
-                    Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), dlcContainer.Path);
-
-                    if (nca != null)
-                    {
-                        Dlcs.Add(new DlcModel(nca.Header.TitleId.ToString("X16"), dlcContainer.Path, dlcNca.Path,
-                            dlcNca.Enabled));
-                    }
-                }
-            }
-        }
-
-        private Nca TryCreateNca(IStorage ncaStorage, string containerPath)
-        {
-            try
-            {
-                return new Nca(VirtualFileSystem.KeySet, ncaStorage);
-            }
-            catch (Exception ex)
-            {
-                Dispatcher.UIThread.InvokeAsync(async () =>
-                {
-                    await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance[
-                        "DialogDlcLoadNcaErrorMessage"], ex.Message, containerPath));
-                });
-            }
-
-            return null;
-        }
-
-        private async Task AddDlc(string path)
-        {
-            if (!File.Exists(path) || Dlcs.FirstOrDefault(x => x.ContainerPath == path) != null)
-            {
-                return;
-            }
-
-            using (FileStream containerFile = File.OpenRead(path))
-            {
-                PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage());
-                bool containsDlc = false;
-
-                VirtualFileSystem.ImportTickets(pfs);
-
-                foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
-                {
-                    using var ncaFile = new UniqueRef<IFile>();
-
-                    pfs.OpenFile(ref ncaFile.Ref(), fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
-
-                    Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), path);
-
-                    if (nca == null)
-                    {
-                        continue;
-                    }
-
-                    if (nca.Header.ContentType == NcaContentType.PublicData)
-                    {
-                        if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000) != TitleId)
-                        {
-                            break;
-                        }
-
-                        Dlcs.Add(new DlcModel(nca.Header.TitleId.ToString("X16"), path, fileEntry.FullPath, true));
-
-                        containsDlc = true;
-                    }
-                }
-
-                if (!containsDlc)
-                {
-                    await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogDlcNoDlcErrorMessage"]);
-                }
-            }
-        }
-
-        private void RemoveDlcs(bool removeSelectedOnly = false)
-        {
-            if (removeSelectedOnly)
-            {
-                Dlcs.RemoveAll(Dlcs.Where(x => x.IsEnabled).ToList());
-            }
-            else
-            {
-                Dlcs.Clear();
-            }
-        }
-
-        public void RemoveSelected()
-        {
-            RemoveDlcs(true);
-        }
-
-        public void RemoveAll()
-        {
-            RemoveDlcs();
-        }
-
-        public async void Add()
-        {
-            OpenFileDialog dialog = new OpenFileDialog() { Title = LocaleManager.Instance["SelectDlcDialogTitle"], AllowMultiple = true };
-
-            dialog.Filters.Add(new FileDialogFilter { Name = "NSP", Extensions = { "nsp" } });
-
-            string[] files = await dialog.ShowAsync(this);
-
-            if (files != null)
-            {
-                foreach (string file in files)
-                {
-                   await AddDlc(file);
-                }
-            }
-        }
-
-        public void Save()
-        {
-            _dlcContainerList.Clear();
-
-            DlcContainer container = default;
-
-            foreach (DlcModel dlc in Dlcs)
-            {
-                if (container.Path != dlc.ContainerPath)
-                {
-                    if (!string.IsNullOrWhiteSpace(container.Path))
-                    {
-                        _dlcContainerList.Add(container);
-                    }
-
-                    container = new DlcContainer { Path = dlc.ContainerPath, DlcNcaList = new List<DlcNca>() };
-                }
-
-                container.DlcNcaList.Add(new DlcNca
-                {
-                    Enabled = dlc.IsEnabled,
-                    TitleId = Convert.ToUInt64(dlc.TitleId, 16),
-                    Path = dlc.FullPath
-                });
-            }
-
-            if (!string.IsNullOrWhiteSpace(container.Path))
-            {
-                _dlcContainerList.Add(container);
-            }
-
-            using (FileStream dlcJsonStream = File.Create(_dlcJsonPath, 4096, FileOptions.WriteThrough))
-            {
-                dlcJsonStream.Write(Encoding.UTF8.GetBytes(JsonHelper.Serialize(_dlcContainerList, true)));
-            }
-
-            Close();
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Windows/DlcManagerWindow.axaml b/Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml
similarity index 94%
rename from Ryujinx.Ava/Ui/Windows/DlcManagerWindow.axaml
rename to Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml
index 94b3895ef4..068ea826a8 100644
--- a/Ryujinx.Ava/Ui/Windows/DlcManagerWindow.axaml
+++ b/Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml
@@ -1,5 +1,5 @@
 <window:StyleableWindow
-    x:Class="Ryujinx.Ava.Ui.Windows.DlcManagerWindow"
+    x:Class="Ryujinx.Ava.Ui.Windows.DownloadableContentManagerWindow"
     xmlns="https://github.com/avaloniaui"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -11,7 +11,7 @@
     WindowStartupLocation="CenterOwner"
     MinWidth="600"
     mc:Ignorable="d">
-    <Grid Name="DlcGrid" Margin="15">
+    <Grid Name="DownloadableContentGrid" Margin="15">
         <Grid.RowDefinitions>
             <RowDefinition Height="Auto" />
             <RowDefinition Height="Auto" />
@@ -40,7 +40,7 @@
                 HorizontalAlignment="Stretch"
                 VerticalAlignment="Stretch"
                 HorizontalScrollBarVisibility="Auto"
-                Items="{Binding Dlcs}"
+                Items="{Binding DownloadableContents}"
                 VerticalScrollBarVisibility="Auto">
                 <DataGrid.Columns>
                     <DataGridTemplateColumn Width="90">
@@ -50,7 +50,7 @@
                                     Width="50"
                                     MinWidth="40"
                                     HorizontalAlignment="Right"
-                                    IsChecked="{Binding IsEnabled}" />
+                                    IsChecked="{Binding Enabled}" />
                             </DataTemplate>
                         </DataGridTemplateColumn.CellTemplate>
                         <DataGridTemplateColumn.Header>
@@ -116,7 +116,7 @@
                     Name="SaveButton"
                     MinWidth="90"
                     Margin="5"
-                    Command="{Binding Save}">
+                    Command="{Binding SaveAndClose}">
                     <TextBlock Text="{locale:Locale SettingsButtonSave}" />
                 </Button>
                 <Button
diff --git a/Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml.cs
new file mode 100644
index 0000000000..972ffbc3e4
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml.cs
@@ -0,0 +1,266 @@
+using Avalonia.Collections;
+using Avalonia.Controls;
+using Avalonia.Threading;
+using LibHac.Common;
+using LibHac.Fs;
+using LibHac.Fs.Fsa;
+using LibHac.FsSystem;
+using LibHac.Tools.Fs;
+using LibHac.Tools.FsSystem;
+using LibHac.Tools.FsSystem.NcaUtils;
+using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.Ui.Controls;
+using Ryujinx.Ava.Ui.Models;
+using Ryujinx.Common.Configuration;
+using Ryujinx.Common.Utilities;
+using Ryujinx.HLE.FileSystem;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Path = System.IO.Path;
+
+namespace Ryujinx.Ava.Ui.Windows
+{
+    public partial class DownloadableContentManagerWindow : StyleableWindow
+    {
+        private readonly List<DownloadableContentContainer> _downloadableContentContainerList;
+        private readonly string _downloadableContentJsonPath;
+
+        public VirtualFileSystem VirtualFileSystem { get; }
+        public AvaloniaList<DownloadableContentModel> DownloadableContents { get; set; } = new AvaloniaList<DownloadableContentModel>();
+        public ulong TitleId { get; }
+        public string TitleName { get; }
+
+        public string Heading => string.Format(LocaleManager.Instance["DlcWindowHeading"], TitleName, TitleId.ToString("X16"));
+
+        public DownloadableContentManagerWindow()
+        {
+            DataContext = this;
+
+            InitializeComponent();
+
+            Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["DlcWindowTitle"];
+        }
+
+        public DownloadableContentManagerWindow(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName)
+        {
+            VirtualFileSystem = virtualFileSystem;
+            TitleId           = titleId;
+            TitleName         = titleName;
+
+            _downloadableContentJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId.ToString("x16"), "dlc.json");
+
+            try
+            {
+                _downloadableContentContainerList = JsonHelper.DeserializeFromFile<List<DownloadableContentContainer>>(_downloadableContentJsonPath);
+            }
+            catch
+            {
+                _downloadableContentContainerList = new List<DownloadableContentContainer>();
+            }
+
+            DataContext = this;
+
+            InitializeComponent();
+
+            Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["DlcWindowTitle"];
+
+            LoadDownloadableContents();
+        }
+
+        private void LoadDownloadableContents()
+        {
+            foreach (DownloadableContentContainer downloadableContentContainer in _downloadableContentContainerList)
+            {
+                if (File.Exists(downloadableContentContainer.ContainerPath))
+                {
+                    using FileStream containerFile = File.OpenRead(downloadableContentContainer.ContainerPath);
+
+                    PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage());
+
+                    VirtualFileSystem.ImportTickets(pfs);
+
+                    foreach (DownloadableContentNca downloadableContentNca in downloadableContentContainer.DownloadableContentNcaList)
+                    {
+                        using var ncaFile = new UniqueRef<IFile>();
+
+                        pfs.OpenFile(ref ncaFile.Ref(), downloadableContentNca.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
+
+                        Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), downloadableContentContainer.ContainerPath);
+                        if (nca != null)
+                        {
+                            DownloadableContents.Add(new DownloadableContentModel(nca.Header.TitleId.ToString("X16"),
+                                                                                  downloadableContentContainer.ContainerPath,
+                                                                                  downloadableContentNca.FullPath,
+                                                                                  downloadableContentNca.Enabled));
+                        }
+                    }
+                }
+            }
+
+            // NOTE: Save the list again to remove leftovers.
+            Save();
+        }
+
+        private Nca TryCreateNca(IStorage ncaStorage, string containerPath)
+        {
+            try
+            {
+                return new Nca(VirtualFileSystem.KeySet, ncaStorage);
+            }
+            catch (Exception ex)
+            {
+                Dispatcher.UIThread.InvokeAsync(async () =>
+                {
+                    await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogDlcLoadNcaErrorMessage"], ex.Message, containerPath));
+                });
+            }
+
+            return null;
+        }
+
+        private async Task AddDownloadableContent(string path)
+        {
+            if (!File.Exists(path) || DownloadableContents.FirstOrDefault(x => x.ContainerPath == path) != null)
+            {
+                return;
+            }
+
+            using (FileStream containerFile = File.OpenRead(path))
+            {
+                PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage());
+                bool containsDownloadableContent = false;
+
+                VirtualFileSystem.ImportTickets(pfs);
+
+                foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
+                {
+                    using var ncaFile = new UniqueRef<IFile>();
+
+                    pfs.OpenFile(ref ncaFile.Ref(), fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
+
+                    Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), path);
+
+                    if (nca == null)
+                    {
+                        continue;
+                    }
+
+                    if (nca.Header.ContentType == NcaContentType.PublicData)
+                    {
+                        if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000) != TitleId)
+                        {
+                            break;
+                        }
+
+                        DownloadableContents.Add(new DownloadableContentModel(nca.Header.TitleId.ToString("X16"), path, fileEntry.FullPath, true));
+
+                        containsDownloadableContent = true;
+                    }
+                }
+
+                if (!containsDownloadableContent)
+                {
+                    await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogDlcNoDlcErrorMessage"]);
+                }
+            }
+        }
+
+        private void RemoveDownloadableContents(bool removeSelectedOnly = false)
+        {
+            if (removeSelectedOnly)
+            {
+                DownloadableContents.RemoveAll(DownloadableContents.Where(x => x.Enabled).ToList());
+            }
+            else
+            {
+                DownloadableContents.Clear();
+            }
+        }
+
+        public void RemoveSelected()
+        {
+            RemoveDownloadableContents(true);
+        }
+
+        public void RemoveAll()
+        {
+            RemoveDownloadableContents();
+        }
+
+        public async void Add()
+        {
+            OpenFileDialog dialog = new OpenFileDialog()
+            { 
+                Title         = LocaleManager.Instance["SelectDlcDialogTitle"],
+                AllowMultiple = true
+            };
+
+            dialog.Filters.Add(new FileDialogFilter
+            {
+                Name       = "NSP",
+                Extensions = { "nsp" }
+            });
+
+            string[] files = await dialog.ShowAsync(this);
+
+            if (files != null)
+            {
+                foreach (string file in files)
+                {
+                   await AddDownloadableContent(file);
+                }
+            }
+        }
+
+        public void Save()
+        {
+            _downloadableContentContainerList.Clear();
+
+            DownloadableContentContainer container = default;
+
+            foreach (DownloadableContentModel downloadableContent in DownloadableContents)
+            {
+                if (container.ContainerPath != downloadableContent.ContainerPath)
+                {
+                    if (!string.IsNullOrWhiteSpace(container.ContainerPath))
+                    {
+                        _downloadableContentContainerList.Add(container);
+                    }
+
+                    container = new DownloadableContentContainer
+                    {
+                        ContainerPath              = downloadableContent.ContainerPath,
+                        DownloadableContentNcaList = new List<DownloadableContentNca>()
+                    };
+                }
+
+                container.DownloadableContentNcaList.Add(new DownloadableContentNca
+                {
+                    Enabled  = downloadableContent.Enabled,
+                    TitleId  = Convert.ToUInt64(downloadableContent.TitleId, 16),
+                    FullPath = downloadableContent.FullPath
+                });
+            }
+
+            if (!string.IsNullOrWhiteSpace(container.ContainerPath))
+            {
+                _downloadableContentContainerList.Add(container);
+            }
+
+            using (FileStream downloadableContentJsonStream = File.Create(_downloadableContentJsonPath, 4096, FileOptions.WriteThrough))
+            {
+                downloadableContentJsonStream.Write(Encoding.UTF8.GetBytes(JsonHelper.Serialize(_downloadableContentContainerList, true)));
+            }
+        }
+
+        public void SaveAndClose()
+        {
+            Save();
+            Close();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Windows/MainWindow.axaml b/Ryujinx.Ava/Ui/Windows/MainWindow.axaml
index ab4d76de41..a08ca91058 100644
--- a/Ryujinx.Ava/Ui/Windows/MainWindow.axaml
+++ b/Ryujinx.Ava/Ui/Windows/MainWindow.axaml
@@ -257,7 +257,7 @@
                 </DockPanel>
             </StackPanel>
             <ContentControl
-                Name="Content"
+                Name="MainContent"
                 Grid.Row="1"
                 Padding="0"
                 HorizontalAlignment="Stretch"
diff --git a/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs
index d55dd41325..a5e3c06a0d 100644
--- a/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs
@@ -2,10 +2,8 @@ using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Input;
 using Avalonia.Interactivity;
-using Avalonia.Markup.Xaml;
 using Avalonia.Media;
 using Avalonia.Threading;
-using Avalonia.Win32;
 using FluentAvalonia.UI.Controls;
 using Ryujinx.Ava.Common;
 using Ryujinx.Ava.Common.Locale;
@@ -33,7 +31,7 @@ using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
 using InputManager = Ryujinx.Input.HLE.InputManager;
-using ProgressBar = Avalonia.Controls.ProgressBar;
+
 namespace Ryujinx.Ava.Ui.Windows
 {
     public partial class MainWindow : StyleableWindow
@@ -87,7 +85,6 @@ namespace Ryujinx.Ava.Ui.Windows
 
             InitializeComponent();
             Load();
-            AttachDebugDevTools();
 
             UiHandler = new AvaHostUiHandler(this);
 
@@ -110,12 +107,6 @@ namespace Ryujinx.Ava.Ui.Windows
             _rendererWaitEvent = new AutoResetEvent(false);
         }
 
-        [Conditional("DEBUG")]
-        private void AttachDebugDevTools()
-        {
-            this.AttachDevTools();
-        }
-
         public void LoadGameList()
         {
             if (_isLoading)
@@ -244,7 +235,7 @@ namespace Ryujinx.Ava.Ui.Windows
 
             PrepareLoadScreen();
 
-            _mainViewContent = Content.Content as Control;
+            _mainViewContent = MainContent.Content as Control;
 
             GlRenderer = new RendererControl(3, 3, ConfigurationState.Instance.Logger.GraphicsDebugLevel);
             AppHost = new AppHost(GlRenderer, InputManager, path, VirtualFileSystem, ContentManager, AccountManager, _userChannelPersistence, this);
@@ -311,7 +302,7 @@ namespace Ryujinx.Ava.Ui.Windows
 
             Dispatcher.UIThread.InvokeAsync(() =>
             {
-                Content.Content = GlRenderer;
+                MainContent.Content = GlRenderer;
 
                 if (startFullscreen && WindowState != WindowState.FullScreen)
                 {
@@ -355,9 +346,9 @@ namespace Ryujinx.Ava.Ui.Windows
 
             Dispatcher.UIThread.InvokeAsync(() =>
             {
-                if (Content.Content != _mainViewContent)
+                if (MainContent.Content != _mainViewContent)
                 {
-                    Content.Content = _mainViewContent;
+                    MainContent.Content = _mainViewContent;
                 }
 
                 ViewModel.ShowMenuAndStatusBar = true;
diff --git a/Ryujinx.Ava/Ui/Windows/MotionSettingsWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/MotionSettingsWindow.axaml.cs
index ec9195302b..b478198416 100644
--- a/Ryujinx.Ava/Ui/Windows/MotionSettingsWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/MotionSettingsWindow.axaml.cs
@@ -1,5 +1,4 @@
 using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
 using FluentAvalonia.UI.Controls;
 using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Ava.Ui.Models;
diff --git a/Ryujinx.Ava/Ui/Windows/RumbleSettingsWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/RumbleSettingsWindow.axaml.cs
index bc8b04e4d9..afb5a33ac0 100644
--- a/Ryujinx.Ava/Ui/Windows/RumbleSettingsWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/RumbleSettingsWindow.axaml.cs
@@ -1,5 +1,4 @@
 using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
 using FluentAvalonia.UI.Controls;
 using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Ava.Ui.Models;
diff --git a/Ryujinx.Ava/Ui/Windows/SettingsWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/SettingsWindow.axaml.cs
index 371d6b6435..cdac6ef680 100644
--- a/Ryujinx.Ava/Ui/Windows/SettingsWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/SettingsWindow.axaml.cs
@@ -1,19 +1,14 @@
 using Avalonia;
 using Avalonia.Controls;
-using Avalonia.Controls.Presenters;
 using Avalonia.Controls.Primitives;
 using Avalonia.Data;
 using Avalonia.Data.Converters;
 using Avalonia.Input;
 using Avalonia.Interactivity;
-using Avalonia.LogicalTree;
-using Avalonia.Markup.Xaml;
-using Avalonia.Threading;
 using FluentAvalonia.Core;
 using FluentAvalonia.UI.Controls;
 using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Ava.Ui.Controls;
-using Ryujinx.Ava.Ui.Models;
 using Ryujinx.Ava.Ui.ViewModels;
 using Ryujinx.HLE.FileSystem;
 using Ryujinx.Input;
@@ -23,8 +18,6 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
 using TimeZone = Ryujinx.Ava.Ui.Models.TimeZone;
 
 namespace Ryujinx.Ava.Ui.Windows
@@ -44,7 +37,6 @@ namespace Ryujinx.Ava.Ui.Windows
 
             InitializeComponent();
             Load();
-            AttachDebugDevTools();
 
             FuncMultiValueConverter<string, string> converter = new(parts => string.Format("{0}  {1}   {2}", parts.ToArray()));
             MultiBinding tzMultiBinding = new() { Converter = converter };
@@ -62,13 +54,6 @@ namespace Ryujinx.Ava.Ui.Windows
 
             InitializeComponent();
             Load();
-            AttachDebugDevTools();
-        }
-
-        [Conditional("DEBUG")]
-        private void AttachDebugDevTools()
-        {
-            this.AttachDevTools();
         }
 
         private void Load()
diff --git a/Ryujinx.Ava/Ui/Windows/StyleableWindow.cs b/Ryujinx.Ava/Ui/Windows/StyleableWindow.cs
index f427adc3e9..5f537ed124 100644
--- a/Ryujinx.Ava/Ui/Windows/StyleableWindow.cs
+++ b/Ryujinx.Ava/Ui/Windows/StyleableWindow.cs
@@ -2,7 +2,6 @@
 using Avalonia.Controls.Primitives;
 using Avalonia.Media.Imaging;
 using Avalonia.Platform;
-using FluentAvalonia.UI.Controls;
 using System;
 using System.IO;
 using System.Reflection;
diff --git a/Ryujinx.Ava/Ui/Windows/TitleUpdateWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/TitleUpdateWindow.axaml.cs
index 4e26ee7363..f1f7850e2d 100644
--- a/Ryujinx.Ava/Ui/Windows/TitleUpdateWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/TitleUpdateWindow.axaml.cs
@@ -1,13 +1,14 @@
 using Avalonia;
 using Avalonia.Collections;
 using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
+using Avalonia.Threading;
 using LibHac.Common;
 using LibHac.Fs;
 using LibHac.Fs.Fsa;
 using LibHac.FsSystem;
-using LibHac.Tools.FsSystem.NcaUtils;
 using LibHac.Ns;
+using LibHac.Tools.FsSystem;
+using LibHac.Tools.FsSystem.NcaUtils;
 using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Ava.Ui.Controls;
 using Ryujinx.Ava.Ui.Models;
@@ -23,14 +24,12 @@ using System.Linq;
 using System.Text;
 using Path = System.IO.Path;
 using SpanHelpers = LibHac.Common.SpanHelpers;
-using LibHac.Tools.FsSystem;
-using Avalonia.Threading;
 
 namespace Ryujinx.Ava.Ui.Windows
 {
     public partial class TitleUpdateWindow : StyleableWindow
     {
-        private readonly string _updateJsonPath;
+        private readonly string     _titleUpdateJsonPath;
         private TitleUpdateMetadata _titleUpdateWindowData;
 
         public VirtualFileSystem VirtualFileSystem { get; }
@@ -46,7 +45,6 @@ namespace Ryujinx.Ava.Ui.Windows
             DataContext = this;
 
             InitializeComponent();
-            AttachDebugDevTools();
             
             Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["UpdateWindowTitle"];
         }
@@ -54,36 +52,33 @@ namespace Ryujinx.Ava.Ui.Windows
         public TitleUpdateWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName)
         {
             VirtualFileSystem = virtualFileSystem;
-            TitleId = titleId;
-            TitleName = titleName;
+            TitleId           = titleId;
+            TitleName         = titleName;
 
-            _updateJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId, "updates.json");
+            _titleUpdateJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId, "updates.json");
 
             try
             {
-                _titleUpdateWindowData = JsonHelper.DeserializeFromFile<TitleUpdateMetadata>(_updateJsonPath);
+                _titleUpdateWindowData = JsonHelper.DeserializeFromFile<TitleUpdateMetadata>(_titleUpdateJsonPath);
             }
             catch
             {
-                _titleUpdateWindowData = new TitleUpdateMetadata {Selected = "", Paths = new List<string>()};
+                _titleUpdateWindowData = new TitleUpdateMetadata 
+                {
+                    Selected = "",
+                    Paths = new List<string>()
+                };
             }
 
             DataContext = this;
 
             InitializeComponent();
-            AttachDebugDevTools();
-            
+
             Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["UpdateWindowTitle"];
 
             LoadUpdates();
         }
 
-        [Conditional("DEBUG")]
-        private void AttachDebugDevTools()
-        {
-            this.AttachDevTools();
-        }
-
         private void LoadUpdates()
         {
             TitleUpdates.Add(new TitleUpdateModel(default, string.Empty, true));
@@ -99,8 +94,8 @@ namespace Ryujinx.Ava.Ui.Windows
             }
             else
             {
-                TitleUpdateModel selected = TitleUpdates.FirstOrDefault(x => x.Path == _titleUpdateWindowData.Selected);
-                List<TitleUpdateModel> enabled = TitleUpdates.Where(x => x.IsEnabled).ToList();
+                TitleUpdateModel       selected = TitleUpdates.FirstOrDefault(x => x.Path == _titleUpdateWindowData.Selected);
+                List<TitleUpdateModel> enabled  = TitleUpdates.Where(x => x.IsEnabled).ToList();
 
                 foreach (TitleUpdateModel update in enabled)
                 {
@@ -126,8 +121,7 @@ namespace Ryujinx.Ava.Ui.Windows
 
                     try
                     {
-                        (Nca patchNca, Nca controlNca) =
-                            ApplicationLoader.GetGameUpdateDataFromPartition(VirtualFileSystem, nsp, TitleId, 0);
+                        (Nca patchNca, Nca controlNca) = ApplicationLoader.GetGameUpdateDataFromPartition(VirtualFileSystem, nsp, TitleId, 0);
 
                         if (controlNca != null && patchNca != null)
                         {
@@ -135,11 +129,8 @@ namespace Ryujinx.Ava.Ui.Windows
 
                             using var nacpFile = new UniqueRef<IFile>();
 
-                            controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None)
-                                .OpenFile(ref nacpFile.Ref(), "/control.nacp".ToU8Span(), OpenMode.Read)
-                                .ThrowIfFailure();
-                            nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None)
-                                .ThrowIfFailure();
+                            controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref(), "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
+                            nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
 
                             TitleUpdates.Add(new TitleUpdateModel(controlData, path));
                         }
@@ -190,9 +181,17 @@ namespace Ryujinx.Ava.Ui.Windows
 
         public async void Add()
         {
-            OpenFileDialog dialog = new OpenFileDialog() { Title = LocaleManager.Instance["SelectUpdateDialogTitle"], AllowMultiple = true };
+            OpenFileDialog dialog = new OpenFileDialog()
+            {
+                Title         = LocaleManager.Instance["SelectUpdateDialogTitle"],
+                AllowMultiple = true
+            };
 
-            dialog.Filters.Add(new FileDialogFilter { Name = "NSP", Extensions = { "nsp" } });
+            dialog.Filters.Add(new FileDialogFilter
+            {
+                Name       = "NSP", 
+                Extensions = { "nsp" }
+            });
 
             string[] files = await dialog.ShowAsync(this);
 
@@ -222,12 +221,10 @@ namespace Ryujinx.Ava.Ui.Windows
                     return 1;
                 }
 
-                return Version.Parse(first.Control.DisplayVersionString.ToString())
-                    .CompareTo(Version.Parse(second.Control.DisplayVersionString.ToString())) * -1;
+                return Version.Parse(first.Control.DisplayVersionString.ToString()).CompareTo(Version.Parse(second.Control.DisplayVersionString.ToString())) * -1;
             });
 
             TitleUpdates.Clear();
-
             TitleUpdates.AddRange(list);
         }
 
@@ -247,9 +244,9 @@ namespace Ryujinx.Ava.Ui.Windows
                 }
             }
 
-            using (FileStream dlcJsonStream = File.Create(_updateJsonPath, 4096, FileOptions.WriteThrough))
+            using (FileStream titleUpdateJsonStream = File.Create(_titleUpdateJsonPath, 4096, FileOptions.WriteThrough))
             {
-                dlcJsonStream.Write(Encoding.UTF8.GetBytes(JsonHelper.Serialize(_titleUpdateWindowData, true)));
+                titleUpdateJsonStream.Write(Encoding.UTF8.GetBytes(JsonHelper.Serialize(_titleUpdateWindowData, true)));
             }
 
             if (Owner is MainWindow window)
diff --git a/Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml.cs
index ff94747754..51c7bff0f1 100644
--- a/Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml.cs
+++ b/Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml.cs
@@ -1,6 +1,5 @@
 using Avalonia;
 using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
 using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Modules;
 using System;
@@ -23,9 +22,7 @@ namespace Ryujinx.Ava.Ui.Windows
             DataContext = this;
 
             InitializeComponent();
-#if DEBUG
-            this.AttachDevTools();
-#endif
+
             Title = LocaleManager.Instance["RyujinxUpdater"];
         }
 
diff --git a/Ryujinx.Common/Configuration/DlcContainer.cs b/Ryujinx.Common/Configuration/DlcContainer.cs
deleted file mode 100644
index c056ac1e81..0000000000
--- a/Ryujinx.Common/Configuration/DlcContainer.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Collections.Generic;
-
-namespace Ryujinx.Common.Configuration
-{
-    public struct DlcContainer
-    {
-        public string Path { get; set; }
-        public List<DlcNca> DlcNcaList { get; set; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/DlcNca.cs b/Ryujinx.Common/Configuration/DlcNca.cs
deleted file mode 100644
index df6a453252..0000000000
--- a/Ryujinx.Common/Configuration/DlcNca.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Common.Configuration
-{
-    public struct DlcNca
-    {
-        public string Path    { get; set; }
-        public ulong  TitleId { get; set; }
-        public bool   Enabled { get; set; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/DownloadableContentContainer.cs b/Ryujinx.Common/Configuration/DownloadableContentContainer.cs
new file mode 100644
index 0000000000..b6ae2f3fb9
--- /dev/null
+++ b/Ryujinx.Common/Configuration/DownloadableContentContainer.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace Ryujinx.Common.Configuration
+{
+    public struct DownloadableContentContainer
+    {
+        [JsonPropertyName("path")]
+        public string ContainerPath { get; set; }
+        [JsonPropertyName("dlc_nca_list")]
+        public List<DownloadableContentNca> DownloadableContentNcaList { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/DownloadableContentNca.cs b/Ryujinx.Common/Configuration/DownloadableContentNca.cs
new file mode 100644
index 0000000000..80b67300e4
--- /dev/null
+++ b/Ryujinx.Common/Configuration/DownloadableContentNca.cs
@@ -0,0 +1,14 @@
+using System.Text.Json.Serialization;
+
+namespace Ryujinx.Common.Configuration
+{
+    public struct DownloadableContentNca
+    {
+        [JsonPropertyName("path")]
+        public string FullPath { get; set; }
+        [JsonPropertyName("title_id")]
+        public ulong  TitleId  { get; set; }
+        [JsonPropertyName("is_enabled")]
+        public bool   Enabled  { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/ApplicationLoader.cs b/Ryujinx.HLE/HOS/ApplicationLoader.cs
index 893a0c97df..ea05d2bbed 100644
--- a/Ryujinx.HLE/HOS/ApplicationLoader.cs
+++ b/Ryujinx.HLE/HOS/ApplicationLoader.cs
@@ -422,19 +422,19 @@ namespace Ryujinx.HLE.HOS
 
             if (File.Exists(titleAocMetadataPath))
             {
-                List<DlcContainer> dlcContainerList = JsonHelper.DeserializeFromFile<List<DlcContainer>>(titleAocMetadataPath);
+                List<DownloadableContentContainer> dlcContainerList = JsonHelper.DeserializeFromFile<List<DownloadableContentContainer>>(titleAocMetadataPath);
 
-                foreach (DlcContainer dlcContainer in dlcContainerList)
+                foreach (DownloadableContentContainer downloadableContentContainer in dlcContainerList)
                 {
-                    foreach (DlcNca dlcNca in dlcContainer.DlcNcaList)
+                    foreach (DownloadableContentNca downloadableContentNca in downloadableContentContainer.DownloadableContentNcaList)
                     {
-                        if (File.Exists(dlcContainer.Path))
+                        if (File.Exists(downloadableContentContainer.ContainerPath))
                         {
-                            _device.Configuration.ContentManager.AddAocItem(dlcNca.TitleId, dlcContainer.Path, dlcNca.Path, dlcNca.Enabled);
+                            _device.Configuration.ContentManager.AddAocItem(downloadableContentNca.TitleId, downloadableContentContainer.ContainerPath, downloadableContentNca.FullPath, downloadableContentNca.Enabled);
                         }
                         else
                         {
-                            Logger.Warning?.Print(LogClass.Application, $"Cannot find AddOnContent file {dlcContainer.Path}. It may have been moved or renamed.");
+                            Logger.Warning?.Print(LogClass.Application, $"Cannot find AddOnContent file {downloadableContentContainer.ContainerPath}. It may have been moved or renamed.");
                         }
                     }
                 }
diff --git a/Ryujinx/Ui/Windows/DlcWindow.cs b/Ryujinx/Ui/Windows/DlcWindow.cs
index 76be60ef0d..1a47ae4148 100644
--- a/Ryujinx/Ui/Windows/DlcWindow.cs
+++ b/Ryujinx/Ui/Windows/DlcWindow.cs
@@ -21,10 +21,10 @@ namespace Ryujinx.Ui.Windows
 {
     public class DlcWindow : Window
     {
-        private readonly VirtualFileSystem  _virtualFileSystem;
-        private readonly string             _titleId;
-        private readonly string             _dlcJsonPath;
-        private readonly List<DlcContainer> _dlcContainerList;
+        private readonly VirtualFileSystem                  _virtualFileSystem;
+        private readonly string                             _titleId;
+        private readonly string                             _dlcJsonPath;
+        private readonly List<DownloadableContentContainer> _dlcContainerList;
 
 #pragma warning disable CS0649, IDE0044
         [GUI] Label         _baseTitleInfoLabel;
@@ -45,11 +45,11 @@ namespace Ryujinx.Ui.Windows
 
             try
             {
-                _dlcContainerList = JsonHelper.DeserializeFromFile<List<DlcContainer>>(_dlcJsonPath);
+                _dlcContainerList = JsonHelper.DeserializeFromFile<List<DownloadableContentContainer>>(_dlcJsonPath);
             }
             catch
             {
-                _dlcContainerList = new List<DlcContainer>();
+                _dlcContainerList = new List<DownloadableContentContainer>();
             }
             
             _dlcTreeView.Model = new TreeStore(typeof(bool), typeof(string), typeof(string));
@@ -75,37 +75,37 @@ namespace Ryujinx.Ui.Windows
             _dlcTreeView.AppendColumn("TitleId", new CellRendererText(), "text",   1);
             _dlcTreeView.AppendColumn("Path",    new CellRendererText(), "text",   2);
 
-            foreach (DlcContainer dlcContainer in _dlcContainerList)
+            foreach (DownloadableContentContainer dlcContainer in _dlcContainerList)
             {
-                if (File.Exists(dlcContainer.Path))
+                if (File.Exists(dlcContainer.ContainerPath))
                 {
                     // The parent tree item has its own "enabled" check box, but it's the actual
                     // nca entries that store the enabled / disabled state. A bit of a UI inconsistency.
                     // Maybe a tri-state check box would be better, but for now we check the parent
                     // "enabled" box if all child NCAs are enabled. Usually fine since each nsp has only one nca.
-                    bool areAllContentPacksEnabled = dlcContainer.DlcNcaList.TrueForAll((nca) => nca.Enabled);
-                    TreeIter parentIter = ((TreeStore)_dlcTreeView.Model).AppendValues(areAllContentPacksEnabled, "", dlcContainer.Path);
-                    using FileStream containerFile = File.OpenRead(dlcContainer.Path);
+                    bool areAllContentPacksEnabled = dlcContainer.DownloadableContentNcaList.TrueForAll((nca) => nca.Enabled);
+                    TreeIter parentIter = ((TreeStore)_dlcTreeView.Model).AppendValues(areAllContentPacksEnabled, "", dlcContainer.ContainerPath);
+                    using FileStream containerFile = File.OpenRead(dlcContainer.ContainerPath);
                     PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage());
                     _virtualFileSystem.ImportTickets(pfs);
 
-                    foreach (DlcNca dlcNca in dlcContainer.DlcNcaList)
+                    foreach (DownloadableContentNca dlcNca in dlcContainer.DownloadableContentNcaList)
                     {
                         using var ncaFile = new UniqueRef<IFile>();
 
-                        pfs.OpenFile(ref ncaFile.Ref(), dlcNca.Path.ToU8Span(), OpenMode.Read).ThrowIfFailure();
-                        Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), dlcContainer.Path);
+                        pfs.OpenFile(ref ncaFile.Ref(), dlcNca.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
+                        Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), dlcContainer.ContainerPath);
 
                         if (nca != null)
                         {
-                            ((TreeStore)_dlcTreeView.Model).AppendValues(parentIter, dlcNca.Enabled, nca.Header.TitleId.ToString("X16"), dlcNca.Path);
+                            ((TreeStore)_dlcTreeView.Model).AppendValues(parentIter, dlcNca.Enabled, nca.Header.TitleId.ToString("X16"), dlcNca.FullPath);
                         }
                     }
                 }
                 else
                 {
                     // DLC file moved or renamed. Allow the user to remove it without crashing the whole dialog.
-                    TreeIter parentIter = ((TreeStore)_dlcTreeView.Model).AppendValues(false, "", $"(MISSING) {dlcContainer.Path}");
+                    TreeIter parentIter = ((TreeStore)_dlcTreeView.Model).AppendValues(false, "", $"(MISSING) {dlcContainer.ContainerPath}");
                 }
             }
         }
@@ -237,19 +237,19 @@ namespace Ryujinx.Ui.Windows
                 {
                     if (_dlcTreeView.Model.IterChildren(out TreeIter childIter, parentIter))
                     {
-                        DlcContainer dlcContainer = new DlcContainer
+                        DownloadableContentContainer dlcContainer = new DownloadableContentContainer
                         {
-                            Path       = (string)_dlcTreeView.Model.GetValue(parentIter, 2),
-                            DlcNcaList = new List<DlcNca>()
+                            ContainerPath              = (string)_dlcTreeView.Model.GetValue(parentIter, 2),
+                            DownloadableContentNcaList = new List<DownloadableContentNca>()
                         };
 
                         do
                         {
-                            dlcContainer.DlcNcaList.Add(new DlcNca
+                            dlcContainer.DownloadableContentNcaList.Add(new DownloadableContentNca
                             {
-                                Enabled = (bool)_dlcTreeView.Model.GetValue(childIter, 0),
-                                TitleId = Convert.ToUInt64(_dlcTreeView.Model.GetValue(childIter, 1).ToString(), 16),
-                                Path    = (string)_dlcTreeView.Model.GetValue(childIter, 2)
+                                Enabled  = (bool)_dlcTreeView.Model.GetValue(childIter, 0),
+                                TitleId  = Convert.ToUInt64(_dlcTreeView.Model.GetValue(childIter, 1).ToString(), 16),
+                                FullPath = (string)_dlcTreeView.Model.GetValue(childIter, 2)
                             });
                         }
                         while (_dlcTreeView.Model.IterNext(ref childIter));