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 @@ - @@ -142,42 +142,40 @@ + VerticalAlignment="Stretch" RowDefinitions="Auto,Auto,Auto"> +