We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 5058

Summary: SDL2 sending multiple events (keyboard and gamepad) at the same time
Product: SDL Reporter: George McMullen <spam-g-libsdl>
Component: eventsAssignee: Sam Lantinga <slouken>
Status: NEW --- QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: glex.spb
Version: 2.0.13   
Hardware: ARM   
OS: Linux   

Description George McMullen 2020-03-24 21:47:01 UTC
Greetings,

I've been working with SDL2 on Raspberry Pi, but I believe this bug may affect other platforms as well (at least Linux based systems). Below is my current setup:

- Raspberry Pi 3b and 3b+
- Raspbian Stretch (both with AND without RetroPie)
- SDL Versions: Starting with SDL 2.0.6 to current
- Pimoroni Picade USB PCB (https://www.adafruit.com/product/2708)

The Picade device is actually driven by an Arduino Leonardo ATmega32U4 and connects to the Raspberry Pi via USB. Once I'm able to compile my tests on Mac or Ubuntu x86 I'll be able to confirm that this affects other platforms.

The Leonardo can be configured to act as a USB Keyboard or HID interface via it's Sketch. In fact, the Picade acts as both in a way (see https://github.com/pimoroni/Picade-Sketch). Each button can be configured to either trigger a key press/release or a HID gamepad event.

I found that when pressing a button configured as a keyboard button, SDL2 will actually trigger both a keyboard event and a gamepad event. Alternatively, when pressing a button configured as a gamepad button, SDL2 will trigger both a gamepad event and a system mouse event.

I traced this behavior back to SDL 2.0.6, specifically on with a commit on Nov 22, 2016 that attempts to fix an issue with XBox One S controllers. See https://github.com/spurious/SDL-mirror/compare/abf96e098eb177cac7d13ebf0f653f84c4bac7f2...c0bf85bee4bdc7cfeadccbf2e2a426d11620a357 for more information (sorry for the Github mirror link, but haven't found a similar capability for the Mercurial repo).

Versions previous to that commit do not have the issue. All versions after that commit have the issue. If I revert those changes in the latest code, I no longer see the issue.

I'd be happy to submit a patch/pull request to resolve the issue, but that may bring back the issue with the XBox One S controller (and I do not have one of those devices to test with).

I've looked at ways to resolve this by modifying the Picade Sketch, but that hasn't solved the issue. I believe any HID device that sends both gamepad and keyboard events would suffer from this same issue (though there may not be many of those around).

The effect on applications is that they get confused as to which event to respond to. I haven't been able to dive deep enough, but I suspect also that the duplicate events get deleted by SDL before they can be processed and freed by the application. I've seen a similar behavior in the latest version of MAME, which causes the application to crash.

I've looked to see if there is some kind of conflict between the keyboard and sysjoystick event system, but haven't been able to find anything thus far. I'd appreciate any advice on how to troubleshoot SDL2 further in an effort to resolve the issue.

Thanks!
Comment 1 Gleb Mazovetskiy 2020-04-26 23:05:15 UTC
I've recently tried to update SDL2 for RG350 (a handheld gaming device) from 2.0.0 to master and saw the same issue.

Thanks George for tracking it down to a particular commit, I'll see if reverting it helps me as well.
Comment 2 Gleb Mazovetskiy 2020-04-27 02:21:42 UTC
Reverting that patch didn't solve the issue for me but my setup is different.
RG350 linux kernel has a custom kernel "device" that handles mode switching (between kb and joystick) and merging the inputs from the 2 hardware inputs into 1.
Comment 3 Gleb Mazovetskiy 2020-04-27 02:52:20 UTC
The other slight difference in my issue is that I get unexpected keyboard keys in joystick mode (along with the joystick buttons). The original issue is about getting unexpected joystick keys in keyboard mode.
Comment 4 George McMullen 2020-04-29 04:16:20 UTC
Hi Gleb,

That's a cool device! So, you've got a Linux kernel running on it which previously had SDL 2.0.0? If you compile SDL 2.0.0 yourself, do you still not have the error?

It might also be helpful to figure out what subsystem is receiving the joystick commands, it could be SYS or even X11. That might help narrow down where to look.

For me, I basically did a binary search across major versions, then drilled into the commits between the previous working and next non-working version, via binary search again.

I believe I used the suggestion from this StackOverflow post to get the list of commits between versions. https://stackoverflow.com/questions/5863426/get-commit-list-between-tags-in-git

It took a while, because I was doing it all manually. I hope that helps you.
Comment 5 George McMullen 2020-04-29 04:22:33 UTC
PS: Noticed this issue/feature request that may be related. https://bugzilla.libsdl.org/show_bug.cgi?id=4955
Comment 6 Gleb Mazovetskiy 2020-06-20 21:38:23 UTC
Apologies for the late reply!

The entire system is built from source.
The buildroot is here https://github.com/od-contrib/buildroot-rg350-old-kernel
(updated SDL2 is in the `upd-sdl2` branch)

The custom Linux kernel driver that handles merging and mode switching is here: https://github.com/tonyjih/RG350_linux/blob/master/drivers/input/linkdev.c (it's a rather old kernel)

There is no X11 on it at all so I don't think it's that.
Comment 7 Gleb Mazovetskiy 2020-06-20 21:40:22 UTC
The related feature request (4955) is so that we can avoid doing it in the kernel (linkdev.c) but that's a long way away
Comment 8 George McMullen 2020-06-21 07:29:46 UTC
Thanks for the additional information Gleb. I think that the problems presented with the ATmega32U4 and RG350 could be related. Unless of course the linkdev kernel driver isn't somehow preventing the native devices from being read by SDL and somehow SDL is picking up on multiple events.

I didn't do an extensive run of all the events that the ATmega32U4 can produce, only showing that the gamepad events I tested also sent mouse events. Do you have any event logs from the RG350's game pad? I'd like to see which game pad events and key events are firing. Since the ATmega32U4 is programmable, perhaps I can replicate those events and see if I get the same response.

The feature request in 4955 seems to be the way these issues will be fixed long term though, either by being able to address multiple devices within a single map, or for a map to be able to have multiple "sub-maps".