Skip to content

Commit 1e6e595

Browse files
committed
Fixed bug 3332 - Win32: reset deadkeys in StartTextInput/StopTextInput
Eric Wasylishen The bug here is that a dead keys pressed before calling SDL_StartTextInput() carries over into future text input, so the next key pressed will have the deadkey applied to it. This in undesirable, imho, and doesn't occur on OS X (haven't check Linux or elsewhere). It's causing a problem for Quakespasm on German keyboard layouts, where we use the ^ deadkey to toggle the console (which enables/disables text input), and ^ characters are showing up in the TEXTINPUT events.
1 parent 708def8 commit 1e6e595

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

src/video/windows/SDL_windowskeyboard.c

+48-2
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,51 @@ WIN_QuitKeyboard(_THIS)
157157
#endif
158158
}
159159

160+
void
161+
WIN_ResetDeadKeys()
162+
{
163+
/*
164+
if a deadkey has been typed, but not the next character (which the deadkey might modify),
165+
this tries to undo the effect pressing the deadkey.
166+
see: http://archives.miloush.net/michkap/archive/2006/09/10/748775.html
167+
*/
168+
169+
BYTE keyboardState[256];
170+
WCHAR buffer[16];
171+
int keycode, scancode, result, i;
172+
173+
GetKeyboardState(keyboardState);
174+
175+
keycode = VK_SPACE;
176+
scancode = MapVirtualKey(keycode, MAPVK_VK_TO_VSC);
177+
if (scancode == 0)
178+
{
179+
/* the keyboard doesn't have this key */
180+
return;
181+
}
182+
183+
for (i = 0; i < 5; i++)
184+
{
185+
result = ToUnicode(keycode, scancode, keyboardState, (LPWSTR)buffer, 16, 0);
186+
if (result > 0)
187+
{
188+
/* success */
189+
return;
190+
}
191+
}
192+
}
193+
160194
void
161195
WIN_StartTextInput(_THIS)
162196
{
163197
#ifndef SDL_DISABLE_WINDOWS_IME
164-
SDL_Window *window = SDL_GetKeyboardFocus();
198+
SDL_Window *window;
199+
#endif
200+
201+
WIN_ResetDeadKeys();
202+
203+
#ifndef SDL_DISABLE_WINDOWS_IME
204+
window = SDL_GetKeyboardFocus();
165205
if (window) {
166206
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
167207
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
@@ -176,7 +216,13 @@ void
176216
WIN_StopTextInput(_THIS)
177217
{
178218
#ifndef SDL_DISABLE_WINDOWS_IME
179-
SDL_Window *window = SDL_GetKeyboardFocus();
219+
SDL_Window *window;
220+
#endif
221+
222+
WIN_ResetDeadKeys();
223+
224+
#ifndef SDL_DISABLE_WINDOWS_IME
225+
window = SDL_GetKeyboardFocus();
180226
if (window) {
181227
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
182228
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;

0 commit comments

Comments
 (0)