Hide Cursor On Idle (#1993)

* Implement "Hide Cursor On Idle" option

Adds a general option to autohide the cursor after 8s have elapsed.

* Fix cursor not hiding on Windows and dispose it

* Don't dispose cursor, fix var names

* Abide by the GNOME documentation

* Fix nits

* Disabled by default, make it so it doesn't utilize any timer

* Remove *NIX time and extra lines

* Don't calculate if option is disabled

* Move if case

* Fix alignment
This commit is contained in:
pineappleEA 2021-02-15 23:48:21 +02:00 committed by GitHub
parent 80ed8596c1
commit 6f1d964801
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 97 additions and 5 deletions

View file

@ -14,7 +14,7 @@ namespace Ryujinx.Configuration
/// <summary> /// <summary>
/// The current version of the file format /// The current version of the file format
/// </summary> /// </summary>
public const int CurrentVersion = 20; public const int CurrentVersion = 22;
public int Version { get; set; } public int Version { get; set; }
@ -133,6 +133,11 @@ namespace Ryujinx.Configuration
/// </summary> /// </summary>
public bool ShowConfirmExit { get; set; } public bool ShowConfirmExit { get; set; }
/// <summary>
/// Hide Cursor on Idle
/// </summary>
public bool HideCursorOnIdle { get; set; }
/// <summary> /// <summary>
/// Enables or disables Vertical Sync /// Enables or disables Vertical Sync
/// </summary> /// </summary>
@ -253,4 +258,4 @@ namespace Ryujinx.Configuration
JsonHelper.Serialize(fileStream, this, true); JsonHelper.Serialize(fileStream, this, true);
} }
} }
} }

View file

@ -365,6 +365,11 @@ namespace Ryujinx.Configuration
/// </summary> /// </summary>
public ReactiveObject<bool> ShowConfirmExit { get; private set; } public ReactiveObject<bool> ShowConfirmExit { get; private set; }
/// <summary>
/// Hide Cursor on Idle
/// </summary>
public ReactiveObject<bool> HideCursorOnIdle { get; private set; }
private ConfigurationState() private ConfigurationState()
{ {
Ui = new UiSection(); Ui = new UiSection();
@ -375,6 +380,7 @@ namespace Ryujinx.Configuration
EnableDiscordIntegration = new ReactiveObject<bool>(); EnableDiscordIntegration = new ReactiveObject<bool>();
CheckUpdatesOnStart = new ReactiveObject<bool>(); CheckUpdatesOnStart = new ReactiveObject<bool>();
ShowConfirmExit = new ReactiveObject<bool>(); ShowConfirmExit = new ReactiveObject<bool>();
HideCursorOnIdle = new ReactiveObject<bool>();
} }
public ConfigurationFileFormat ToFileFormat() public ConfigurationFileFormat ToFileFormat()
@ -420,6 +426,7 @@ namespace Ryujinx.Configuration
EnableDiscordIntegration = EnableDiscordIntegration, EnableDiscordIntegration = EnableDiscordIntegration,
CheckUpdatesOnStart = CheckUpdatesOnStart, CheckUpdatesOnStart = CheckUpdatesOnStart,
ShowConfirmExit = ShowConfirmExit, ShowConfirmExit = ShowConfirmExit,
HideCursorOnIdle = HideCursorOnIdle,
EnableVsync = Graphics.EnableVsync, EnableVsync = Graphics.EnableVsync,
EnableShaderCache = Graphics.EnableShaderCache, EnableShaderCache = Graphics.EnableShaderCache,
EnablePtc = System.EnablePtc, EnablePtc = System.EnablePtc,
@ -483,6 +490,7 @@ namespace Ryujinx.Configuration
EnableDiscordIntegration.Value = true; EnableDiscordIntegration.Value = true;
CheckUpdatesOnStart.Value = true; CheckUpdatesOnStart.Value = true;
ShowConfirmExit.Value = true; ShowConfirmExit.Value = true;
HideCursorOnIdle.Value = false;
Graphics.EnableVsync.Value = true; Graphics.EnableVsync.Value = true;
Graphics.EnableShaderCache.Value = true; Graphics.EnableShaderCache.Value = true;
System.EnablePtc.Value = true; System.EnablePtc.Value = true;
@ -787,6 +795,15 @@ namespace Ryujinx.Configuration
configurationFileUpdated = true; configurationFileUpdated = true;
} }
if (configurationFileFormat.Version < 22)
{
Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 22.");
configurationFileFormat.HideCursorOnIdle = false;
configurationFileUpdated = true;
}
List<InputConfig> inputConfig = new List<InputConfig>(); List<InputConfig> inputConfig = new List<InputConfig>();
inputConfig.AddRange(configurationFileFormat.ControllerConfig); inputConfig.AddRange(configurationFileFormat.ControllerConfig);
inputConfig.AddRange(configurationFileFormat.KeyboardConfig); inputConfig.AddRange(configurationFileFormat.KeyboardConfig);
@ -814,6 +831,7 @@ namespace Ryujinx.Configuration
EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration; EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration;
CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart; CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart;
ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit; ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit;
HideCursorOnIdle.Value = configurationFileFormat.HideCursorOnIdle;
Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync; Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache; Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
System.EnablePtc.Value = configurationFileFormat.EnablePtc; System.EnablePtc.Value = configurationFileFormat.EnablePtc;

