From 23b9a47d0899c6a7ef70392556480390b3da66f1 Mon Sep 17 00:00:00 2001 From: Babib3l Date: Mon, 30 Mar 2026 22:04:23 +0200 Subject: [PATCH] Refresh input modified state only when keybinds actually change --- .../Input/ControllerInputViewModel.cs | 6 +- .../UI/ViewModels/Input/InputViewModel.cs | 101 +++++++++++------- .../Views/Input/ControllerInputView.axaml.cs | 5 +- .../UI/Views/Input/KeyboardInputView.axaml.cs | 5 +- 4 files changed, 70 insertions(+), 47 deletions(-) diff --git a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs index 2949b69a8..2df530cb7 100644 --- a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs @@ -88,19 +88,19 @@ namespace Ryujinx.Ava.UI.ViewModels.Input public async void ShowMotionConfig() { await MotionInputView.Show(this); - ParentModel.IsModified = true; + ParentModel.RefreshModifiedState(); } public async void ShowRumbleConfig() { await RumbleInputView.Show(this); - ParentModel.IsModified = true; + ParentModel.RefreshModifiedState(); } public async void ShowLedConfig() { await LedInputView.Show(this); - ParentModel.IsModified = true; + ParentModel.RefreshModifiedState(); } public void OnParentModelChanged() diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs index 5bab2c49f..827ec128c 100644 --- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs @@ -181,8 +181,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input return; } - MarkAsChanged(); ApplyControllerSelection(controllerIndex); + RefreshModifiedState(); } } @@ -265,7 +265,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input return; } - MarkAsChanged(); _device = value; DeviceType selected = Devices[_device].Type; @@ -282,6 +281,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input } } + RefreshModifiedState(); FindPairedDeviceInConfigFile(); OnPropertyChanged(); OnPropertyChanged(nameof(SelectedDeviceItem)); @@ -298,8 +298,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input return; } - MarkAsChanged(); LoadSelectedDeviceDefaults(); + RefreshModifiedState(); FindPairedDeviceInConfigFile(); NotifyChanges(); } @@ -393,20 +393,19 @@ namespace Ryujinx.Ava.UI.ViewModels.Input - private void LoadConfiguration(InputConfig inputConfig = null) + private InputConfig GetPersistedInputConfig() { - InputConfig persistedConfig; - if (UseGlobalConfig && Program.UseExtraConfig) { - persistedConfig = ConfigurationState.InstanceExtra.Hid.InputConfig.Value.FirstOrDefault(inputConfig => inputConfig.PlayerIndex == _playerId); - } - else - { - persistedConfig = ConfigurationState.Instance.Hid.InputConfig.Value.FirstOrDefault(inputConfig => inputConfig.PlayerIndex == _playerId); + return ConfigurationState.InstanceExtra.Hid.InputConfig.Value.FirstOrDefault(inputConfig => inputConfig.PlayerIndex == _playerId); } - Config = inputConfig ?? GetDisplayedInputConfig(persistedConfig); + return ConfigurationState.Instance.Hid.InputConfig.Value.FirstOrDefault(inputConfig => inputConfig.PlayerIndex == _playerId); + } + + private void LoadConfiguration(InputConfig inputConfig = null) + { + Config = inputConfig ?? GetDisplayedInputConfig(GetPersistedInputConfig()); if (Config is StandardKeyboardInputConfig keyboardInputConfig) { @@ -451,15 +450,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input } } - private void MarkAsChanged() - { - //If tracking is active, then allow changing the modifier - if (!IsModified && _isChangeTrackingActive) - { - IsModified = true; - } - } - public void UnlinkDevice() { // "Disabled" mode is available after unbinding the device @@ -534,6 +524,55 @@ namespace Ryujinx.Ava.UI.ViewModels.Input LoadConfiguration(LoadDefaultConfiguration()); } + public void RefreshModifiedState() + { + if (!_isChangeTrackingActive) + { + return; + } + + IsModified = !ConfigsMatch(GetSelectedDeviceConfig(), GetDisplayedInputConfig(GetPersistedInputConfig())); + } + + private static bool ConfigsMatch(InputConfig currentConfig, InputConfig otherConfig) + { + if (currentConfig == null || otherConfig == null) + { + return currentConfig == otherConfig; + } + + return JsonHelper.Serialize(currentConfig, _serializerContext.InputConfig) == + JsonHelper.Serialize(otherConfig, _serializerContext.InputConfig); + } + + private InputConfig GetSelectedDeviceConfig() + { + if (_device <= 0 || _device >= Devices.Count) + { + return null; + } + + (DeviceType Type, string Id, string Name) device = Devices[_device]; + InputConfig config = device.Type switch + { + DeviceType.Keyboard => (ConfigViewModel as KeyboardInputViewModel)?.Config.GetConfig(), + DeviceType.Controller => (ConfigViewModel as ControllerInputViewModel)?.Config.GetConfig(), + _ => null, + }; + + if (config == null) + { + return null; + } + + config.Id = device.Type == DeviceType.Keyboard ? device.Id : device.Id.Split(" ")[0]; + config.Name = device.Name; + config.PlayerIndex = _playerId; + config.ControllerType = Controllers[_controller].Type; + + return config; + } + private void LoadInputDriver() { if (_device < 0) @@ -1160,25 +1199,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input } else { - (DeviceType Type, string Id, string Name) device = Devices[Device]; - - if (device.Type == DeviceType.Keyboard) - { - KeyboardInputConfig inputConfig = (ConfigViewModel as KeyboardInputViewModel).Config; - inputConfig.Id = device.Id; - } - else - { - GamepadInputConfig inputConfig = (ConfigViewModel as ControllerInputViewModel).Config; - inputConfig.Id = device.Id.Split(" ")[0]; - } - - InputConfig config = !IsController - ? (ConfigViewModel as KeyboardInputViewModel).Config.GetConfig() - : (ConfigViewModel as ControllerInputViewModel).Config.GetConfig(); - config.ControllerType = Controllers[_controller].Type; - config.PlayerIndex = _playerId; - config.Name = device.Name; + InputConfig config = GetSelectedDeviceConfig(); int i = newConfig.FindIndex(x => x.PlayerIndex == PlayerId); if (i == -1) diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs index 02e6e99c9..7bf755116 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs @@ -116,7 +116,6 @@ namespace Ryujinx.Ava.UI.Views.Input if (e.ButtonValue.HasValue) { Button buttonValue = e.ButtonValue.Value; - FlagInputConfigChanged(); switch (button.Name) { @@ -187,6 +186,8 @@ namespace Ryujinx.Ava.UI.Views.Input viewModel.Config.RightJoystick = buttonValue.AsHidType(); break; } + + FlagInputConfigChanged(); } }; @@ -212,7 +213,7 @@ namespace Ryujinx.Ava.UI.Views.Input private void FlagInputConfigChanged() { - (DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true; + (DataContext as ControllerInputViewModel)!.ParentModel.RefreshModifiedState(); } private void MouseClick(object sender, PointerPressedEventArgs e) diff --git a/src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml.cs index e7b0daf80..1ff38424b 100644 --- a/src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml.cs @@ -73,7 +73,6 @@ namespace Ryujinx.Ava.UI.Views.Input if (be.ButtonValue.HasValue) { Button buttonValue = be.ButtonValue.Value; - ViewModel.ParentModel.IsModified = true; switch (button.Name) { @@ -162,6 +161,8 @@ namespace Ryujinx.Ava.UI.Views.Input ViewModel.Config.RightStickLeft = buttonValue.AsHidType(); break; } + + ViewModel.ParentModel.RefreshModifiedState(); } }; @@ -240,7 +241,7 @@ namespace Ryujinx.Ava.UI.Views.Input if (buttonActions.TryGetValue(_currentAssigner.ToggledButton.Name, out Action action)) { action(); - ViewModel.ParentModel.IsModified = true; + ViewModel.ParentModel.RefreshModifiedState(); } } }