Mercurial > hg > openttd
changeset 20692:ae27ee8c7eed draft
-Fix: [Win32] Only forward key presses to the IME system if an edit box has the input focus.
author | Michael Lutz <michi@icosahedron.de> |
---|---|
date | Sun, 21 Jul 2013 22:23:02 +0200 |
parents | db5bb913dedf |
children | 2b19f1e6c882 |
files | src/video/win32_v.cpp src/window.cpp src/window_func.h |
diffstat | 3 files changed, 52 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -21,6 +21,7 @@ #include "../texteff.hpp" #include "../thread/thread.h" #include "../progress.h" +#include "../window_func.h" #include "win32_v.h" #include <windows.h> @@ -432,6 +433,20 @@ _draw_thread->Exit(); } +/** Forward key presses to the window system. */ +static LRESULT HandleCharMsg(uint keycode, uint charcode) +{ +#if !defined(UNICODE) + wchar_t w; + int len = MultiByteToWideChar(_codepage, 0, (char*)&charcode, 1, &w, 1); + charcode = len == 1 ? w : 0; +#endif /* UNICODE */ + + HandleKeypress(GB(charcode, 0, 16) | (keycode << 16)); + + return 0; +} + static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static uint32 keycode = 0; @@ -592,31 +607,50 @@ return 0; } -#if !defined(UNICODE) - wchar_t w; - int len = MultiByteToWideChar(_codepage, 0, (char*)&charcode, 1, &w, 1); - charcode = len == 1 ? w : 0; -#endif /* UNICODE */ + /* IMEs and other input methods sometimes send a WM_CHAR without a WM_KEYDOWN, + * clear the keycode so a previous WM_KEYDOWN doesn't become 'stuck'. */ + uint cur_keycode = keycode; + keycode = 0; - /* No matter the keyboard layout, we will map the '~' to the console */ - scancode = scancode == 41 ? (int)WKC_BACKQUOTE : keycode; - HandleKeypress(GB(charcode, 0, 16) | (scancode << 16)); - return 0; + return HandleCharMsg(cur_keycode, charcode); } case WM_KEYDOWN: { - keycode = MapWindowsKey(wParam); + /* No matter the keyboard layout, we will map the '~' to the console. */ + uint scancode = GB(lParam, 16, 8); + keycode = scancode == 41 ? WKC_BACKQUOTE : MapWindowsKey(wParam); /* Silently drop all messages handled by WM_CHAR. */ MSG msg; if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { - if (msg.message == WM_CHAR && GB(lParam, 16, 8) == GB(msg.lParam, 16, 8)) { + if ((msg.message == WM_CHAR || msg.message == WM_DEADCHAR) && GB(lParam, 16, 8) == GB(msg.lParam, 16, 8)) { return 0; } } - HandleKeypress(0 | (keycode << 16)); - return 0; + uint charcode = MapVirtualKey(wParam, MAPVK_VK_TO_CHAR); + + /* No character translation? */ + if (charcode == 0) { + HandleKeypress(0 | (keycode << 16)); + return 0; + } + + /* Is the console key a dead key? If yes, ignore the first key down event. */ + if (HasBit(charcode, 31) && !console) { + if (scancode == 41) { + console = true; + return 0; + } + } + console = false; + + /* IMEs and other input methods sometimes send a WM_CHAR without a WM_KEYDOWN, + * clear the keycode so a previous WM_KEYDOWN doesn't become 'stuck'. */ + uint cur_keycode = keycode; + keycode = 0; + + return HandleCharMsg(cur_keycode, LOWORD(charcode)); } case WM_SYSKEYDOWN: // user presses F10 or Alt, both activating the title-menu @@ -979,7 +1013,8 @@ while (PeekMessage(&mesg, NULL, 0, 0, PM_REMOVE)) { InteractiveRandom(); // randomness - TranslateMessage(&mesg); + /* Convert key messages to char messages if we want text input. */ + if (EditBoxInGlobalFocus()) TranslateMessage(&mesg); DispatchMessage(&mesg); } if (_exit_game) return;
--- a/src/window.cpp +++ b/src/window.cpp @@ -350,7 +350,7 @@ * has a edit box as focused widget, or if a console is focused. * @return returns true if an edit box is in global focus or if the focused window is a console, else false */ -static bool EditBoxInGlobalFocus() +bool EditBoxInGlobalFocus() { if (_focused_window == NULL) return false;