[X11] Reconcile logical keyboard state with physical state on FocusIn

since the window system doesn't do it for us like other platforms.

This prevents sticky keys and missed keys when going in and out
of focus, for example Alt would appear to stick if switching away
from an SDL app with Alt-Tab and had to be pressed again.

CR: Sam
This commit is contained in:
Pierre-Loup A. Griffais 2014-09-11 19:24:42 -07:00
parent 6ed37a2783
commit d74afdb47b

View file

@ -507,6 +507,27 @@ ProcessHitTest(_THIS, const SDL_WindowData *data, const XEvent *xev)
return ret;
}
static void
ReconcileKeyboardState(_THIS, const SDL_WindowData *data)
{
SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
SDL_Window* window = data->window;
Display *display = viddata->display;
char keys[32];
int keycode = 0;
X11_XQueryKeymap( display, keys );
while ( keycode < 256 ) {
if ( keys[keycode / 8] & (1 << (keycode % 8)) ) {
SDL_SendKeyboardKey(SDL_PRESSED, viddata->key_layout[keycode]);
} else {
SDL_SendKeyboardKey(SDL_RELEASED, viddata->key_layout[keycode]);
}
keycode++;
}
}
static void
X11_DispatchEvent(_THIS)
{
@ -655,16 +676,7 @@ X11_DispatchEvent(_THIS)
#endif
if (data->pending_focus == PENDING_FOCUS_OUT &&
data->window == SDL_GetKeyboardFocus()) {
/* We want to reset the keyboard here, because we may have
missed keyboard messages after our previous FocusOut.
*/
/* Actually, if we do this we clear the ALT key on Unity
because it briefly takes focus for their dashboard.
I think it's better to think the ALT key is held down
when it's not, then always lose the ALT modifier on Unity.
*/
/* SDL_ResetKeyboard(); */
ReconcileKeyboardState(_this, data);
}
data->pending_focus = PENDING_FOCUS_IN;
data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_IN_TIME;