Skip to content

Differentiate direct and indirect pens/tablets on Android #6570

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from

Conversation

Susko3
Copy link
Member

@Susko3 Susko3 commented Apr 27, 2025

This PR uses the Android API 29+ (Android 10+) function InputDevice.isExternal() to check if the tablet device is external or internal, mapping to indirect and direct respectively. The code path that propagate this value to the PenHandler is as follows:

  1. Android sends a pen event to AndroidGameSurface
  2. Query event.getDevice().isExternal() and store to a "global" variable: LastPenDeviceType (on the Android UI thread)
  3. SDL handles the event and adds it to the queue
  4. Handle SDL_EVENT_PEN_PROXIMITY_IN, querying LastPenDeviceType (on the main thread)
  5. Invoke PenHandler

Testing

Tested to work as expected on ASUS Z012D with a Gaomon S620 tablet (thanks @Danielbzac!). I would like to see testing on a Samsung Galaxy Note device to check that internal pen digitizers are actually reported as internal by this API.

Susko3 added 5 commits April 27, 2025 18:12
Based on the heuristic that internal `InputDevice`s are direct and
external are indirect. Ideally, this would be in SDL, but I'm not sure
how to pitch a cross-platform API.
Copy link
Collaborator

@bdach bdach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haven't tested and probably won't, just read through. probably the testing here will be done on users

@@ -530,14 +531,40 @@ private void handleKeyboardEvent(SDL_KeyboardEvent evtKey)

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

protected abstract TabletPenDeviceType GetPenDeviceType(SDL_PenID id);
Copy link
Collaborator

@bdach bdach Apr 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What on earth is this method? Not only is it something that looks like it should delegate straight to SDL3, not a single override of this method uses the supplied argument!

What is even the guarantee that the ID of this "pen device" is going to correlate with whatever the android implementation returns? At that point why even bother with handling the SDL "proximity events" or whatever?

At that point just commit and have this "pen device type" thing be plain global state, it's much less misleading that way.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this was global state, it could change when a pen is pressed down – this could lead to touch or mouse inputs getting stuck (pen pressed down as touch, but released as mouse due to global state).


Debug.Assert(e != null);

// SDLSurface does some weird checks here for event action index, but it doesn't really matter as we only expect one pen at a time
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the sort of comment that is unhelpful. What would be helpful is a link to the checks in question and an explanation of what's "weird" about it so that someone in a year or five can come in and determine what is "weird" about them.

}

/// <summary>
/// Sets <see cref="LastPenDeviceType"/> iff <c>SDLGenericMotionListener_API14.onGenericMotion()</c> would call <c>onNativePen()</c>.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These xmldocs are also describing some super specific scenario (also referencing some sdl method at that?) without linking to any relevant source.

@Susko3
Copy link
Member Author

Susko3 commented May 17, 2025

I have done more testing on this InputDevice.isExternal() idea, seems to work quite well for internal (S-pen) and external (USB) tablets. I'll try to take this to SDL to avoid having all the hacks in o!f.

@Susko3 Susko3 closed this May 17, 2025
@Susko3
Copy link
Member Author

Susko3 commented May 17, 2025

libsdl-org/SDL#13065

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

I wanted help with an issue involving my graphics tablet in the game
2 participants