Keyboard input problems with libsdl2 on Linux

I've been getting stuck and confused, or confusing myself a couple times over the last eight weeks with my code ~= HMH days 16 - 20. For the most part things had been going really smoothly until the last three weeks, especially the last seven days, I struggled with keyboard input on the SDL2 platform. And turns out there is a good reason why.

For libsdl2 v2.0.4 and 2.0.5, when I pressed and held a key, it would report only one event with the repeat flag set after the system auto-repeat delay (500ms). Then it spammed keydown & pressed - keyup & released events with the repeat flag unset, which continued for up to a couple of seconds after the key was physically released. There's no way I could filter these events

This started after adding the SDL2 equivalent sleep function to return CPU to the system after each frame was processed. Prior to that, the bug wasn't showing (although I recall the event flags in my debug printouts were still wrong). I very soon dropped the idea that the sleep was the root cause (else developing SDL2 on Linux would be completely untenable).

I tried everything. I fiddled with the auto-repeat settings, I tried to get input from X11 instead. I even wrote code to get events directly from the evdev kernel interface. Of course, the kernel events were perfect. But behind a display server that's behind a window manager that's behind <yet another interface> ... that's behind SDL2, polling input directly from the kernel breaks the security model of the GUI stack. Even though my code POC'd my suspicions, I couldn't distribute games that uses it (although a handmade Linux desktop could ;)

Finally, I found a bug report for SDL2 last night. It was exactly this issue.
https://bugzilla.libsdl.org/show_bug.cgi?id=3472

And there is a patch that I tested locally on my system with success.
https://bugzilla-attachments.libsdl.org/attachment.cgi?id=2594

Buggy Example:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
TS: 4266  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4305  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 4305  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4305  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4332  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4332  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4372  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 4372  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4372  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4399  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4399  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4439  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 4439  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4439  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4467  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4467  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4467  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4506  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4533  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4567  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4606  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4640  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4667  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4700  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4739  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4772  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4800  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4833  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4873  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4906  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 4933  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 4967  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 5005  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 5039  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 5066  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0


Correct Example:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
TS: 4385  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0
TS: 5383  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 0
TS: 5885  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 5919  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 5952  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 5985  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6018  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6051  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6084  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6118  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6151  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6184  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6217  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6250  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6285  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6317  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6350  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6383  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6417  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6450  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6483  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6516  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6551  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6584  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6617  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6650  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6683  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6717  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6751  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6785  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6818  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6851  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6885  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6918  KeyUp: 0  KeyDwn: 1 Pressed: 1 Release: 0 Repeat: 1
TS: 6952  KeyUp: 1  KeyDwn: 0 Pressed: 0 Release: 1 Repeat: 0

This was probably my fault, sorry!

I submitted a few patches to SDL in 2.0.4 to correct a couple of XIM related issues, and they were included in 2.0.5. Unfortunately these changes seemed to have some bad interactions with certain input methods and caused the broken key repeats.

I wrote the patch you linked pretty soon after 2.0.5 was released and I was made aware of the problem, but I guess it might not have been included in every distro's copy of 2.0.5 yet.

You said this also happened in 2.0.4 though, so maybe there was some other older issue that my patch fixed? In any case, if you run with XMODIFIERS="@im=none" (or maybe unset) then there shouldn't be any repeat problems - you could setenv() this before initing SDL I suppose.
(╯°□°)╯︵ ┻━┻