windows: Support emoji inputs (#10125)
To work properly, needs #10119 to be merged. https://github.com/zed-industries/zed/assets/14981363/2bb0c51b-6c70-4b29-8baa-302fb4fb9e89 Release Notes: - N/A
This commit is contained in:
@@ -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<String> {
|
||||
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::<u16>(
|
||||
buffer.as_mut_ptr().cast::<u16>(),
|
||||
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<isize> {
|
||||
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<String> {
|
||||
let src = [wparam.0 as u16];
|
||||
let Ok(first_char) = char::decode_utf16(src).collect::<Vec<_>>()[0] else {
|
||||
return None;
|
||||
};
|
||||
Some(first_char.to_string())
|
||||
}
|
||||
|
||||
fn handle_ime_char(&self, wparam: WPARAM) -> Option<isize> {
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user