Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 72bbc5d

Browse files
authored
Win32: Support Korean input (#24713)
This change fixes a bug in Korean input whereby WM_IME_COMPOSITION messages of type GCS_RESULTSTR were assumed to end composing mode. This change breaks out an additional handler for "commit composing text" events. In Japanese/Chinese IMEs, these events typically occur on selection of a candidate from the candidates list and are mostly synonymous with an "end composing" event. In Korean text input, there is no candidates list, but rather a character is built up as keypresses are handled, and committed as soon as the character is unambiguously complete; in other words, when either space/return is pressed or a keypress is received that cannot be interpreted as a modification of the character being composed and therefore must be the first keystroke of a new character. In these cases, we want to commit the previous character without ending the composition. To illustrate with an example: 1. User focuses on a text field and sets input mode to Hangul. 2. User presses 'ㄱ'. Composing region contains 'ㄱ'. 3. User presses 'ㅏ'. Composing region is updated to '가'. 4. User presses 'ㄴ'. Composing region is updated to '간'. 5. User presses 'ㅏ'. Result string '가' is committed. Composing region is updated to '나'. 6. User presses 'ㄷ'. Composing string is updated to '낟'. 7. User presses 'ㅏ'. Result string '나' is committed. Composing region is updated to '다'. 8. User presses space or enter. Result string '다' is committed. Composing is ended. On a non-Korean QWERTY keyboard the following key mappings serve to perform the above input: * r -> ㄱ * k -> ㅏ * s -> ㄴ * e -> ㄷ To support the above, we break out a separate "commit composing" method and commit on WM_IME_COMPOSITION events of type GCS_RESULTSTR and end composing on WM_IME_ENDCOMPOSITION events. Further, we eliminate the workaround in the GCS_RESULTSTR handler for continued composition on Chinese/Japanese IMEs now that we're no longer ending composition on that event type.
1 parent 83a776c commit 72bbc5d

14 files changed

+69
-9
lines changed

shell/platform/windows/flutter_window_win32.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ void FlutterWindowWin32::OnComposeBegin() {
176176
binding_handler_delegate_->OnComposeBegin();
177177
}
178178

179+
void FlutterWindowWin32::OnComposeCommit() {
180+
binding_handler_delegate_->OnComposeCommit();
181+
}
182+
179183
void FlutterWindowWin32::OnComposeEnd() {
180184
binding_handler_delegate_->OnComposeEnd();
181185
}

shell/platform/windows/flutter_window_win32.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ class FlutterWindowWin32 : public WindowWin32, public WindowBindingHandler {
6565
// |WindowWin32|
6666
void OnComposeBegin() override;
6767

68+
// |WindowWin32|
69+
void OnComposeCommit() override;
70+
6871
// |WindowWin32|
6972
void OnComposeEnd() override;
7073

shell/platform/windows/flutter_window_win32_unittests.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class SpyKeyboardKeyHandler : public KeyboardHandlerBase {
7878
MOCK_METHOD2(TextHook,
7979
void(FlutterWindowsView* window, const std::u16string& text));
8080
MOCK_METHOD0(ComposeBeginHook, void());
81+
MOCK_METHOD0(ComposeCommitHook, void());
8182
MOCK_METHOD0(ComposeEndHook, void());
8283
MOCK_METHOD2(ComposeChangeHook,
8384
void(const std::u16string& text, int cursor_pos));
@@ -112,6 +113,7 @@ class SpyTextInputPlugin : public KeyboardHandlerBase,
112113
MOCK_METHOD2(TextHook,
113114
void(FlutterWindowsView* window, const std::u16string& text));
114115
MOCK_METHOD0(ComposeBeginHook, void());
116+
MOCK_METHOD0(ComposeCommitHook, void());
115117
MOCK_METHOD0(ComposeEndHook, void());
116118
MOCK_METHOD2(ComposeChangeHook,
117119
void(const std::u16string& text, int cursor_pos));

shell/platform/windows/flutter_windows_view.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ void FlutterWindowsView::OnComposeBegin() {
210210
SendComposeBegin();
211211
}
212212

213+
void FlutterWindowsView::OnComposeCommit() {
214+
SendComposeCommit();
215+
}
216+
213217
void FlutterWindowsView::OnComposeEnd() {
214218
SendComposeEnd();
215219
}
@@ -329,6 +333,12 @@ void FlutterWindowsView::SendComposeBegin() {
329333
}
330334
}
331335

336+
void FlutterWindowsView::SendComposeCommit() {
337+
for (const auto& handler : keyboard_handlers_) {
338+
handler->ComposeCommitHook();
339+
}
340+
}
341+
332342
void FlutterWindowsView::SendComposeEnd() {
333343
for (const auto& handler : keyboard_handlers_) {
334344
handler->ComposeEndHook();

shell/platform/windows/flutter_windows_view.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate,
111111
// |WindowBindingHandlerDelegate|
112112
void OnComposeBegin() override;
113113

114+
// |WindowBindingHandlerDelegate|
115+
void OnComposeCommit() override;
116+
114117
// |WindowBindingHandlerDelegate|
115118
void OnComposeEnd() override;
116119

@@ -202,6 +205,13 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate,
202205
// input method such as in CJK text input.
203206
void SendComposeBegin();
204207

208+
// Reports an IME compose commit event.
209+
//
210+
// Triggered when the user commits the current composing text while using a
211+
// multi-step input method such as in CJK text input. Composing continues with
212+
// the next keypress.
213+
void SendComposeCommit();
214+
205215
// Reports an IME compose end event.
206216
//
207217
// Triggered when the user commits the composing text while using a multi-step

shell/platform/windows/keyboard_handler_base.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,17 @@ class KeyboardHandlerBase {
4545
// input method such as in CJK text input.
4646
virtual void ComposeBeginHook() = 0;
4747

48+
// Handler for IME compose commit events.
49+
//
50+
// Triggered when the user commits the current composing text while using a
51+
// multi-step input method such as in CJK text input. Composing continues with
52+
// the next keypress.
53+
virtual void ComposeCommitHook() = 0;
54+
4855
// Handler for IME compose end events.
4956
//
50-
// Triggered when the user commits the composing text while using a multi-step
51-
// input method such as in CJK text input.
57+
// Triggered when the user ends editing composing text while using a
58+
// multi-step input method such as in CJK text input.
5259
virtual void ComposeEndHook() = 0;
5360

5461
// Handler for IME compose change events.

shell/platform/windows/keyboard_key_handler.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ void KeyboardKeyHandler::ComposeBeginHook() {
181181
// Ignore.
182182
}
183183

184+
void KeyboardKeyHandler::ComposeCommitHook() {
185+
// Ignore.
186+
}
187+
184188
void KeyboardKeyHandler::ComposeEndHook() {
185189
// Ignore.
186190
}

shell/platform/windows/keyboard_key_handler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ class KeyboardKeyHandler : public KeyboardHandlerBase {
107107
// |KeyboardHandlerBase|
108108
void ComposeBeginHook() override;
109109

110+
// |KeyboardHandlerBase|
111+
void ComposeCommitHook() override;
112+
110113
// |KeyboardHandlerBase|
111114
void ComposeEndHook() override;
112115

shell/platform/windows/testing/mock_window_win32.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class MockWin32Window : public WindowWin32 {
4242
MOCK_METHOD6(OnKey, bool(int, int, int, char32_t, bool, bool));
4343
MOCK_METHOD2(OnScroll, void(double, double));
4444
MOCK_METHOD0(OnComposeBegin, void());
45+
MOCK_METHOD0(OnComposeCommit, void());
4546
MOCK_METHOD0(OnComposeEnd, void());
4647
MOCK_METHOD2(OnComposeChange, void(const std::u16string&, int));
4748
MOCK_METHOD4(DefaultWindowProc, LRESULT(HWND, UINT, WPARAM, LPARAM));

shell/platform/windows/text_input_plugin.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,14 @@ void TextInputPlugin::ComposeBeginHook() {
111111
SendStateUpdate(*active_model_);
112112
}
113113

114+
void TextInputPlugin::ComposeCommitHook() {
115+
if (active_model_ == nullptr) {
116+
return;
117+
}
118+
active_model_->CommitComposing();
119+
SendStateUpdate(*active_model_);
120+
}
121+
114122
void TextInputPlugin::ComposeEndHook() {
115123
if (active_model_ == nullptr) {
116124
return;

0 commit comments

Comments
 (0)