From b246794c72ab30a3ab97694d871296cbde9b1c8c Mon Sep 17 00:00:00 2001 From: Susko3 Date: Sun, 17 Jul 2022 17:00:13 +0200 Subject: [PATCH 1/5] Fix Windows Ink events being handled as touch events --- osu.Framework/Platform/SDL2/SDL2Extensions.cs | 37 +++++++++++++++++++ osu.Framework/Platform/SDL2DesktopWindow.cs | 10 ++++- .../Platform/Windows/WindowsWindow.cs | 27 ++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/osu.Framework/Platform/SDL2/SDL2Extensions.cs b/osu.Framework/Platform/SDL2/SDL2Extensions.cs index 727fe44caa..5fd238815a 100644 --- a/osu.Framework/Platform/SDL2/SDL2Extensions.cs +++ b/osu.Framework/Platform/SDL2/SDL2Extensions.cs @@ -1084,5 +1084,42 @@ public static string ReadableName(this SDL.SDL_LogPriority priority) return "unknown"; } } + + private static bool tryGetTouchDeviceIndex(long touchId, out int index) + { + int n = SDL.SDL_GetNumTouchDevices(); + + for (int i = 0; i < n; i++) + { + long currentTouchId = SDL.SDL_GetTouchDevice(i); + + if (touchId == currentTouchId) + { + index = i; + return true; + } + } + + index = -1; + return false; + } + + /// + /// Gets the of the touch device for this . + /// + /// + /// On Windows, this will return "touch" for touchscreen events or "pen" for pen/tablet events. + /// + public static bool TryGetTouchName(this SDL.SDL_TouchFingerEvent e, out string name) + { + if (tryGetTouchDeviceIndex(e.touchId, out int index)) + { + name = SDL.SDL_GetTouchName(index); + return name != null; + } + + name = null; + return false; + } } } diff --git a/osu.Framework/Platform/SDL2DesktopWindow.cs b/osu.Framework/Platform/SDL2DesktopWindow.cs index d34b273706..38396b06d1 100644 --- a/osu.Framework/Platform/SDL2DesktopWindow.cs +++ b/osu.Framework/Platform/SDL2DesktopWindow.cs @@ -815,7 +815,7 @@ private void handleSDLEvent(SDL.SDL_Event e) case SDL.SDL_EventType.SDL_FINGERDOWN: case SDL.SDL_EventType.SDL_FINGERUP: case SDL.SDL_EventType.SDL_FINGERMOTION: - handleTouchFingerEvent(e.tfinger); + HandleTouchFingerEvent(e.tfinger); break; case SDL.SDL_EventType.SDL_DROPFILE: @@ -869,7 +869,7 @@ private void handleDropEvent(SDL.SDL_DropEvent evtDrop) return null; } - private void handleTouchFingerEvent(SDL.SDL_TouchFingerEvent evtTfinger) + protected virtual void HandleTouchFingerEvent(SDL.SDL_TouchFingerEvent evtTfinger) { var eventType = (SDL.SDL_EventType)evtTfinger.type; @@ -1634,6 +1634,8 @@ private static Display displayFromSDL(int displayIndex) /// public event Action MouseMove; + protected void TriggerMouseMove(float x, float y) => MouseMove?.Invoke(new Vector2(x, y)); + /// /// Invoked when the user moves the mouse cursor within the window (via relative / raw input). /// @@ -1644,11 +1646,15 @@ private static Display displayFromSDL(int displayIndex) /// public event Action MouseDown; + protected void TriggerMouseDown(MouseButton button) => MouseDown?.Invoke(button); + /// /// Invoked when the user releases a mouse button. /// public event Action MouseUp; + protected void TriggerMouseUp(MouseButton button) => MouseUp?.Invoke(button); + /// /// Invoked when the user presses a key. /// diff --git a/osu.Framework/Platform/Windows/WindowsWindow.cs b/osu.Framework/Platform/Windows/WindowsWindow.cs index 96ae4d3509..6faf5bc616 100644 --- a/osu.Framework/Platform/Windows/WindowsWindow.cs +++ b/osu.Framework/Platform/Windows/WindowsWindow.cs @@ -15,6 +15,7 @@ using osu.Framework.Platform.SDL2; using osu.Framework.Platform.Windows.Native; using osuTK; +using osuTK.Input; using SDL2; using Icon = osu.Framework.Platform.Windows.Native.Icon; @@ -248,6 +249,32 @@ private void handleImeMessage(IntPtr hWnd, uint uMsg, long lParam) #endregion + protected override void HandleTouchFingerEvent(SDL.SDL_TouchFingerEvent evtTfinger) + { + if (evtTfinger.TryGetTouchName(out string name) && name == "pen") + { + // Windows Ink tablet/pen handling + // InputManager expects to receive this as mouse events, to have proper `mouseSource` input priority (see InputManager.GetPendingInputs) + + TriggerMouseMove(evtTfinger.x * Size.Width, evtTfinger.y * Size.Height); + + switch ((SDL.SDL_EventType)evtTfinger.type) + { + case SDL.SDL_EventType.SDL_FINGERDOWN: + TriggerMouseDown(MouseButton.Left); + break; + + case SDL.SDL_EventType.SDL_FINGERUP: + TriggerMouseUp(MouseButton.Left); + break; + } + + return; + } + + base.HandleTouchFingerEvent(evtTfinger); + } + public override Size Size { protected set From 8a60c1787b3fcfc6841dc9b5b394f5d2316f4256 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Mon, 22 May 2023 23:33:28 +0200 Subject: [PATCH 2/5] Use correct, scaled size --- osu.Framework/Platform/Windows/WindowsWindow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Framework/Platform/Windows/WindowsWindow.cs b/osu.Framework/Platform/Windows/WindowsWindow.cs index ae04e870b2..1499b99a28 100644 --- a/osu.Framework/Platform/Windows/WindowsWindow.cs +++ b/osu.Framework/Platform/Windows/WindowsWindow.cs @@ -214,7 +214,7 @@ protected override void HandleTouchFingerEvent(SDL.SDL_TouchFingerEvent evtTfing // Windows Ink tablet/pen handling // InputManager expects to receive this as mouse events, to have proper `mouseSource` input priority (see InputManager.GetPendingInputs) - TriggerMouseMove(evtTfinger.x * Size.Width, evtTfinger.y * Size.Height); + TriggerMouseMove(evtTfinger.x * ClientSize.Width, evtTfinger.y * ClientSize.Height); switch ((SDL.SDL_EventType)evtTfinger.type) { From a2abc714f00b749055560318ea4530c2181c8a06 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Sun, 17 Dec 2023 13:31:55 +0100 Subject: [PATCH 3/5] Add note about touch device detection in osu! --- osu.Framework/Platform/Windows/WindowsWindow.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Framework/Platform/Windows/WindowsWindow.cs b/osu.Framework/Platform/Windows/WindowsWindow.cs index 1499b99a28..6e0e687a07 100644 --- a/osu.Framework/Platform/Windows/WindowsWindow.cs +++ b/osu.Framework/Platform/Windows/WindowsWindow.cs @@ -213,6 +213,7 @@ protected override void HandleTouchFingerEvent(SDL.SDL_TouchFingerEvent evtTfing { // Windows Ink tablet/pen handling // InputManager expects to receive this as mouse events, to have proper `mouseSource` input priority (see InputManager.GetPendingInputs) + // osu! expects to get tablet events as mouse events, and touch events as touch events for touch device (TD mod) handling (see https://github.com/ppy/osu/issues/25590) TriggerMouseMove(evtTfinger.x * ClientSize.Width, evtTfinger.y * ClientSize.Height); From 985922df650c54c956a0e0b6dc21833ffb379f41 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Dec 2023 01:05:02 +0900 Subject: [PATCH 4/5] Update SDL2 --- osu.Framework/osu.Framework.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Framework/osu.Framework.csproj b/osu.Framework/osu.Framework.csproj index 591150e5c3..b44f777151 100644 --- a/osu.Framework/osu.Framework.csproj +++ b/osu.Framework/osu.Framework.csproj @@ -38,7 +38,7 @@ - +