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 4989

Summary: video/x11 events from keyboard state reconciliation at focus-in indistinguishable from real events
Product: SDL Reporter: Maarten de Vries <sdl-bugzilla>
Component: videoAssignee: Sam Lantinga <slouken>
Status: NEW --- QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: sdl-bugzilla
Version: HG 2.1   
Hardware: x86_64   
OS: Linux   
Attachments: Send keyboard state reconciliation events with window_id 0

Description Maarten de Vries 2020-02-16 14:10:27 UTC
Created attachment 4219 [details]
Send keyboard state reconciliation events with window_id 0

In the X11 video backend, when a window is focussed in, the current keyboard state is synchronized to the internal state. Each change to the internal state is done by calling SDL_SendKeyboardKey, which generates a key event.

This is done *after* the keyboard focus has been set to the window receiving the focus, so all of these events are reported with the window_id of that window.
I believe this is suboptimal, since the real key-down event happened when the window wasn't focussed.

In my case, this also causes unwanted behaviour in my application. My application responds to the escape key by closing itself. However, if another application is closed with the escape key, and the focus returns to the SDL application, the SDL application still sees the escape key in the pressed state and promptly generates a keydown event for the newly focussed window, which then also closes itself.

The end result is that I press escape once, and two windows respond by closing themselves.

I attached a simple patch that changes this behaviour. The keydown events are still generated, but *before* the keyboard focus is set to the new window. That means the window_id on the event is 0, and my application doesn't close any window.

While this isn't fully backwards compatible, I believe it is better behaviour. I expect that most applications either care either about the key state or real events from hardware. In the first case, the application should be polling the key state whenever the game state is updated, and in the second case the application wouldn't want the keydown event that happened while the window wasn't focussed. I can't be sure, but I may have seen similar issues in other games in the past that could have been caused by this.

I also considered adding a field to the events to mark them as virtual events rather than hardware events, but that would be an ABI incompatible change. If that's not a problem, I could also implement that instead.