diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs index 432a37e33..bb58ee517 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/TouchDevice.cs @@ -31,6 +31,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid newState.Touches[i] = new TouchState { DeltaTime = newState.SamplingNumber, + Attribute = pi.Attribute, X = pi.X, Y = pi.Y, FingerId = (uint)i, diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/TouchPoint.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/TouchPoint.cs index d1172dd06..457d2b0d0 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/TouchPoint.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/TouchPoint.cs @@ -1,7 +1,10 @@ +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen; + namespace Ryujinx.HLE.HOS.Services.Hid { public struct TouchPoint { + public TouchAttribute Attribute; public uint X; public uint Y; public uint DiameterX; diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchAttribute.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchAttribute.cs index 8a8f9cc1e..d2c5726a5 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchAttribute.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/TouchScreen/TouchAttribute.cs @@ -3,7 +3,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen { [Flags] - enum TouchAttribute : uint + public enum TouchAttribute : uint { None = 0, Start = 1 << 0, diff --git a/Ryujinx.Input/HLE/TouchScreenManager.cs b/Ryujinx.Input/HLE/TouchScreenManager.cs index ffa8eeacc..579dcd745 100644 --- a/Ryujinx.Input/HLE/TouchScreenManager.cs +++ b/Ryujinx.Input/HLE/TouchScreenManager.cs @@ -1,5 +1,6 @@ using Ryujinx.HLE; using Ryujinx.HLE.HOS.Services.Hid; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.TouchScreen; using System; namespace Ryujinx.Input.HLE @@ -8,6 +9,7 @@ namespace Ryujinx.Input.HLE { private readonly IMouse _mouse; private Switch _device; + private bool _wasClicking; public TouchScreenManager(IMouse mouse) { @@ -19,10 +21,35 @@ namespace Ryujinx.Input.HLE _device = device; } - public bool Update(bool isFocused, float aspectRatio = 0) + public bool Update(bool isFocused, bool isClicking = false, float aspectRatio = 0) { - if (!isFocused) + if (!isFocused || (!_wasClicking && !isClicking)) { + // In case we lost focus, send the end touch. + if (_wasClicking && !isClicking) + { + MouseStateSnapshot snapshot = IMouse.GetMouseStateSnapshot(_mouse); + var touchPosition = IMouse.GetTouchPosition(snapshot.Position, _mouse.ClientSize, aspectRatio); + + TouchPoint currentPoint = new TouchPoint + { + Attribute = TouchAttribute.End, + + X = (uint)touchPosition.X, + Y = (uint)touchPosition.Y, + + // Placeholder values till more data is acquired + DiameterX = 10, + DiameterY = 10, + Angle = 90 + }; + + _device.Hid.Touchscreen.Update(currentPoint); + + } + + _wasClicking = false; + _device.Hid.Touchscreen.Update(); return false; @@ -30,11 +57,24 @@ namespace Ryujinx.Input.HLE if (aspectRatio > 0) { - var snapshot = IMouse.GetMouseStateSnapshot(_mouse); + MouseStateSnapshot snapshot = IMouse.GetMouseStateSnapshot(_mouse); var touchPosition = IMouse.GetTouchPosition(snapshot.Position, _mouse.ClientSize, aspectRatio); + TouchAttribute attribute = TouchAttribute.None; + + if (!_wasClicking && isClicking) + { + attribute = TouchAttribute.Start; + } + else if (_wasClicking && !isClicking) + { + attribute = TouchAttribute.End; + } + TouchPoint currentPoint = new TouchPoint { + Attribute = attribute, + X = (uint)touchPosition.X, Y = (uint)touchPosition.Y, @@ -46,6 +86,8 @@ namespace Ryujinx.Input.HLE _device.Hid.Touchscreen.Update(currentPoint); + _wasClicking = isClicking; + return true; } diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs index d0848012f..50c5725f4 100644 --- a/Ryujinx/Ui/MainWindow.cs +++ b/Ryujinx/Ui/MainWindow.cs @@ -74,6 +74,8 @@ namespace Ryujinx.Ui public RendererWidgetBase RendererWidget; public InputManager InputManager; + public bool IsFocused; + private static bool UseVulkan = false; #pragma warning disable CS0169, CS0649, IDE0044 @@ -157,6 +159,8 @@ namespace Ryujinx.Ui WindowStateEvent += WindowStateEvent_Changed; DeleteEvent += Window_Close; + FocusInEvent += MainWindow_FocusInEvent; + FocusOutEvent += MainWindow_FocusOutEvent; _applicationLibrary.ApplicationAdded += Application_Added; _applicationLibrary.ApplicationCountUpdated += ApplicationCount_Updated; @@ -272,6 +276,16 @@ namespace Ryujinx.Ui _fullScreen.Label = args.Event.NewWindowState.HasFlag(Gdk.WindowState.Fullscreen) ? "Exit Fullscreen" : "Enter Fullscreen"; } + private void MainWindow_FocusOutEvent(object o, FocusOutEventArgs args) + { + IsFocused = false; + } + + private void MainWindow_FocusInEvent(object o, FocusInEventArgs args) + { + IsFocused = true; + } + private void UpdateColumns() { foreach (TreeViewColumn column in _gameTable.Columns) diff --git a/Ryujinx/Ui/RendererWidgetBase.cs b/Ryujinx/Ui/RendererWidgetBase.cs index 4ba87a1b1..289b2dbf1 100644 --- a/Ryujinx/Ui/RendererWidgetBase.cs +++ b/Ryujinx/Ui/RendererWidgetBase.cs @@ -37,7 +37,6 @@ namespace Ryujinx.Ui private bool _isActive; private bool _isStopped; - private bool _isFocused; private bool _toggleFullscreen; private bool _toggleDockedMode; @@ -91,8 +90,6 @@ namespace Ryujinx.Ui | EventMask.KeyPressMask | EventMask.KeyReleaseMask)); - Shown += Renderer_Shown; - _exitEvent = new ManualResetEvent(false); _hideCursorOnIdle = ConfigurationState.Instance.HideCursorOnIdle; @@ -124,16 +121,6 @@ namespace Ryujinx.Ui }); } - private void Parent_FocusOutEvent(object o, Gtk.FocusOutEventArgs args) - { - _isFocused = false; - } - - private void Parent_FocusInEvent(object o, Gtk.FocusInEventArgs args) - { - _isFocused = true; - } - private void Renderer_Destroyed(object sender, EventArgs e) { ConfigurationState.Instance.HideCursorOnIdle.Event -= HideCursorStateChanged; @@ -142,11 +129,6 @@ namespace Ryujinx.Ui Dispose(); } - private void Renderer_Shown(object sender, EventArgs e) - { - _isFocused = ParentWindow.State.HasFlag(Gdk.WindowState.Focused); - } - protected override bool OnMotionNotifyEvent(EventMotion evnt) { if (_hideCursorOnIdle) @@ -341,10 +323,7 @@ namespace Ryujinx.Ui _isActive = true; - Gtk.Window parent = this.Toplevel as Gtk.Window; - - parent.FocusInEvent += Parent_FocusInEvent; - parent.FocusOutEvent += Parent_FocusOutEvent; + Gtk.Window parent = Toplevel as Gtk.Window; Application.Invoke(delegate { @@ -445,9 +424,9 @@ namespace Ryujinx.Ui return false; } - if (_isFocused) + if ((Toplevel as MainWindow).IsFocused) { - Gtk.Application.Invoke(delegate + Application.Invoke(delegate { KeyboardStateSnapshot keyboard = _keyboardInterface.GetKeyboardStateSnapshot(); @@ -465,7 +444,7 @@ namespace Ryujinx.Ui NpadManager.Update(); - if (_isFocused) + if ((Toplevel as MainWindow).IsFocused) { KeyboardHotkeyState currentHotkeyState = GetHotkeyState(); @@ -481,10 +460,10 @@ namespace Ryujinx.Ui // Touchscreen bool hasTouch = false; - // Get screen touch position from left mouse click - if (_isFocused && (_inputManager.MouseDriver as GTK3MouseDriver).IsButtonPressed(MouseButton.Button1)) + // Get screen touch position + if ((Toplevel as MainWindow).IsFocused) { - hasTouch = TouchScreenManager.Update(true, ConfigurationState.Instance.Graphics.AspectRatio.Value.ToFloat()); + hasTouch = TouchScreenManager.Update(true, (_inputManager.MouseDriver as GTK3MouseDriver).IsButtonPressed(MouseButton.Button1), ConfigurationState.Instance.Graphics.AspectRatio.Value.ToFloat()); } if (!hasTouch)