SDL3 Pen: Confusing pen proximity api
(I tested what follows only in linux and x11).
I was going to use the pen capabilities that check for pen proximity and noticed that the concept is not what I expected (I'm used to qt pen api). I was expecting that SDL_EVENT_PEN_PROXIMITY_IN/OUT would be sent when the pen enters/leaves tablet proximity (when the pen is moved near or far from the tablet) but it seems that right now they are sent when the pen is connected/disconnected. No events are sent when the pen is moved near or far from the tablet, but it would be great that they were.
My proposal is to reuse SDL_EVENT_PEN_PROXIMITY_IN/OUT to notify that the pen went near/far away the tablet and add two new event types, SDL_EVENT_PEN_ADDED/REMOVED, and SDL_Event::pdevice (similar to other devices) to notify that the devide was (dis)connected.
I made a sample implementation for what I propose for x11: https://github.com/deiflou/SDL/tree/pen_proximity, I couldn't make it work using wayland though. It is the first time I code any x11/xinput stuff and I don't know if that is the best way.
I'm pretty sure this is supposed to work the way you'd expect. Pinging @icculus to verify.
I think there was some weird limitation, like Wayland only reports pens on connect/disconnect and not on tradition proximity, but I could be totally wrong. I'll check tonight when I'm in from of a real computer!
Just as an informative note: I based the code in qt's handling of the proximity: https://github.com/qt/qtbase/blob/731d9a13956ef40e3f563f5ff5ff5c250b8d6d94/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp#L1515
Okay, I looked back over the subsystem, and we're not going to add new events. Several serious platforms don't report devices coming and going. Some only report proximity events when a pen moves, without any indication that the pen or tablet existed before. Some don't even send proximity events! You don't know the pen exists until it sends a touch event and then we synthesize a proximity event from there.
That being said, since we can apparently get better proximity events from X11, we should make them work as expected, instead of only sending proximity_out if the tablet is unplugged.
Working on this; looks like X11, Wayland, and (maybe?) Cocoa can handle proximity separate from tool add/remove, at least in some cases. I've cleaned up @deiflou's patch and am trying to thread it through the various backends now.
and (maybe?) Cocoa
Cocoa won't tell you when a device is added or removed, but device IDs are stable between proximity events. So we can just add a pen device when we see a new ID on proximity-in, and never remove it (until shutdown). You probably get new device IDs if you unplug and reconnect a tablet, but that'd have to happen a lot to cause a significant drain, so I'm willing to live with it.
Actually, this might be true of everything. Hmm.
Okay, this sucks like 1000x less. :)
I'm going to test this on various platforms before we merge, but this was an obvious win once I saw it in action.
Hi. I tested the changes. This is what I saw:
- In X11: It sends proximity events when the pen enters/leaves proximity (as I would expect)
- In wayland: It sends 3 proximity in events on tablet plug in (and when the app starts and the tablet is plugged in); and it sends 3 proximity out events when I plug the tablet out
If you want me to test anything more concrete, just ask. Thanks for all the improvements.
In wayland: It sends 3 proximity in events on tablet plug in (and when the app starts and the tablet is plugged in); and it sends 3 proximity out events when I plug the tablet out
I see this too, with XWayland; if you force SDL to use the Wayland video backend, this doesn't happen (right now, SDL defaults to X11, until some important protocols are available, so you have to set the SDL_VIDEO_DRIVER=wayland environment variable to get it). On real X11 I don't get the multiple device thing with the same laptop and tablet.
It's possible that the three separate devices is an XWayland bug or our XInput2 code mishandling something, but I don't know, and I'm willing to let it slide for now.
Unrelated: Wayland is also the only system of all SDL's supported platforms that reports SDL_PEN_AXIS_DISTANCE with my tablet, which is kinda cool.
Ok. I tried again using the environment variable and the proximity in/out events are sent as in x11. The only thing I noticed that differs is that in x11 they are always sent, even if the pointer is not over the window. In wayland they are sent only if the pointer is over the window. This is not something I care about, I'm just reporting because I don't really know the "right" way it should behave.
Thanks again.