mirror of https://github.com/OpenTTD/OpenTTD
(svn r25667) -Fix: [Win32] Only forward key presses to the IME system if an edit box has the input focus.
parent
8b476de3bf
commit
923eb009e8
|
@ -21,9 +21,15 @@
|
||||||
#include "../texteff.hpp"
|
#include "../texteff.hpp"
|
||||||
#include "../thread/thread.h"
|
#include "../thread/thread.h"
|
||||||
#include "../progress.h"
|
#include "../progress.h"
|
||||||
|
#include "../window_func.h"
|
||||||
#include "win32_v.h"
|
#include "win32_v.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
/* Missing define in MinGW headers. */
|
||||||
|
#ifndef MAPVK_VK_TO_CHAR
|
||||||
|
#define MAPVK_VK_TO_CHAR (2)
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
HWND main_wnd;
|
HWND main_wnd;
|
||||||
HBITMAP dib_sect;
|
HBITMAP dib_sect;
|
||||||
|
@ -432,6 +438,20 @@ static void PaintWindowThread(void *)
|
||||||
_draw_thread->Exit();
|
_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 LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
static uint32 keycode = 0;
|
static uint32 keycode = 0;
|
||||||
|
@ -592,31 +612,50 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(UNICODE)
|
/* IMEs and other input methods sometimes send a WM_CHAR without a WM_KEYDOWN,
|
||||||
wchar_t w;
|
* clear the keycode so a previous WM_KEYDOWN doesn't become 'stuck'. */
|
||||||
int len = MultiByteToWideChar(_codepage, 0, (char*)&charcode, 1, &w, 1);
|
uint cur_keycode = keycode;
|
||||||
charcode = len == 1 ? w : 0;
|
keycode = 0;
|
||||||
#endif /* UNICODE */
|
|
||||||
|
|
||||||
/* No matter the keyboard layout, we will map the '~' to the console */
|
return HandleCharMsg(cur_keycode, charcode);
|
||||||
scancode = scancode == 41 ? (int)WKC_BACKQUOTE : keycode;
|
|
||||||
HandleKeypress(GB(charcode, 0, 16) | (scancode << 16));
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_KEYDOWN: {
|
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. */
|
/* Silently drop all messages handled by WM_CHAR. */
|
||||||
MSG msg;
|
MSG msg;
|
||||||
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleKeypress(0 | (keycode << 16));
|
uint charcode = MapVirtualKey(wParam, MAPVK_VK_TO_CHAR);
|
||||||
return 0;
|
|
||||||
|
/* 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
|
case WM_SYSKEYDOWN: // user presses F10 or Alt, both activating the title-menu
|
||||||
|
@ -979,7 +1018,8 @@ void VideoDriver_Win32::MainLoop()
|
||||||
|
|
||||||
while (PeekMessage(&mesg, NULL, 0, 0, PM_REMOVE)) {
|
while (PeekMessage(&mesg, NULL, 0, 0, PM_REMOVE)) {
|
||||||
InteractiveRandom(); // randomness
|
InteractiveRandom(); // randomness
|
||||||
TranslateMessage(&mesg);
|
/* Convert key messages to char messages if we want text input. */
|
||||||
|
if (EditBoxInGlobalFocus()) TranslateMessage(&mesg);
|
||||||
DispatchMessage(&mesg);
|
DispatchMessage(&mesg);
|
||||||
}
|
}
|
||||||
if (_exit_game) return;
|
if (_exit_game) return;
|
||||||
|
|
|
@ -350,7 +350,7 @@ void SetFocusedWindow(Window *w)
|
||||||
* has a edit box as focused widget, or if a console is focused.
|
* 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
|
* @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;
|
if (_focused_window == NULL) return false;
|
||||||
|
|
||||||
|
|
|
@ -52,4 +52,6 @@ void SetWindowClassesDirty(WindowClass cls);
|
||||||
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force = true);
|
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force = true);
|
||||||
void DeleteWindowByClass(WindowClass cls);
|
void DeleteWindowByClass(WindowClass cls);
|
||||||
|
|
||||||
|
bool EditBoxInGlobalFocus();
|
||||||
|
|
||||||
#endif /* WINDOW_FUNC_H */
|
#endif /* WINDOW_FUNC_H */
|
||||||
|
|
Loading…
Reference in New Issue