diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs
index fbb545f8b..25e6e3fba 100644
--- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs
@@ -1188,6 +1188,16 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
}
}
+ private void ApplySelectedProfileSilently(string profileName)
+ {
+ SetSelectedProfileSilently(profileName);
+
+ if (TryLoadProfileConfiguration(profileName, out InputConfig profileConfig))
+ {
+ LoadConfiguration(profileConfig, false);
+ }
+ }
+
private void RefreshProfileBindingState()
{
OnPropertyChanged(nameof(CanBindSelectedProfile));
@@ -1346,7 +1356,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
}
LoadConfiguration(LoadDefaultConfiguration(), false);
- SetSelectedProfileSilently(GetCurrentProfileDefaultName());
RefreshProfileBindingState();
}
@@ -1428,12 +1437,22 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{
bool duplicateDeviceAssignmentChanged = _allowDuplicateDeviceAssignment.HasValue &&
_allowDuplicateDeviceAssignment.Value != GetSavedAllowDuplicateDeviceAssignment();
- bool configChanged = !ConfigsMatch(GetSelectedDeviceConfig(), GetDisplayedInputConfig(GetPersistedInputConfig()));
+ bool configChanged = !ConfigsMatch(GetSelectedDeviceConfig(), GetPersistedComparisonConfig());
bool playerAssignmentsChanged = !PlayerAssignmentsMatch(GetEditedPlayerInputAssignment(), GetPersistedPlayerInputAssignment());
return duplicateDeviceAssignmentChanged || configChanged || playerAssignmentsChanged;
}
+ private InputConfig GetPersistedComparisonConfig()
+ {
+ if (!IsDefaultProfileName(ProfileName) && TryLoadProfileConfiguration(ProfileName, out InputConfig profileConfig))
+ {
+ return profileConfig;
+ }
+
+ return GetDisplayedInputConfig(GetPersistedInputConfig());
+ }
+
private static bool ConfigsMatch(InputConfig currentConfig, InputConfig otherConfig)
{
if (currentConfig == null || otherConfig == null)
@@ -1857,7 +1876,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
selectedProfile = GetCurrentProfileDefaultName();
}
- SetSelectedProfileSilently(selectedProfile);
+ ApplySelectedProfileSilently(selectedProfile);
}
finally
{
@@ -2130,7 +2149,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
ReplaceBoundProfileName(ProfileName, null);
LoadProfiles();
- SetSelectedProfileSilently(ProfilesList[0].ToString());
+ ApplySelectedProfileSilently(ProfilesList[0].ToString());
RefreshModifiedState();
}
}
diff --git a/src/Ryujinx/UI/Views/Input/InputView.axaml b/src/Ryujinx/UI/Views/Input/InputView.axaml
index 7b0a46bee..5f4b42094 100644
--- a/src/Ryujinx/UI/Views/Input/InputView.axaml
+++ b/src/Ryujinx/UI/Views/Input/InputView.axaml
@@ -106,6 +106,8 @@
IsEnabled="{Binding ShowSettings}"
SelectedItem="{Binding ChosenProfile, Mode=TwoWay}"
SelectionChanged="ComboBox_SelectionChanged"
+ GotFocus="ProfileBox_OnGotFocus"
+ LostFocus="ProfileBox_OnLostFocus"
ItemsSource="{Binding ProfilesList}"
Text="{Binding ProfileName, Mode=TwoWay}">
@@ -124,11 +126,12 @@
diff --git a/src/Ryujinx/UI/Views/Input/InputView.axaml.cs b/src/Ryujinx/UI/Views/Input/InputView.axaml.cs
index 57bfa7e1c..d80ef2a10 100644
--- a/src/Ryujinx/UI/Views/Input/InputView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Input/InputView.axaml.cs
@@ -2,6 +2,7 @@ using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Interactivity;
using Avalonia;
+using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Media;
using FluentAvalonia.UI.Controls;
@@ -11,12 +12,15 @@ using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels.Input;
+using System.ComponentModel;
namespace Ryujinx.Ava.UI.Views.Input
{
public partial class InputView : RyujinxControl
{
private bool _dialogOpen;
+ private bool _isEditingProfileName;
+ private InputViewModel _subscribedViewModel;
public InputView()
{
@@ -43,11 +47,24 @@ namespace Ryujinx.Ava.UI.Views.Input
private void ReplaceViewModel(bool useGlobalConfig)
{
- ViewModel = new InputViewModel(this, useGlobalConfig); // Create new Input Page with the selected input config scope.
+ if (_subscribedViewModel != null)
+ {
+ _subscribedViewModel.PropertyChanged -= ViewModel_OnPropertyChanged;
+ _subscribedViewModel = null;
+ }
+
+ InputViewModel newViewModel = new InputViewModel(this, useGlobalConfig); // Create new Input Page with the selected input config scope.
+ newViewModel.PropertyChanged += ViewModel_OnPropertyChanged;
+ _subscribedViewModel = newViewModel;
+
+ ViewModel = newViewModel;
InitializeComponent();
SetupProfileBoxItemTemplate();
+ _isEditingProfileName = false;
+ UpdateProfileLinkIconVisibility();
+
if (VisualRoot is not null)
{
ViewModel.RetargetKeyboardDriver(this);
@@ -232,8 +249,44 @@ namespace Ryujinx.Ava.UI.Views.Input
ViewModel?.LoadProfile();
}
+ private void ViewModel_OnPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == nameof(InputViewModel.IsProfileLinked))
+ {
+ UpdateProfileLinkIconVisibility();
+ }
+ }
+
+ private void ProfileBox_OnGotFocus(object sender, GotFocusEventArgs e)
+ {
+ _isEditingProfileName = true;
+ UpdateProfileLinkIconVisibility();
+ }
+
+ private void ProfileBox_OnLostFocus(object sender, RoutedEventArgs e)
+ {
+ _isEditingProfileName = false;
+ UpdateProfileLinkIconVisibility();
+ }
+
+ private void UpdateProfileLinkIconVisibility()
+ {
+ if (ProfileLinkIcon == null)
+ {
+ return;
+ }
+
+ ProfileLinkIcon.IsVisible = !_isEditingProfileName && (ViewModel?.IsProfileLinked ?? false);
+ }
+
public void Dispose()
{
+ if (_subscribedViewModel != null)
+ {
+ _subscribedViewModel.PropertyChanged -= ViewModel_OnPropertyChanged;
+ _subscribedViewModel = null;
+ }
+
ViewModel.Dispose();
}
}