diff --git a/docs/compatibility.csv b/docs/compatibility.csv
index 4cf9102bd..660c7a9b0 100644
--- a/docs/compatibility.csv
+++ b/docs/compatibility.csv
@@ -2063,7 +2063,7 @@
010002700C34C000,"Numbala",,playable,2020-05-11 12:01:07
010020500C8C8000,"Number Place 10000",gpu,menus,2021-11-24 09:14:23
010003701002C000,"Nurse Love Syndrome",,playable,2022-10-13 10:05:22
-0000000000000000,"nx-hbmenu",Needs Update;homebrew,boots,2024-04-06 22:05:32
+,"nx-hbmenu",Needs Update;homebrew,boots,2024-04-06 22:05:32
,"nxquake2",services;crash;homebrew,nothing,2022-08-04 23:14:04
010049F00EC30000,"Nyan Cat: Lost in Space",online,playable,2021-06-12 13:22:03
01002E6014FC4000,"O---O",,playable,2022-10-29 12:12:14
@@ -2471,7 +2471,7 @@
0100AFE00DDAC000,"Royal Roads",,playable,2020-11-17 12:54:38
0100E2C00B414000,"RPG Maker MV",nvdec,playable,2021-01-05 20:12:01
01005CD015986000,"rRootage Reloaded",,playable,2022-08-05 23:20:18
-0000000000000000,"RSDKv5u",homebrew,ingame,2024-04-01 16:25:34
+,"RSDKv5u",homebrew,ingame,2024-04-01 16:25:34
010009B00D33C000,"Rugby Challenge 4",slow;online-broken;UE4,playable,2022-10-06 12:45:53
01006EC00F2CC000,"RUINER",UE4,playable,2022-10-03 14:11:33
010074F00DE4A000,"Run the Fan",,playable,2021-02-27 13:36:28
@@ -2674,10 +2674,10 @@
01004F401BEBE000,"Song of Nunu: A League of Legends Story",,ingame,2024-07-12 18:53:44
0100E5400BF94000,"Songbird Symphony",,playable,2021-02-27 02:44:04
010031D00A604000,"Songbringer",,playable,2020-06-22 10:42:02
-0000000000000000,"Sonic 1 (2013)",crash;homebrew,ingame,2024-04-06 18:31:20
-0000000000000000,"Sonic 2 (2013)",crash;homebrew,ingame,2024-04-01 16:25:30
-0000000000000000,"Sonic A.I.R",homebrew,ingame,2024-04-01 16:25:32
-0000000000000000,"Sonic CD",crash;homebrew,ingame,2024-04-01 16:25:31
+,"Sonic 1 (2013)",crash;homebrew,ingame,2024-04-06 18:31:20
+,"Sonic 2 (2013)",crash;homebrew,ingame,2024-04-01 16:25:30
+,"Sonic A.I.R",homebrew,ingame,2024-04-01 16:25:32
+,"Sonic CD",crash;homebrew,ingame,2024-04-01 16:25:31
010040E0116B8000,"Sonic Colors: Ultimate",,playable,2022-11-12 21:24:26
01001270012B6000,"SONIC FORCES™",,playable,2024-07-28 13:11:21
01004AD014BF0000,"Sonic Frontiers",gpu;deadlock;amd-vendor-bug;intel-vendor-bug,ingame,2024-09-05 09:18:53
@@ -2694,7 +2694,7 @@
0100707011722000,"Space Elite Force",,playable,2020-11-27 15:21:05
010047B010260000,"Space Pioneer",,playable,2022-10-20 12:24:37
010010A009830000,"Space Ribbon",,playable,2022-08-15 17:17:10
-0000000000000000,"SpaceCadetPinball",homebrew,ingame,2024-04-18 19:30:04
+,"SpaceCadetPinball",homebrew,ingame,2024-04-18 19:30:04
0100D9B0041CE000,"Spacecats with Lasers",,playable,2022-08-15 17:22:44
010034800FB60000,"Spaceland",,playable,2020-11-01 14:31:56
010028D0045CE000,"Sparkle 2",,playable,2020-10-19 11:51:39
@@ -2839,7 +2839,7 @@
0100000000010000,"Super Mario Odyssey™",nvdec;intel-vendor-bug;mac-bug,playable,2024-08-25 01:32:34
010036B0034E4000,"Super Mario Party™",gpu;Needs Update;ldn-works,ingame,2024-06-21 05:10:16
0100BC0018138000,"Super Mario RPG™",gpu;audio;nvdec,ingame,2024-06-19 17:43:42
-0000000000000000,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
+,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
010049900F546000,"Super Mario™ 3D All-Stars",services-horizon;slow;vulkan;amd-vendor-bug,ingame,2024-05-07 02:38:16
010028600EBDA000,"Super Mario™ 3D World + Bowser’s Fury",ldn-works,playable,2024-07-31 10:45:37
01004F8006A78000,"Super Meat Boy",services,playable,2020-04-02 23:10:07
diff --git a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
index 2faff6e61..47bfadc4c 100644
--- a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
@@ -158,13 +158,15 @@ namespace Ryujinx.HLE.HOS.Applets.Error
string[] buttons = GetButtonsText(module, description, "DlgBtn");
- bool showDetails = _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Code: {module}-{description:0000}", "\n" + message, buttons);
+ (uint Module, uint Description) errorCodeTuple = (module, uint.Parse(description.ToString("0000")));
+
+ bool showDetails = _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Code: {module}-{description:0000}", "\n" + message, buttons, errorCodeTuple);
if (showDetails)
{
message = GetMessageText(module, description, "FlvMsg");
buttons = GetButtonsText(module, description, "FlvBtn");
- _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Details: {module}-{description:0000}", "\n" + message, buttons);
+ _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Details: {module}-{description:0000}", "\n" + message, buttons, errorCodeTuple);
}
}
diff --git a/src/Ryujinx.HLE/UI/IHostUIHandler.cs b/src/Ryujinx.HLE/UI/IHostUIHandler.cs
index 8ccb5cf89..3748eef39 100644
--- a/src/Ryujinx.HLE/UI/IHostUIHandler.cs
+++ b/src/Ryujinx.HLE/UI/IHostUIHandler.cs
@@ -45,10 +45,12 @@ namespace Ryujinx.HLE.UI
/// The value associated to the .
void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value);
+ ///
/// Displays a Message Dialog box specific to Error Applet and blocks until it is closed.
///
/// False when OK is pressed, True when another button (Details) is pressed.
- bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText);
+ // ReSharper disable once UnusedParameter.Global
+ bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText, (uint Module, uint Description)? errorCode = null);
///
/// Creates a handler to process keyboard inputs into text strings.
diff --git a/src/Ryujinx.Input/HLE/NpadManager.cs b/src/Ryujinx.Input/HLE/NpadManager.cs
index 4a54b7ead..21219d91b 100644
--- a/src/Ryujinx.Input/HLE/NpadManager.cs
+++ b/src/Ryujinx.Input/HLE/NpadManager.cs
@@ -185,6 +185,15 @@ namespace Ryujinx.Input.HLE
}
}
+ public bool InputUpdatesBlocked
+ {
+ get
+ {
+ lock (_lock)
+ return _blockInputUpdates;
+ }
+ }
+
public void BlockInputUpdates()
{
lock (_lock)
diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs
index 25f451858..f143d4e03 100644
--- a/src/Ryujinx/AppHost.cs
+++ b/src/Ryujinx/AppHost.cs
@@ -1041,6 +1041,7 @@ namespace Ryujinx.Ava
if (_viewModel.StartGamesInFullscreen)
{
_viewModel.WindowState = WindowState.FullScreen;
+ _viewModel.Window.TitleBar.ExtendsContentIntoTitleBar = true;
}
if (_viewModel.WindowState is WindowState.FullScreen || _viewModel.StartGamesWithoutUI)
diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json
index d09b4a9a0..c8299ccbd 100644
--- a/src/Ryujinx/Assets/locales.json
+++ b/src/Ryujinx/Assets/locales.json
@@ -3497,6 +3497,31 @@
"zh_TW": "記住視窗大小/位置"
}
},
+ {
+ "ID": "SettingsTabGeneralDisableInputWhenOutOfFocus",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "Disable Input when Out of Focus",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "Deaktiver inndata når vinduet er ute av fokus",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
{
"ID": "SettingsTabGeneralShowTitleBar",
"Translations": {
diff --git a/src/Ryujinx/Headless/Windows/WindowBase.cs b/src/Ryujinx/Headless/Windows/WindowBase.cs
index c9d672af4..081998a00 100644
--- a/src/Ryujinx/Headless/Windows/WindowBase.cs
+++ b/src/Ryujinx/Headless/Windows/WindowBase.cs
@@ -513,7 +513,7 @@ namespace Ryujinx.Headless
Exit();
}
- public bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText)
+ public bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText, (uint Module, uint Description)? errorCode = null)
{
SDL_MessageBoxData data = new()
{
@@ -521,7 +521,7 @@ namespace Ryujinx.Headless
message = message,
buttons = new SDL_MessageBoxButtonData[buttonsText.Length],
numbuttons = buttonsText.Length,
- window = WindowHandle,
+ window = WindowHandle
};
for (int i = 0; i < buttonsText.Length; i++)
diff --git a/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs
index c75e532ec..c03c4c45f 100644
--- a/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs
+++ b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs
@@ -75,31 +75,32 @@ namespace Ryujinx.Ava.UI.Applet
bool opened = false;
UserResult response = await ContentDialogHelper.ShowDeferredContentDialog(_parent,
- title,
- message,
- string.Empty,
- LocaleManager.Instance[LocaleKeys.DialogOpenSettingsWindowLabel],
- string.Empty,
- LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
- (int)Symbol.Important,
- deferEvent,
- async window =>
- {
- if (opened)
- {
- return;
- }
+ title,
+ message,
+ string.Empty,
+ LocaleManager.Instance[LocaleKeys.DialogOpenSettingsWindowLabel],
+ string.Empty,
+ LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
+ (int)Symbol.Important,
+ deferEvent,
+ async window =>
+ {
+ if (opened)
+ {
+ return;
+ }
- opened = true;
+ opened = true;
- _parent.SettingsWindow = new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
+ _parent.SettingsWindow =
+ new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
- await _parent.SettingsWindow.ShowDialog(window);
+ await _parent.SettingsWindow.ShowDialog(window);
- _parent.SettingsWindow = null;
+ _parent.SettingsWindow = null;
- opened = false;
- });
+ opened = false;
+ });
if (response == UserResult.Ok)
{
@@ -110,7 +111,9 @@ namespace Ryujinx.Ava.UI.Applet
}
catch (Exception ex)
{
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogMessageDialogErrorExceptionMessage, ex));
+ await ContentDialogHelper.CreateErrorDialog(
+ LocaleManager.Instance.UpdateAndGetDynamicValue(
+ LocaleKeys.DialogMessageDialogErrorExceptionMessage, ex));
dialogCloseEvent.Set();
}
@@ -134,7 +137,9 @@ namespace Ryujinx.Ava.UI.Applet
try
{
_parent.ViewModel.AppHost.NpadManager.BlockInputUpdates();
- (UserResult result, string userInput) = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard], args);
+ (UserResult result, string userInput) =
+ await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard],
+ args);
if (result == UserResult.Ok)
{
@@ -146,7 +151,9 @@ namespace Ryujinx.Ava.UI.Applet
{
error = true;
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogSoftwareKeyboardErrorExceptionMessage, ex));
+ await ContentDialogHelper.CreateErrorDialog(
+ LocaleManager.Instance.UpdateAndGetDynamicValue(
+ LocaleKeys.DialogSoftwareKeyboardErrorExceptionMessage, ex));
}
finally
{
@@ -177,7 +184,8 @@ namespace Ryujinx.Ava.UI.Applet
args.InitialText = "Ryujinx";
args.StringLengthMin = 1;
args.StringLengthMax = 25;
- (UserResult result, string userInput) = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.CabinetDialog], args);
+ (UserResult result, string userInput) =
+ await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.CabinetDialog], args);
if (result == UserResult.Ok)
{
inputText = userInput;
@@ -201,11 +209,13 @@ namespace Ryujinx.Ava.UI.Applet
Dispatcher.UIThread.InvokeAsync(async () =>
{
dialogCloseEvent.Set();
- await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.CabinetScanDialog],
- string.Empty,
- LocaleManager.Instance[LocaleKeys.InputDialogOk],
- string.Empty,
- LocaleManager.Instance[LocaleKeys.CabinetTitle]);
+ await ContentDialogHelper.CreateInfoDialog(
+ LocaleManager.Instance[LocaleKeys.CabinetScanDialog],
+ string.Empty,
+ LocaleManager.Instance[LocaleKeys.InputDialogOk],
+ string.Empty,
+ LocaleManager.Instance[LocaleKeys.CabinetTitle]
+ );
});
dialogCloseEvent.WaitOne();
}
@@ -217,7 +227,8 @@ namespace Ryujinx.Ava.UI.Applet
_parent.ViewModel.AppHost?.Stop();
}
- public bool DisplayErrorAppletDialog(string title, string message, string[] buttons)
+ public bool DisplayErrorAppletDialog(string title, string message, string[] buttons,
+ (uint Module, uint Description)? errorCode = null)
{
ManualResetEvent dialogCloseEvent = new(false);
@@ -229,9 +240,7 @@ namespace Ryujinx.Ava.UI.Applet
{
ErrorAppletWindow msgDialog = new(_parent, buttons, message)
{
- Title = title,
- WindowStartupLocation = WindowStartupLocation.CenterScreen,
- Width = 400
+ Title = title, WindowStartupLocation = WindowStartupLocation.CenterScreen, Width = 400
};
object response = await msgDialog.Run();
@@ -249,7 +258,9 @@ namespace Ryujinx.Ava.UI.Applet
{
dialogCloseEvent.Set();
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogErrorAppletErrorExceptionMessage, ex));
+ await ContentDialogHelper.CreateErrorDialog(
+ LocaleManager.Instance.UpdateAndGetDynamicValue(
+ LocaleKeys.DialogErrorAppletErrorExceptionMessage, ex));
}
});
@@ -259,38 +270,36 @@ namespace Ryujinx.Ava.UI.Applet
}
public IDynamicTextInputHandler CreateDynamicTextInputHandler() => new AvaloniaDynamicTextInputHandler(_parent);
-
+
public UserProfile ShowPlayerSelectDialog()
{
UserId selected = UserId.Null;
byte[] defaultGuestImage = EmbeddedResources.Read("Ryujinx.HLE/HOS/Services/Account/Acc/GuestUserImage.jpg");
UserProfile guest = new(new UserId("00000000000000000000000000000080"), "Guest", defaultGuestImage);
-
+
ManualResetEvent dialogCloseEvent = new(false);
-
+
Dispatcher.UIThread.InvokeAsync(async () =>
{
ObservableCollection profiles = [];
NavigationDialogHost nav = new();
-
+
_parent.AccountManager.GetAllUsers()
.OrderBy(x => x.Name)
.ForEach(profile => profiles.Add(new Models.UserProfile(profile, nav)));
-
+
profiles.Add(new Models.UserProfile(guest, nav));
- UserSelectorDialogViewModel viewModel = new()
+ ProfileSelectorDialogViewModel viewModel = new()
{
- Profiles = profiles,
- SelectedUserId = _parent.AccountManager.LastOpenedUser.UserId
+ Profiles = profiles, SelectedUserId = _parent.AccountManager.LastOpenedUser.UserId
};
- UserSelectorDialog content = new(viewModel);
- (selected, _) = await UserSelectorDialog.ShowInputDialog(content);
-
+ (selected, _) = await ProfileSelectorDialog.ShowInputDialog(viewModel);
+
dialogCloseEvent.Set();
});
-
+
dialogCloseEvent.WaitOne();
-
+
UserProfile profile = _parent.AccountManager.LastOpenedUser;
if (selected == guest.UserId)
{
@@ -311,6 +320,7 @@ namespace Ryujinx.Ava.UI.Applet
}
}
}
+
return profile;
}
}
diff --git a/src/Ryujinx/UI/Applet/UserSelectorDialog.axaml b/src/Ryujinx/UI/Applet/ProfileSelectorDialog.axaml
similarity index 96%
rename from src/Ryujinx/UI/Applet/UserSelectorDialog.axaml
rename to src/Ryujinx/UI/Applet/ProfileSelectorDialog.axaml
index 2816afbce..d929cc501 100644
--- a/src/Ryujinx/UI/Applet/UserSelectorDialog.axaml
+++ b/src/Ryujinx/UI/Applet/ProfileSelectorDialog.axaml
@@ -1,5 +1,5 @@
+ x:DataType="viewModels:ProfileSelectorDialogViewModel">
-
+
diff --git a/src/Ryujinx/UI/Applet/UserSelectorDialog.axaml.cs b/src/Ryujinx/UI/Applet/ProfileSelectorDialog.axaml.cs
similarity index 85%
rename from src/Ryujinx/UI/Applet/UserSelectorDialog.axaml.cs
rename to src/Ryujinx/UI/Applet/ProfileSelectorDialog.axaml.cs
index 95081913e..b2c396b69 100644
--- a/src/Ryujinx/UI/Applet/UserSelectorDialog.axaml.cs
+++ b/src/Ryujinx/UI/Applet/ProfileSelectorDialog.axaml.cs
@@ -16,15 +16,15 @@ using UserProfileSft = Ryujinx.HLE.HOS.Services.Account.Acc.UserProfile;
namespace Ryujinx.Ava.UI.Applet
{
- public partial class UserSelectorDialog : UserControl, INotifyPropertyChanged
+ public partial class ProfileSelectorDialog : UserControl
{
- public UserSelectorDialogViewModel ViewModel { get; set; }
+ public ProfileSelectorDialogViewModel ViewModel { get; set; }
- public UserSelectorDialog(UserSelectorDialogViewModel viewModel)
+ public ProfileSelectorDialog(ProfileSelectorDialogViewModel viewModel)
{
+ DataContext = ViewModel = viewModel;
+
InitializeComponent();
- ViewModel = viewModel;
- DataContext = ViewModel;
}
private void Grid_PointerEntered(object sender, PointerEventArgs e)
@@ -54,7 +54,7 @@ namespace Ryujinx.Ava.UI.Applet
if (ViewModel.Profiles[selectedIndex] is UserProfile userProfile)
{
ViewModel.SelectedUserId = userProfile.UserId;
- Logger.Info?.Print(LogClass.UI, $"Selected user: {userProfile.UserId}");
+ Logger.Info?.Print(LogClass.UI, $"Selected: {userProfile.UserId}", "ProfileSelector");
ObservableCollection newProfiles = [];
@@ -79,7 +79,7 @@ namespace Ryujinx.Ava.UI.Applet
}
}
- public static async Task<(UserId Id, bool Result)> ShowInputDialog(UserSelectorDialog content)
+ public static async Task<(UserId Id, bool Result)> ShowInputDialog(ProfileSelectorDialogViewModel viewModel)
{
ContentDialog contentDialog = new()
{
@@ -87,22 +87,25 @@ namespace Ryujinx.Ava.UI.Applet
PrimaryButtonText = LocaleManager.Instance[LocaleKeys.Continue],
SecondaryButtonText = string.Empty,
CloseButtonText = LocaleManager.Instance[LocaleKeys.Cancel],
- Content = content,
+ Content = new ProfileSelectorDialog(viewModel),
Padding = new Thickness(0)
};
UserId result = UserId.Null;
bool input = false;
+
+ contentDialog.Closed += Handler;
+ await ContentDialogHelper.ShowAsync(contentDialog);
+
+ return (result, input);
+
void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs)
{
if (eventArgs.Result == ContentDialogResult.Primary)
{
- if (contentDialog.Content is UserSelectorDialog view)
- {
- result = view.ViewModel.SelectedUserId;
- input = true;
- }
+ result = viewModel.SelectedUserId;
+ input = true;
}
else
{
@@ -110,12 +113,6 @@ namespace Ryujinx.Ava.UI.Applet
input = false;
}
}
-
- contentDialog.Closed += Handler;
-
- await ContentDialogHelper.ShowAsync(contentDialog);
-
- return (result, input);
}
}
}
diff --git a/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs
index 10256babe..be0a5d644 100644
--- a/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs
@@ -2,6 +2,7 @@ using Avalonia.Media.Imaging;
using Avalonia.Styling;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
+using Gommon;
using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Utilities.Configuration;
@@ -32,15 +33,16 @@ namespace Ryujinx.Ava.UI.ViewModels
Dispatcher.UIThread.Post(() => UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value));
}
+ private const string LogoPathFormat = "resm:Ryujinx.Assets.UIImages.Logo_{0}_{1}.png?assembly=Ryujinx";
+
private void UpdateLogoTheme(string theme)
{
bool isDarkTheme = theme == "Dark" || (theme == "Auto" && RyujinxApp.DetectSystemTheme() == ThemeVariant.Dark);
+
+ string themeName = isDarkTheme ? "Dark" : "Light";
- string basePath = "resm:Ryujinx.Assets.UIImages.";
- string themeSuffix = isDarkTheme ? "Dark.png" : "Light.png";
-
- GithubLogo = LoadBitmap($"{basePath}Logo_GitHub_{themeSuffix}?assembly=Ryujinx");
- DiscordLogo = LoadBitmap($"{basePath}Logo_Discord_{themeSuffix}?assembly=Ryujinx");
+ GithubLogo = LoadBitmap(LogoPathFormat.Format("GitHub", themeName));
+ DiscordLogo = LoadBitmap(LogoPathFormat.Format("Discord", themeName));
}
private static Bitmap LoadBitmap(string uri) => new(Avalonia.Platform.AssetLoader.Open(new Uri(uri)));
@@ -48,6 +50,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public void Dispose()
{
ThemeManager.ThemeChanged -= ThemeManager_ThemeChanged;
+
+ GithubLogo.Dispose();
+ DiscordLogo.Dispose();
+
GC.SuppressFinalize(this);
}
}
diff --git a/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs
index e8869c475..e550c4ae0 100644
--- a/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs
@@ -264,7 +264,7 @@ namespace Ryujinx.Ava.UI.ViewModels
Logger.Error?.Print(LogClass.Application, $"Couldn't get valid amiibo data: {exception}");
// Neither local or remote files are valid JSON, close window.
- ShowInfoDialog();
+ await ShowInfoDialog();
Close();
}
else if (!remoteIsValid)
@@ -273,7 +273,7 @@ namespace Ryujinx.Ava.UI.ViewModels
// Only the local file is valid, the local one should be used
// but the user should be warned.
- ShowInfoDialog();
+ await ShowInfoDialog();
}
}
@@ -525,7 +525,7 @@ namespace Ryujinx.Ava.UI.ViewModels
AmiiboImage = bitmap;
}
- private static async void ShowInfoDialog()
+ private static async Task ShowInfoDialog()
{
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogAmiiboApiTitle],
LocaleManager.Instance[LocaleKeys.DialogAmiiboApiConnectErrorMessage],
diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
index 227347030..bbfe80570 100644
--- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
@@ -107,7 +107,7 @@ namespace Ryujinx.Ava.UI.ViewModels
[ObservableProperty] private ApplicationContextMenu _gridAppContextMenu;
[ObservableProperty] private bool _updateAvailable;
- public static AsyncRelayCommand UpdateCommand => Commands.Create(async () =>
+ public static AsyncRelayCommand UpdateCommand { get; } = Commands.Create(async () =>
{
if (Updater.CanUpdate(true))
await Updater.BeginUpdateAsync(true);
diff --git a/src/Ryujinx/UI/ViewModels/UserSelectorDialogViewModel.cs b/src/Ryujinx/UI/ViewModels/ProfileSelectorDialogViewModel.cs
similarity index 82%
rename from src/Ryujinx/UI/ViewModels/UserSelectorDialogViewModel.cs
rename to src/Ryujinx/UI/ViewModels/ProfileSelectorDialogViewModel.cs
index 094aed5cf..979e1616a 100644
--- a/src/Ryujinx/UI/ViewModels/UserSelectorDialogViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/ProfileSelectorDialogViewModel.cs
@@ -4,7 +4,7 @@ using System.Collections.ObjectModel;
namespace Ryujinx.Ava.UI.ViewModels
{
- public partial class UserSelectorDialogViewModel : BaseModel
+ public partial class ProfileSelectorDialogViewModel : BaseModel
{
[ObservableProperty] private UserId _selectedUserId;
diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
index b3df13e7f..017d68a28 100644
--- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
@@ -126,6 +126,8 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableDockedMode { get; set; }
public bool EnableKeyboard { get; set; }
public bool EnableMouse { get; set; }
+ public bool DisableInputWhenOutOfFocus { get; set; }
+
public VSyncMode VSyncMode
{
get => _vSyncMode;
@@ -498,6 +500,7 @@ namespace Ryujinx.Ava.UI.ViewModels
EnableDockedMode = config.System.EnableDockedMode;
EnableKeyboard = config.Hid.EnableKeyboard;
EnableMouse = config.Hid.EnableMouse;
+ DisableInputWhenOutOfFocus = config.Hid.DisableInputWhenOutOfFocus;
// Keyboard Hotkeys
KeyboardHotkey = new HotkeyConfig(config.Hid.Hotkeys.Value);
@@ -609,6 +612,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.System.EnableDockedMode.Value = EnableDockedMode;
config.Hid.EnableKeyboard.Value = EnableKeyboard;
config.Hid.EnableMouse.Value = EnableMouse;
+ config.Hid.DisableInputWhenOutOfFocus.Value = DisableInputWhenOutOfFocus;
// Keyboard Hotkeys
config.Hid.Hotkeys.Value = KeyboardHotkey.GetConfig();
diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
index a0bcd1aa2..d1931ae2f 100644
--- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
@@ -51,12 +51,8 @@ namespace Ryujinx.Ava.UI.Views.Main
XciTrimmerMenuItem.Command = Commands.Create(XCITrimmerWindow.Show);
AboutWindowMenuItem.Command = Commands.Create(AboutWindow.Show);
CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityList.Show());
-
- UpdateMenuItem.Command = Commands.Create(async () =>
- {
- if (Updater.CanUpdate(true))
- await Updater.BeginUpdateAsync(true);
- });
+
+ UpdateMenuItem.Command = MainWindowViewModel.UpdateCommand;
FaqMenuItem.Command =
SetupGuideMenuItem.Command =
diff --git a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml
index 98416654b..02cc1fc7b 100644
--- a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml
+++ b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml
@@ -290,10 +290,12 @@
-