Merge pull request #6703 from Susko3/android-pen-workaround

Add workaround for pen clicks not working on Android
This commit is contained in:
Dan Balasescu
2026-01-29 17:14:51 +09:00
committed by GitHub

View File

@@ -533,11 +533,36 @@ namespace osu.Framework.Platform.SDL3
private void handleKeymapChangedEvent() => KeymapChanged?.Invoke();
private readonly bool penProximityWorkaround = RuntimeInfo.OS == RuntimeInfo.Platform.Android;
private bool tryGetPenDeviceType(SDL_PenID penID, out TabletPenDeviceType deviceType)
{
if (penDeviceTypes.TryGetValue(penID, out deviceType))
return true;
// Workaround for Android: after clicking with a pen, it can send motion and touch events even though we've received SDL_EVENT_PEN_PROXIMITY_OUT.
// It's either a bug in Android or SDL.
// Instead of ignoring those events, fetch the type and store it.
if (penProximityWorkaround)
{
var sdlType = SDL_GetPenDeviceType(penID);
if (sdlType == SDL_PenDeviceType.SDL_PEN_DEVICE_TYPE_INVALID)
return false;
deviceType = sdlType.ToTabletPenDeviceType();
penDeviceTypes[penID] = deviceType;
return true;
}
return false;
}
private void handlePenProximityEvent(SDL_PenProximityEvent evtPenProximity)
{
if (evtPenProximity.type == SDL_EventType.SDL_EVENT_PEN_PROXIMITY_IN)
{
if (penDeviceTypes.ContainsKey(evtPenProximity.which))
if (!penProximityWorkaround && penDeviceTypes.ContainsKey(evtPenProximity.which))
Logger.Log($"Unexpected SDL_EVENT_PEN_PROXIMITY_IN for pen id={evtPenProximity.which}. Pen already in proximity.", level: LogLevel.Important);
penDeviceTypes[evtPenProximity.which] = SDL_GetPenDeviceType(evtPenProximity.which).ThrowIfFailed().ToTabletPenDeviceType();
@@ -551,7 +576,7 @@ namespace osu.Framework.Platform.SDL3
private void handlePenMotionEvent(SDL_PenMotionEvent evtPenMotion)
{
if (penDeviceTypes.TryGetValue(evtPenMotion.which, out var type))
if (tryGetPenDeviceType(evtPenMotion.which, out var type))
PenMove?.Invoke(type, new Vector2(evtPenMotion.x, evtPenMotion.y) * Scale, evtPenMotion.pen_state.HasFlagFast(SDL_PenInputFlags.SDL_PEN_INPUT_DOWN));
else
Logger.Log($"Unexpected SDL_EVENT_PEN_MOTION for pen id={evtPenMotion.which}. Pen not in proximity.", level: LogLevel.Important);
@@ -559,7 +584,7 @@ namespace osu.Framework.Platform.SDL3
private void handlePenTouchEvent(SDL_PenTouchEvent evtPenTouch)
{
if (penDeviceTypes.TryGetValue(evtPenTouch.which, out var type))
if (tryGetPenDeviceType(evtPenTouch.which, out var type))
PenTouch?.Invoke(type, evtPenTouch.down, new Vector2(evtPenTouch.x, evtPenTouch.y) * Scale);
else
Logger.Log($"Unexpected {evtPenTouch.type} for pen id={evtPenTouch.which}. Pen not in proximity.", level: LogLevel.Important);