windows: Fix IME candidate window not appearing at cursor position (#46079)

Release Notes:

- Fixed some IME popups and the emoji picker not appearing at the cursor
position on windows
This commit is contained in:
Lukas Wirth authored and GitHub committed 2026-01-05 15:48:52 +00:00
1 parent ea90a72e2e
commit 1e0c4f85ce
3 files changed
+35 -22

No files matched your search

+21 -19
View File
@@ -586,30 +586,32 @@ impl WindowsWindowInner {
}
fn handle_ime_position(&self, handle: HWND) -> Option<isize> {
if let Some(caret_position) = self.retrieve_caret_position() {
self.update_ime_position(handle, caret_position);
}
Some(0)
}
pub(crate) fn update_ime_position(&self, handle: HWND, caret_position: POINT) {
unsafe {
let ctx = ImmGetContext(handle);
if ctx.is_invalid() {
return;
}
let Some(caret_position) = self.retrieve_caret_position() else {
return Some(0);
let config = COMPOSITIONFORM {
dwStyle: CFS_POINT,
ptCurrentPos: caret_position,
..Default::default()
};
{
let config = COMPOSITIONFORM {
dwStyle: CFS_POINT,
ptCurrentPos: caret_position,
..Default::default()
};
ImmSetCompositionWindow(ctx, &config as _).ok().log_err();
}
{
let config = CANDIDATEFORM {
dwStyle: CFS_CANDIDATEPOS,
ptCurrentPos: caret_position,
..Default::default()
};
ImmSetCandidateWindow(ctx, &config as _).ok().log_err();
}
ImmSetCompositionWindow(ctx, &config).ok().log_err();
let config = CANDIDATEFORM {
dwStyle: CFS_CANDIDATEPOS,
ptCurrentPos: caret_position,
..Default::default()
};
ImmSetCandidateWindow(ctx, &config).ok().log_err();
ImmReleaseContext(handle, ctx).ok().log_err();
Some(0)
}
}
+9 -2
View File
@@ -920,8 +920,15 @@ impl PlatformWindow for WindowsWindow {
self.state.renderer.borrow().gpu_specs().log_err()
}
fn update_ime_position(&self, _bounds: Bounds<Pixels>) {
// There is no such thing on Windows.
fn update_ime_position(&self, bounds: Bounds<Pixels>) {
let scale_factor = self.state.scale_factor.get();
let caret_position = POINT {
x: (bounds.origin.x.0 * scale_factor) as i32,
y: (bounds.origin.y.0 * scale_factor) as i32
+ ((bounds.size.height.0 * scale_factor) as i32 / 2),
};
self.0.update_ime_position(self.0.hwnd, caret_position);
}
}
+5 -1
View File
@@ -1124,7 +1124,11 @@ impl Buffer {
syntax_map,
reparse: None,
non_text_state_update_count: 0,
sync_parse_timeout: Some(Duration::from_millis(1)),
sync_parse_timeout: if cfg!(any(test, feature = "test-support")) {
Some(Duration::from_millis(10))
} else {
Some(Duration::from_millis(1))
},
parse_status: watch::channel(ParseStatus::Idle),
autoindent_requests: Default::default(),
wait_for_autoindent_txs: Default::default(),