diff -r 5c42e467f6cd src/video/x11/SDL_x11events.c --- a/src/video/x11/SDL_x11events.c Fri Sep 19 12:09:51 2014 -0400 +++ b/src/video/x11/SDL_x11events.c Sun Sep 21 02:46:53 2014 -0500 @@ -507,6 +507,32 @@ return ret; } +static unsigned +GetNumLockModifierMask(_THIS) +{ + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + Display *display = viddata->display; + unsigned num_mask = 0; + int i, j; + XModifierKeymap *xmods; + unsigned n; + + xmods = X11_XGetModifierMapping(display); + n = xmods->max_keypermod; + for(i = 3; i < 8; i++) { + for(j = 0; j < n; j++) { + KeyCode kc = xmods->modifiermap[i * n + j]; + if ( viddata->key_layout[kc] == SDL_SCANCODE_NUMLOCKCLEAR ) { + num_mask = 1 << i; + break; + } + } + } + X11_XFreeModifiermap(xmods); + + return num_mask; +} + static void ReconcileKeyboardState(_THIS, const SDL_WindowData *data) { @@ -515,6 +541,9 @@ Display *display = viddata->display; char keys[32]; int keycode = 0; + Window junk_window; + int x, y; + unsigned int mask; X11_XQueryKeymap( display, keys ); @@ -526,6 +555,30 @@ } keycode++; } + + /* Get the keyboard modifier state */ + if ( X11_XQueryPointer(display, DefaultRootWindow(display), + &junk_window, &junk_window, &x, &y, &x, &y, &mask) ) { + unsigned num_mask = GetNumLockModifierMask(_this); + const Uint8 *keystate = SDL_GetKeyboardState(NULL); + Uint8 capslockState = keystate[SDL_SCANCODE_CAPSLOCK]; + Uint8 numlockState = keystate[SDL_SCANCODE_NUMLOCKCLEAR]; + + /* Toggle key mod state if needed */ + if ( !!(mask & LockMask) != !!(SDL_GetModState() & KMOD_CAPS) ) { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); + if ( capslockState == SDL_RELEASED ) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); + } + } + + if ( !!(mask & num_mask) != !!(SDL_GetModState() & KMOD_NUM) ) { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR); + if ( numlockState == SDL_RELEASED ) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR); + } + } + } } static void @@ -1225,7 +1278,14 @@ Uint32 now = SDL_GetTicks(); if (SDL_TICKS_PASSED(now, data->pending_focus_time)) { if ( data->pending_focus == PENDING_FOCUS_IN ) { + SDL_Window *oldFocus = SDL_GetKeyboardFocus(); + X11_DispatchFocusIn(data); + + /* If no window had focus, get current keyboard state. */ + if (oldFocus == NULL) { + ReconcileKeyboardState(_this, data); + } } else { X11_DispatchFocusOut(data); }