diff --git a/src/Ryujinx.Gtk3/UI/RendererWidgetBase.cs b/src/Ryujinx.Gtk3/UI/RendererWidgetBase.cs index 0e636792db00..70f474a94de2 100644 --- a/src/Ryujinx.Gtk3/UI/RendererWidgetBase.cs +++ b/src/Ryujinx.Gtk3/UI/RendererWidgetBase.cs @@ -70,10 +70,10 @@ public abstract class RendererWidgetBase : DrawingArea private readonly CancellationTokenSource _gpuCancellationTokenSource; // Hide Cursor - const int CursorHideIdleTime = 5; // seconds private static readonly Cursor _invisibleCursor = new(Display.Default, CursorType.BlankCursor); private long _lastCursorMoveTime; private HideCursorMode _hideCursorMode; + private int _hideCursorIdleTime; private readonly InputManager _inputManager; private readonly IKeyboard _keyboardInterface; private readonly GraphicsDebugLevel _glLogLevel; @@ -116,9 +116,12 @@ public RendererWidgetBase(InputManager inputManager, GraphicsDebugLevel glLogLev _gpuCancellationTokenSource = new CancellationTokenSource(); _hideCursorMode = ConfigurationState.Instance.HideCursor; + _hideCursorIdleTime = ConfigurationState.Instance.HideCursorIdleTime; + _lastCursorMoveTime = Stopwatch.GetTimestamp(); ConfigurationState.Instance.HideCursor.Event += HideCursorStateChanged; + ConfigurationState.Instance.HideCursorIdleTime.Event += HideCursorIdleTimeStateChanged; ConfigurationState.Instance.Graphics.AntiAliasing.Event += UpdateAnriAliasing; ConfigurationState.Instance.Graphics.ScalingFilter.Event += UpdateScalingFilter; ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event += UpdateScalingFilterLevel; @@ -170,9 +173,18 @@ private void HideCursorStateChanged(object sender, ReactiveEventArgs state) + { + Application.Invoke(delegate + { + _hideCursorIdleTime = state.NewValue; + }); + } + private void Renderer_Destroyed(object sender, EventArgs e) { ConfigurationState.Instance.HideCursor.Event -= HideCursorStateChanged; + ConfigurationState.Instance.HideCursorIdleTime.Event -= HideCursorIdleTimeStateChanged; ConfigurationState.Instance.Graphics.AntiAliasing.Event -= UpdateAnriAliasing; ConfigurationState.Instance.Graphics.ScalingFilter.Event -= UpdateScalingFilter; ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event -= UpdateScalingFilterLevel; @@ -335,7 +347,7 @@ private void HandleScreenState(KeyboardStateSnapshot keyboard) { case HideCursorMode.OnIdle: long cursorMoveDelta = Stopwatch.GetTimestamp() - _lastCursorMoveTime; - Window.Cursor = (cursorMoveDelta >= CursorHideIdleTime * Stopwatch.Frequency) ? _invisibleCursor : null; + Window.Cursor = (cursorMoveDelta >= _hideCursorIdleTime * Stopwatch.Frequency) ? _invisibleCursor : null; break; case HideCursorMode.Always: Window.Cursor = _invisibleCursor; diff --git a/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.cs b/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.cs index dc467c0f211f..b2f8ab8a7a60 100644 --- a/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.cs +++ b/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.cs @@ -53,9 +53,9 @@ public class SettingsWindow : Window [GUI] CheckButton _discordToggle; [GUI] CheckButton _checkUpdatesToggle; [GUI] CheckButton _showConfirmExitToggle; - [GUI] RadioButton _hideCursorNever; - [GUI] RadioButton _hideCursorOnIdle; - [GUI] RadioButton _hideCursorAlways; + [GUI] ComboBoxText _hideCursorSelect; + [GUI] Box _hideCursorIdleTimeBox; + [GUI] Entry _hideCursorIdleTimeSpin; [GUI] CheckButton _vSyncToggle; [GUI] CheckButton _shaderCacheToggle; [GUI] CheckButton _textureRecompressionToggle; @@ -147,6 +147,7 @@ private SettingsWindow(MainWindow parent, Builder builder, VirtualFileSystem vir _configureControllerH.Pressed += (sender, args) => ConfigureController_Pressed(sender, PlayerIndex.Handheld); _systemTimeZoneEntry.FocusOutEvent += TimeZoneEntry_FocusOut; + _hideCursorSelect.Changed += (sender, args) => _hideCursorIdleTimeBox.Visible = _hideCursorSelect.ActiveId == HideCursorMode.OnIdle.ToString(); _resScaleCombo.Changed += (sender, args) => _resScaleText.Visible = _resScaleCombo.ActiveId == "-1"; _scalingFilter.Changed += (sender, args) => _scalingFilterSlider.Visible = _scalingFilter.ActiveId == "2"; _galThreading.Changed += (sender, args) => @@ -230,19 +231,6 @@ private SettingsWindow(MainWindow parent, Builder builder, VirtualFileSystem vir _showConfirmExitToggle.Click(); } - switch (ConfigurationState.Instance.HideCursor.Value) - { - case HideCursorMode.Never: - _hideCursorNever.Click(); - break; - case HideCursorMode.OnIdle: - _hideCursorOnIdle.Click(); - break; - case HideCursorMode.Always: - _hideCursorAlways.Click(); - break; - } - if (ConfigurationState.Instance.Graphics.EnableVsync) { _vSyncToggle.Click(); @@ -349,6 +337,7 @@ private SettingsWindow(MainWindow parent, Builder builder, VirtualFileSystem vir _systemTimeZoneCompletion.MatchFunc = TimeZoneMatchFunc; + _hideCursorSelect.SetActiveId(ConfigurationState.Instance.HideCursor.Value.ToString()); _systemLanguageSelect.SetActiveId(ConfigurationState.Instance.System.Language.Value.ToString()); _systemRegionSelect.SetActiveId(ConfigurationState.Instance.System.Region.Value.ToString()); _galThreading.SetActiveId(ConfigurationState.Instance.Graphics.BackendThreading.Value.ToString()); @@ -366,6 +355,8 @@ private SettingsWindow(MainWindow parent, Builder builder, VirtualFileSystem vir _multiLanSelect.SetActiveId(ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value); _multiModeSelect.SetActiveId(ConfigurationState.Instance.Multiplayer.Mode.Value.ToString()); + _hideCursorIdleTimeBox.Visible = _hideCursorSelect.ActiveId == HideCursorMode.OnIdle.ToString(); + _hideCursorIdleTimeSpin.Buffer.Text = ConfigurationState.Instance.HideCursorIdleTime.Value.ToString(); _custThemePath.Buffer.Text = ConfigurationState.Instance.UI.CustomThemePath; _resScaleText.Buffer.Text = ConfigurationState.Instance.Graphics.ResScaleCustom.Value.ToString(); _scalingFilterLevel.Value = ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value; @@ -573,18 +564,6 @@ private void SaveSettings() _directoryChanged = false; } - HideCursorMode hideCursor = HideCursorMode.Never; - - if (_hideCursorOnIdle.Active) - { - hideCursor = HideCursorMode.OnIdle; - } - - if (_hideCursorAlways.Active) - { - hideCursor = HideCursorMode.Always; - } - if (!float.TryParse(_resScaleText.Buffer.Text, out float resScaleCustom) || resScaleCustom <= 0.0f) { resScaleCustom = 1.0f; @@ -627,7 +606,8 @@ private void SaveSettings() ConfigurationState.Instance.EnableDiscordIntegration.Value = _discordToggle.Active; ConfigurationState.Instance.CheckUpdatesOnStart.Value = _checkUpdatesToggle.Active; ConfigurationState.Instance.ShowConfirmExit.Value = _showConfirmExitToggle.Active; - ConfigurationState.Instance.HideCursor.Value = hideCursor; + ConfigurationState.Instance.HideCursor.Value = Enum.Parse(_hideCursorSelect.ActiveId); + ConfigurationState.Instance.HideCursorIdleTime.Value = int.Parse(_hideCursorIdleTimeSpin.Buffer.Text); ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active; ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active; ConfigurationState.Instance.Graphics.EnableTextureRecompression.Value = _textureRecompressionToggle.Active; diff --git a/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.glade b/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.glade index f0dbd6b63709..4026021d2526 100644 --- a/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.glade +++ b/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.glade @@ -2,6 +2,12 @@ + + 1 + 10 + 1 + 1 + 3 1 @@ -104,147 +110,147 @@ - - True - False - 10 - 10 - vertical - - - Enable Discord Rich Presence - True - True - False - Choose whether or not to display Ryujinx on your "currently playing" Discord activity - start - True - - - False - True - 5 - 0 - - - - - Check for Updates on Launch - True - True - False - start - True - - - False - True - 5 - 1 - - - - - Show "Confirm Exit" Dialog - True - True - False - start - True - - - False - True - 5 - 2 - - - - + True False + 10 + 10 + vertical - - True - False - end - Hide Cursor: - - - False - True - 5 - 2 - + + Enable Discord Rich Presence + True + True + False + Choose whether or not to display Ryujinx on your "currently playing" Discord activity + start + True + + + False + True + 5 + 0 + - - Never - True - True - False - start - 5 - 5 - True - True - - - False - True - 3 - + + Check for Updates on Launch + True + True + False + start + True + + + False + True + 5 + 1 + - - On Idle - True - True - False - start - 5 - 5 - True - _hideCursorNever - - - False - True - 4 - + + Show "Confirm Exit" Dialog + True + True + False + start + True + + + False + True + 5 + 2 + - - Always - True - True - False - start - 5 - 5 - True - _hideCursorNever - - - False - True - 5 - + + True + False + + + True + False + end + Whether to hide cursor on idle, always or never + Hide Cursor: + + + False + True + 5 + 2 + + + + + True + True + 100 + Whether to hide cursor on idle, always or never + + Never + On Idle + Always + + + + False + True + 3 + + + + + False + False + + + True + False + 10 + 5 + How many seconds to wait before hiding the cursor + Seconds: + + + False + True + 4 + + + + + True + True + How many seconds to wait before hiding the cursor + 0 + _hideCursorIdleTimeSpinAdjustment + + + False + False + 5 + + + + + + + True + True + 5 + 4 + - - - False - True - 5 - 4 - - - - + + True True 1 - + diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs index 3387e1be13b4..aa80ca5d0270 100644 --- a/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs +++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs @@ -172,6 +172,11 @@ public class ConfigurationFileFormat /// public HideCursorMode HideCursor { get; set; } + /// + /// How many seconds to wait before hiding the cursor when set to hide on idle + /// + public int HideCursorIdleTime { get; set; } + /// /// Enables or disables Vertical Sync /// diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs index 2609dc9baa56..257cd4ebd781 100644 --- a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs +++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs @@ -632,10 +632,15 @@ public MultiplayerSection() public ReactiveObject EnableHardwareAcceleration { get; private set; } /// - /// Hide Cursor on Idle + /// Whether to hide cursor on idle, always or never /// public ReactiveObject HideCursor { get; private set; } + /// + /// How many seconds to wait before hiding the cursor when set to hide on idle + /// + public ReactiveObject HideCursorIdleTime { get; private set; } + private ConfigurationState() { UI = new UISection(); @@ -649,6 +654,7 @@ private ConfigurationState() ShowConfirmExit = new ReactiveObject(); EnableHardwareAcceleration = new ReactiveObject(); HideCursor = new ReactiveObject(); + HideCursorIdleTime = new ReactiveObject(); } public ConfigurationFileFormat ToFileFormat() @@ -686,6 +692,7 @@ public ConfigurationFileFormat ToFileFormat() ShowConfirmExit = ShowConfirmExit, EnableHardwareAcceleration = EnableHardwareAcceleration, HideCursor = HideCursor, + HideCursorIdleTime = HideCursorIdleTime, EnableVsync = Graphics.EnableVsync, EnableShaderCache = Graphics.EnableShaderCache, EnableTextureRecompression = Graphics.EnableTextureRecompression, @@ -794,6 +801,7 @@ public void LoadDefault() ShowConfirmExit.Value = true; EnableHardwareAcceleration.Value = true; HideCursor.Value = HideCursorMode.OnIdle; + HideCursorIdleTime.Value = 5; Graphics.EnableVsync.Value = true; Graphics.EnableShaderCache.Value = true; Graphics.EnableTextureRecompression.Value = false; @@ -1491,6 +1499,7 @@ public void Load(ConfigurationFileFormat configurationFileFormat, string configu ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit; EnableHardwareAcceleration.Value = configurationFileFormat.EnableHardwareAcceleration; HideCursor.Value = configurationFileFormat.HideCursor; + HideCursorIdleTime.Value = configurationFileFormat.HideCursorIdleTime; Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync; Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache; Graphics.EnableTextureRecompression.Value = configurationFileFormat.EnableTextureRecompression; diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 6074a5fdb370..d45cec9eef20 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -132,6 +132,7 @@ public bool DirectoryChanged public bool CheckUpdatesOnStart { get; set; } public bool ShowConfirmExit { get; set; } public int HideCursor { get; set; } + public int HideCursorIdleTime { get; set; } public bool EnableDockedMode { get; set; } public bool EnableKeyboard { get; set; } public bool EnableMouse { get; set; } @@ -391,6 +392,7 @@ public void LoadCurrentConfiguration() CheckUpdatesOnStart = config.CheckUpdatesOnStart; ShowConfirmExit = config.ShowConfirmExit; HideCursor = (int)config.HideCursor.Value; + HideCursorIdleTime = (int)config.HideCursorIdleTime.Value; GameDirectories.Clear(); GameDirectories.AddRange(config.UI.GameDirs.Value); @@ -475,6 +477,7 @@ public void SaveSettings() config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart; config.ShowConfirmExit.Value = ShowConfirmExit; config.HideCursor.Value = (HideCursorMode)HideCursor; + config.HideCursorIdleTime.Value = HideCursorIdleTime; if (_directoryChanged) {