diff --git a/crates/gpui/src/platform/windows/window.rs b/crates/gpui/src/platform/windows/window.rs index 5885a74b1582ca63fffb3d0a5eb291d6b7b079db..2cc6b06eed3d87c756ba090953b59da77f7de42f 100644 --- a/crates/gpui/src/platform/windows/window.rs +++ b/crates/gpui/src/platform/windows/window.rs @@ -284,7 +284,6 @@ impl WindowsWindowInner { WM_CHAR => self.handle_char_msg(msg, wparam, lparam), WM_IME_STARTCOMPOSITION => self.handle_ime_position(), WM_IME_COMPOSITION => self.handle_ime_composition(lparam), - WM_IME_CHAR => self.handle_ime_char(wparam), WM_SETCURSOR => self.handle_set_cursor(lparam), _ => None, }; @@ -782,7 +781,6 @@ impl WindowsWindowInner { let string_len = ImmGetCompositionStringW(ctx, GCS_COMPSTR, None, 0); let result = if string_len >= 0 { let mut buffer = vec![0u8; string_len as usize + 2]; - // let mut buffer = [0u8; MAX_PATH as _]; ImmGetCompositionStringW( ctx, GCS_COMPSTR, @@ -812,6 +810,32 @@ impl WindowsWindowInner { } } + fn parse_ime_compostion_result(&self) -> Option { + unsafe { + let ctx = ImmGetContext(self.hwnd); + let string_len = ImmGetCompositionStringW(ctx, GCS_RESULTSTR, None, 0); + let result = if string_len >= 0 { + let mut buffer = vec![0u8; string_len as usize + 2]; + ImmGetCompositionStringW( + ctx, + GCS_RESULTSTR, + Some(buffer.as_mut_ptr() as _), + string_len as _, + ); + let wstring = std::slice::from_raw_parts::( + buffer.as_mut_ptr().cast::(), + string_len as usize / 2, + ); + let string = String::from_utf16_lossy(wstring); + Some(string) + } else { + None + }; + ImmReleaseContext(self.hwnd, ctx); + result + } + } + fn handle_ime_composition(&self, lparam: LPARAM) -> Option { let mut ime_input = None; if lparam.0 as u32 & GCS_COMPSTR.0 > 0 { @@ -840,31 +864,22 @@ impl WindowsWindowInner { input_handler.replace_and_mark_text_in_range(None, comp_string, Some(0..caret_pos)); self.input_handler.set(Some(input_handler)); } + if lparam.0 as u32 & GCS_RESULTSTR.0 > 0 { + let Some(comp_result) = self.parse_ime_compostion_result() else { + return None; + }; + let Some(mut input_handler) = self.input_handler.take() else { + return Some(1); + }; + input_handler.replace_text_in_range(None, &comp_result); + self.input_handler.set(Some(input_handler)); + self.invalidate_client_area(); + return Some(0); + } // currently, we don't care other stuff None } - fn parse_ime_char(&self, wparam: WPARAM) -> Option { - let src = [wparam.0 as u16]; - let Ok(first_char) = char::decode_utf16(src).collect::>()[0] else { - return None; - }; - Some(first_char.to_string()) - } - - fn handle_ime_char(&self, wparam: WPARAM) -> Option { - let Some(ime_char) = self.parse_ime_char(wparam) else { - return Some(1); - }; - let Some(mut input_handler) = self.input_handler.take() else { - return Some(1); - }; - input_handler.replace_text_in_range(None, &ime_char); - self.input_handler.set(Some(input_handler)); - self.invalidate_client_area(); - Some(0) - } - fn handle_drag_drop(&self, input: PlatformInput) { let mut callbacks = self.callbacks.borrow_mut(); let Some(ref mut func) = callbacks.input else {