Fixing windows ink tablet events on SDL3
Susko3 opened this issue · 1 comments
Preface
For best performance and customizability, the built in tablet drivers should be used. But windows ink tablets are quite common and plug-and-play on windows, so it makes sense to support them.
Supporting tablets that generate fake mouse events (likely includes external OpenTabletDriver) is out of scope, if it works then great, but if it doesn't, we'll ask users to disable relative mouse mode.
Related issues:
- SDL3
- Before SDL3
SDL changes
SDL3 already handles absolute raw input (i.e. tablets/windows ink), but it forcefully converts the events to relative motion. So the fix is to report the events as absolute input. Importantly, the mouseID is SDL_PEN_MOUSEID to allow discerning those events framework-side. (By default, the tablet inputs are marked with mouseID=0, same as touchpad inputs.)
Unsure if upstream will accept this. We would hide this behind a hint, eg. SDL_HINT_WINDOWS_TABLET_ALWAYS_ABSOLUTE_MOTION, but using SDL_PEN_MOUSEID
is really hacky. There is already a way to discern tablet events from touches that is arguably just as hacky.
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index eb0131b2b..52d3ca2eb 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -578,13 +578,7 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDL
}
}
} else {
- const int MAXIMUM_TABLET_RELATIVE_MOTION = 32;
- if (SDL_abs(relX) > MAXIMUM_TABLET_RELATIVE_MOTION ||
- SDL_abs(relY) > MAXIMUM_TABLET_RELATIVE_MOTION) {
- /* Ignore this motion, probably a pen lift and drop */
- } else {
- SDL_SendMouseMotion(timestamp, window, mouseID, SDL_TRUE, (float)relX, (float)relY);
- }
+ SDL_SendMouseMotion(timestamp, window, SDL_PEN_MOUSEID, SDL_FALSE, (float)(x - window->x), (float)(y - window->y));
}
data->last_raw_mouse_position.x = x;
Framework changes
Framework-side we'd discern tablet from relative mouse events, similar to how touch events are handled on windows.
osu-framework/osu.Framework/Platform/Windows/WindowsWindow.cs
Lines 218 to 238 in 7fe8bcb
Adding sensitivity is fairly simple, basically copying the old WindowsMouseHandler logic.
osu-framework/osu.Framework/Platform/Windows/WindowsMouseHandler.cs
Lines 129 to 142 in 66e8ea1
WIP branch & testing
Here's the WIP framework branch: https://github.com/ppy/osu-framework/compare/master...Susko3:win-fix-sdl3-tablet?expand=1. To run, release SDL3-CS locally with the SDL3 changes.
I've tested this with https://github.com/Teages/vTablet using an android phone as a tablet. The code works really well for positioning the cursor, but there are some issues with tablet pen down events not registering. I've not investigated those yet.
Please give it a spin on a real tablet. And if it works fine, I'll start with the upstream SDL changes.
osu! input settings
We should probably have high precision mouse and sensitivity if no tablets are detected. Unsure about the names. It's also possible to have mouse sensitivity be a different setting from tablet sensitivity.
The suggested settings text makes little sense to me. "Using windows ink?" should be removed, or the part after it should be written to make sense.
I can't suggest better copy because I don't know what it's trying to convey.