diff options
author | Takahiro Shizuki <sntulix> | 2021-08-01 21:52:22 +0300 |
---|---|---|
committer | Harley Acheson <harley.acheson@gmail.com> | 2021-08-01 21:52:22 +0300 |
commit | 836aeebf70776791866c8cc82a0ca2ad7ffb8e4d (patch) | |
tree | d2d976c1d4b6b8951f514c2fbc08d7acd6b045b3 /intern/ghost/intern/GHOST_ImeWin32.cpp | |
parent | 79277986c299eaa3df9364e6d9f2b88d2b4f2dea (diff) |
IME Win32: Fix Duplicated Initial Character
When entering characters using IME on Windows, Japanese and Chinese
will both usually result in the first keystroke being duplicated. The
problem is that we are informed too late, after the first key is
pressed, that we are IME composing. This patch ensures we are entering
non-English characters using ImmGetConversionStatus() and then deals
with editing keys (like arrows and backspace) on a per-language basis.
see D11929 for more details.
Differential Revision: https://developer.blender.org/D11929
Reviewed by Brecht Van Lommel
Diffstat (limited to 'intern/ghost/intern/GHOST_ImeWin32.cpp')
-rw-r--r-- | intern/ghost/intern/GHOST_ImeWin32.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/intern/ghost/intern/GHOST_ImeWin32.cpp b/intern/ghost/intern/GHOST_ImeWin32.cpp index 112a266ae28..412f7e4276c 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.cpp +++ b/intern/ghost/intern/GHOST_ImeWin32.cpp @@ -34,6 +34,8 @@ GHOST_ImeWin32::GHOST_ImeWin32() : is_composing_(false), ime_status_(false), input_language_id_(LANG_USER_DEFAULT), + conversion_modes_(IME_CMODE_ALPHANUMERIC), + sentence_mode_(IME_SMODE_NONE), system_caret_(false), caret_rect_(-1, -1, 0, 0), is_first(true), @@ -59,6 +61,63 @@ bool GHOST_ImeWin32::SetInputLanguage() return ime_status_; } +WORD GHOST_ImeWin32::GetInputLanguage() +{ + return input_language_id_; +} + +void GHOST_ImeWin32::UpdateConversionStatus(HWND window_handle) +{ + HIMC imm_context = ::ImmGetContext(window_handle); + if (imm_context) { + if (::ImmGetOpenStatus(imm_context)) { + ::ImmGetConversionStatus(imm_context, &conversion_modes_, &sentence_mode_); + } + else { + conversion_modes_ = IME_CMODE_ALPHANUMERIC; + sentence_mode_ = IME_SMODE_NONE; + } + ::ImmReleaseContext(window_handle, imm_context); + } + else { + conversion_modes_ = IME_CMODE_ALPHANUMERIC; + sentence_mode_ = IME_SMODE_NONE; + } +} + +bool GHOST_ImeWin32::IsEnglishMode() +{ + return (conversion_modes_ & IME_CMODE_NOCONVERSION) || + !(conversion_modes_ & (IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE)); +} + +bool GHOST_ImeWin32::IsImeKeyEvent(char ascii) +{ + if (!(IsEnglishMode())) { + /* In Chinese, Japanese, Korena, all alpha keys are processed by IME. */ + if ((ascii >= 'A' && ascii <= 'Z') || (ascii >= 'a' && ascii <= 'z')) { + return true; + } + switch (PRIMARYLANGID(GetInputLanguage())) { + /* In Japanese, all symbolic characters are also processed by IME. */ + case LANG_JAPANESE: { + if (ascii >= ' ' && ascii <= '~') { + return true; + } + break; + } + /* In Chinese, some symbolic characters are also processed by IME. */ + case LANG_CHINESE: { + if (ascii && strchr("!\"$'(),.:;<>?[\\]^_`", ascii)) { + return true; + } + break; + } + } + } + return false; +} + void GHOST_ImeWin32::CreateImeWindow(HWND window_handle) { /** |