View file

@ -1,5 +1,5 @@
{ {
"version": 20, "version": 22,
"res_scale": 1, "res_scale": 1,
"res_scale_custom": 1, "res_scale_custom": 1,
"max_anisotropy": -1, "max_anisotropy": -1,
@ -22,6 +22,7 @@
"enable_discord_integration": true, "enable_discord_integration": true,
"check_updates_on_start": true, "check_updates_on_start": true,
"show_confirm_exit": true, "show_confirm_exit": true,
"hide_cursor_on_idle": false,
"enable_vsync": true, "enable_vsync": true,
"enable_shader_cache": true, "enable_shader_cache": true,
"enable_ptc": true, "enable_ptc": true,

View file

@ -42,6 +42,8 @@ namespace Ryujinx.Ui
private double _mouseY; private double _mouseY;
private bool _mousePressed; private bool _mousePressed;
private DateTime _lastCursorMoveTime = DateTime.Now;
private bool _toggleFullscreen; private bool _toggleFullscreen;
private bool _toggleDockedMode; private bool _toggleDockedMode;
@ -62,6 +64,8 @@ namespace Ryujinx.Ui
private GraphicsDebugLevel _glLogLevel; private GraphicsDebugLevel _glLogLevel;
private readonly ManualResetEvent _exitEvent; private readonly ManualResetEvent _exitEvent;
private Gdk.Cursor _invisibleCursor = new Gdk.Cursor (Gdk.Display.Default, Gdk.CursorType.BlankCursor);
public GlRenderer(Switch device, GraphicsDebugLevel glLogLevel) public GlRenderer(Switch device, GraphicsDebugLevel glLogLevel)
: base (GetGraphicsMode(), : base (GetGraphicsMode(),
@ -304,9 +308,37 @@ namespace Ryujinx.Ui
_mouseY = evnt.Y; _mouseY = evnt.Y;
} }
ResetCursorIdle();
return false; return false;
} }
private void ResetCursorIdle()
{
if (ConfigurationState.Instance.HideCursorOnIdle)
{
_lastCursorMoveTime = DateTime.Now;
}
if (Window.Cursor != null)
{
Window.Cursor = null;
}
}
private void HideCursorIdle()
{
if (ConfigurationState.Instance.HideCursorOnIdle)
{
TimeSpan elapsedTime = DateTime.Now.Subtract(_lastCursorMoveTime);
if (elapsedTime.TotalSeconds > 8)
{
Gtk.Application.Invoke(delegate { Window.Cursor = _invisibleCursor; });
}
}
}
protected override void OnGetPreferredHeight(out int minimumHeight, out int naturalHeight) protected override void OnGetPreferredHeight(out int minimumHeight, out int naturalHeight)
{ {
Gdk.Monitor monitor = Display.GetMonitorAtWindow(Window); Gdk.Monitor monitor = Display.GetMonitorAtWindow(Window);
@ -485,6 +517,8 @@ namespace Ryujinx.Ui
MotionDevice motionDevice = new MotionDevice(_dsuClient); MotionDevice motionDevice = new MotionDevice(_dsuClient);
HideCursorIdle();
foreach (InputConfig inputConfig in ConfigurationState.Instance.Hid.InputConfig.Value) foreach (InputConfig inputConfig in ConfigurationState.Instance.Hid.InputConfig.Value)
{ {
ControllerKeys currentButton = 0; ControllerKeys currentButton = 0;

View file

@ -43,6 +43,7 @@ namespace Ryujinx.Ui.Windows
[GUI] CheckButton _discordToggle; [GUI] CheckButton _discordToggle;
[GUI] CheckButton _checkUpdatesToggle; [GUI] CheckButton _checkUpdatesToggle;
[GUI] CheckButton _showConfirmExitToggle; [GUI] CheckButton _showConfirmExitToggle;
[GUI] CheckButton _hideCursorOnIdleToggle;
[GUI] CheckButton _vSyncToggle; [GUI] CheckButton _vSyncToggle;
[GUI] CheckButton _shaderCacheToggle; [GUI] CheckButton _shaderCacheToggle;
[GUI] CheckButton _ptcToggle; [GUI] CheckButton _ptcToggle;
@ -185,6 +186,11 @@ namespace Ryujinx.Ui.Windows
_showConfirmExitToggle.Click(); _showConfirmExitToggle.Click();
} }
if (ConfigurationState.Instance.HideCursorOnIdle)
{
_hideCursorOnIdleToggle.Click();
}
if (ConfigurationState.Instance.Graphics.EnableVsync) if (ConfigurationState.Instance.Graphics.EnableVsync)
{ {
_vSyncToggle.Click(); _vSyncToggle.Click();
@ -403,6 +409,7 @@ namespace Ryujinx.Ui.Windows
ConfigurationState.Instance.EnableDiscordIntegration.Value = _discordToggle.Active; ConfigurationState.Instance.EnableDiscordIntegration.Value = _discordToggle.Active;
ConfigurationState.Instance.CheckUpdatesOnStart.Value = _checkUpdatesToggle.Active; ConfigurationState.Instance.CheckUpdatesOnStart.Value = _checkUpdatesToggle.Active;
ConfigurationState.Instance.ShowConfirmExit.Value = _showConfirmExitToggle.Active; ConfigurationState.Instance.ShowConfirmExit.Value = _showConfirmExitToggle.Active;
ConfigurationState.Instance.HideCursorOnIdle.Value = _hideCursorOnIdleToggle.Active;
ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active; ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active; ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active;
ConfigurationState.Instance.System.EnablePtc.Value = _ptcToggle.Active; ConfigurationState.Instance.System.EnablePtc.Value = _ptcToggle.Active;
@ -582,4 +589,4 @@ namespace Ryujinx.Ui.Windows
Dispose(); Dispose();
} }
} }
} }

View file

@ -150,7 +150,23 @@
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="padding">5</property> <property name="padding">5</property>
<property name="position">1</property> <property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="_hideCursorOnIdleToggle">
<property name="label" translatable="yes">Hide Cursor On Idle</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="halign">start</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">5</property>
<property name="position">3</property>
</packing> </packing>
</child> </child>
</object> </object>

View file

@ -1209,6 +1209,17 @@
true, true,
false false
] ]
},
"hide_cursor_on_idle": {
"$id": "#/properties/hide_cursor_on_idle",
"type": "boolean",
"title": "Hide Cursor On Idle",
"description": "Hides the cursor after being idle for 5 seconds",
"default": false,
"examples": [
true,
false
]
}, },
"enable_vsync": { "enable_vsync": {
"$id": "#/properties/enable_vsync", "$id": "#/properties/enable_vsync",