From 3d04d7ef0870fe74c529dd6c35e1c02d869bd3c0 Mon Sep 17 00:00:00 2001 From: mageven <62494521+mageven@users.noreply.github.com> Date: Wed, 3 Mar 2021 04:15:33 +0530 Subject: [PATCH] Fix "Hide Cursor on Idle" inefficiency (#2058) * Rewrite cursor hiding code to be efficient * Formatting nits --- Ryujinx/Ui/GLRenderer.cs | 82 ++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/Ryujinx/Ui/GLRenderer.cs b/Ryujinx/Ui/GLRenderer.cs index 52dcedbc9..896dc1915 100644 --- a/Ryujinx/Ui/GLRenderer.cs +++ b/Ryujinx/Ui/GLRenderer.cs @@ -5,20 +5,23 @@ using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; using OpenTK.Input; +using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Configuration; using Ryujinx.Graphics.OpenGL; -using Ryujinx.HLE; using Ryujinx.HLE.HOS.Services.Hid; using Ryujinx.Modules.Motion; using Ryujinx.Ui.Widgets; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Threading; namespace Ryujinx.Ui { + using Switch = HLE.Switch; + public class GlRenderer : GLWidget { static GlRenderer() @@ -42,8 +45,6 @@ namespace Ryujinx.Ui private double _mouseY; private bool _mousePressed; - private DateTime _lastCursorMoveTime = DateTime.Now; - private bool _toggleFullscreen; private bool _toggleDockedMode; @@ -51,7 +52,7 @@ namespace Ryujinx.Ui private long _ticks = 0; - private readonly System.Diagnostics.Stopwatch _chrono; + private readonly Stopwatch _chrono; private readonly Switch _device; @@ -65,7 +66,11 @@ namespace Ryujinx.Ui private readonly ManualResetEvent _exitEvent; - private Gdk.Cursor _invisibleCursor = new Gdk.Cursor (Gdk.Display.Default, Gdk.CursorType.BlankCursor); + // Hide Cursor + const int CursorHideIdleTime = 8; // seconds + private static readonly Cursor _invisibleCursor = new Cursor(Display.Default, CursorType.BlankCursor); + private long _lastCursorMoveTime; + private bool _hideCursorOnIdle; public GlRenderer(Switch device, GraphicsDebugLevel glLogLevel) : base (GetGraphicsMode(), @@ -84,9 +89,9 @@ namespace Ryujinx.Ui Initialize(); - _chrono = new System.Diagnostics.Stopwatch(); + _chrono = new Stopwatch(); - _ticksPerFrame = System.Diagnostics.Stopwatch.Frequency / TargetFps; + _ticksPerFrame = Stopwatch.Frequency / TargetFps; AddEvents((int)(EventMask.ButtonPressMask | EventMask.ButtonReleaseMask @@ -101,6 +106,28 @@ namespace Ryujinx.Ui _glLogLevel = glLogLevel; _exitEvent = new ManualResetEvent(false); + + _hideCursorOnIdle = ConfigurationState.Instance.HideCursorOnIdle; + _lastCursorMoveTime = Stopwatch.GetTimestamp(); + + ConfigurationState.Instance.HideCursorOnIdle.Event += HideCursorStateChanged; + } + + private void HideCursorStateChanged(object sender, ReactiveEventArgs state) + { + Gtk.Application.Invoke(delegate + { + _hideCursorOnIdle = state.NewValue; + + if (_hideCursorOnIdle) + { + _lastCursorMoveTime = Stopwatch.GetTimestamp(); + } + else + { + Window.Cursor = null; + } + }); } private static GraphicsMode GetGraphicsMode() @@ -126,6 +153,8 @@ namespace Ryujinx.Ui private void GLRenderer_Destroyed(object sender, EventArgs e) { + ConfigurationState.Instance.HideCursorOnIdle.Event -= HideCursorStateChanged; + _dsuClient?.Dispose(); Dispose(); } @@ -186,6 +215,12 @@ namespace Ryujinx.Ui } _toggleDockedMode = toggleDockedMode; + + if (_hideCursorOnIdle) + { + long cursorMoveDelta = Stopwatch.GetTimestamp() - _lastCursorMoveTime; + Window.Cursor = (cursorMoveDelta >= CursorHideIdleTime * Stopwatch.Frequency) ? _invisibleCursor : null; + } } private void GLRenderer_Initialized(object sender, EventArgs e) @@ -308,37 +343,14 @@ namespace Ryujinx.Ui _mouseY = evnt.Y; } - ResetCursorIdle(); + if (_hideCursorOnIdle) + { + _lastCursorMoveTime = Stopwatch.GetTimestamp(); + } 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) { Gdk.Monitor monitor = Display.GetMonitorAtWindow(Window); @@ -517,8 +529,6 @@ namespace Ryujinx.Ui MotionDevice motionDevice = new MotionDevice(_dsuClient); - HideCursorIdle(); - foreach (InputConfig inputConfig in ConfigurationState.Instance.Hid.InputConfig.Value) { ControllerKeys currentButton = 0;