Skip to content

Commit 2d602e6

Browse files
committed
Add workaround to fix pen clicks not working on Android
1 parent 5b716dc commit 2d602e6

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

osu.Framework/Platform/SDL3/SDL3Window_Input.cs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -533,11 +533,36 @@ private void handleKeyboardEvent(SDL_KeyboardEvent evtKey)
533533

534534
private void handleKeymapChangedEvent() => KeymapChanged?.Invoke();
535535

536+
private readonly bool penProximityWorkaround = RuntimeInfo.OS == RuntimeInfo.Platform.Android;
537+
538+
private bool tryGetPenDeviceType(SDL_PenID penID, out TabletPenDeviceType deviceType)
539+
{
540+
if (penDeviceTypes.TryGetValue(penID, out deviceType))
541+
return true;
542+
543+
// 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.
544+
// It's either a bug in Android or SDL.
545+
// Instead of ignoring those events, fetch the type and store it.
546+
if (penProximityWorkaround)
547+
{
548+
var sdlType = SDL_GetPenDeviceType(penID);
549+
550+
if (sdlType == SDL_PenDeviceType.SDL_PEN_DEVICE_TYPE_INVALID)
551+
return false;
552+
553+
deviceType = sdlType.ToTabletPenDeviceType();
554+
penDeviceTypes[penID] = deviceType;
555+
return true;
556+
}
557+
558+
return false;
559+
}
560+
536561
private void handlePenProximityEvent(SDL_PenProximityEvent evtPenProximity)
537562
{
538563
if (evtPenProximity.type == SDL_EventType.SDL_EVENT_PEN_PROXIMITY_IN)
539564
{
540-
if (penDeviceTypes.ContainsKey(evtPenProximity.which))
565+
if (!penProximityWorkaround && penDeviceTypes.ContainsKey(evtPenProximity.which))
541566
Logger.Log($"Unexpected SDL_EVENT_PEN_PROXIMITY_IN for pen id={evtPenProximity.which}. Pen already in proximity.", level: LogLevel.Important);
542567

543568
penDeviceTypes[evtPenProximity.which] = SDL_GetPenDeviceType(evtPenProximity.which).ThrowIfFailed().ToTabletPenDeviceType();
@@ -551,15 +576,15 @@ private void handlePenProximityEvent(SDL_PenProximityEvent evtPenProximity)
551576

552577
private void handlePenMotionEvent(SDL_PenMotionEvent evtPenMotion)
553578
{
554-
if (penDeviceTypes.TryGetValue(evtPenMotion.which, out var type))
579+
if (tryGetPenDeviceType(evtPenMotion.which, out var type))
555580
PenMove?.Invoke(type, new Vector2(evtPenMotion.x, evtPenMotion.y) * Scale, evtPenMotion.pen_state.HasFlagFast(SDL_PenInputFlags.SDL_PEN_INPUT_DOWN));
556581
else
557582
Logger.Log($"Unexpected SDL_EVENT_PEN_MOTION for pen id={evtPenMotion.which}. Pen not in proximity.", level: LogLevel.Important);
558583
}
559584

560585
private void handlePenTouchEvent(SDL_PenTouchEvent evtPenTouch)
561586
{
562-
if (penDeviceTypes.TryGetValue(evtPenTouch.which, out var type))
587+
if (tryGetPenDeviceType(evtPenTouch.which, out var type))
563588
PenTouch?.Invoke(type, evtPenTouch.down, new Vector2(evtPenTouch.x, evtPenTouch.y) * Scale);
564589
else
565590
Logger.Log($"Unexpected {evtPenTouch.type} for pen id={evtPenTouch.which}. Pen not in proximity.", level: LogLevel.Important);

0 commit comments

Comments
 (0)