diff --git a/src/forms/tests/stale.rs b/src/forms/tests/stale.rs index d23fc59..07e7356 100644 --- a/src/forms/tests/stale.rs +++ b/src/forms/tests/stale.rs @@ -1,4 +1,4 @@ -use gpui::{AppContext, Context, IntoElement, Render, TestAppContext, Window}; +use gpui::{AppContext, Context, EntityInputHandler, IntoElement, Render, TestAppContext, Window}; use super::setup; use crate::forms::{TextInput, UnitInput}; @@ -45,3 +45,24 @@ fn a_unit_gone_from_its_list_keeps_the_field(cx: &mut TestAppContext) { cx.run_until_parked(); assert!(cx.debug_bounds("number-root").is_some()); } + +#[gpui::test] +fn an_ime_finds_its_composition_before_the_next_layout(cx: &mut TestAppContext) { + let (fields, cx) = super::open(1, false, cx); + let field = fields[0].clone(); + super::focus(&field, cx); + field.update(cx, |input, cx| input.set_text("abc", cx)); + cx.run_until_parked(); + let laid = field + .read_with(cx, |input, _| input.bounds_for(3)) + .expect("laid out"); + let asked = cx.update(|window, cx| { + field.update(cx, |input, cx| { + input.replace_and_mark_text_in_range(None, "n", None, window, cx); + let at = gpui::Bounds::new(laid.origin, gpui::size(gpui::px(200.), laid.size.height)); + input.bounds_for_range(3..4, at, window, cx) + }) + }); + let asked = asked.expect("the candidate box has a place"); + assert_eq!(asked.origin, laid.origin, "at the caret, on its line"); +} diff --git a/src/forms/text/ime.rs b/src/forms/text/ime.rs index 2d4706a..f5357f8 100644 --- a/src/forms/text/ime.rs +++ b/src/forms/text/ime.rs @@ -126,19 +126,13 @@ impl EntityInputHandler for TextInput { fn bounds_for_range( &mut self, range_utf16: Range, - bounds: Bounds, + _: Bounds, _: &mut Window, _: &mut Context, ) -> Option> { let range = self.range_from_utf16(&range_utf16); - let line_height = self.layout.as_ref()?.line_height; - let start = self.position_for(self.display_offset(range.start))?; - let end = self.position_for(self.display_offset(range.end))?; - let origin = bounds.origin - self.scroll; - Some(Bounds::from_corners( - origin + start, - origin + gpui::point(end.x, end.y + line_height), - )) + let (start, end) = (self.bounds_for(range.start)?, self.bounds_for(range.end)?); + Some(Bounds::from_corners(start.origin, end.bottom_left())) } fn character_index_for_point( diff --git a/tasks/github.md b/tasks/github.md index 09bd867..899f093 100644 --- a/tasks/github.md +++ b/tasks/github.md @@ -17,7 +17,7 @@ - [x] G10 CI: `cargo fmt` on the files the last commits left unformatted - [x] G11 Issue #7: a caret is a whole number of device pixels wide at a device pixel, so it never shows thin then thick; tested -- [ ] G12 Issue #7: an IME asks for its candidate box past the laid-out text; the box clamps to the last layout, as `bounds_for` does; tested +- [x] G12 Issue #7: an IME asks for its candidate box past the laid-out text; the box clamps to the last layout, as `bounds_for` does; tested - [ ] G13 Issue #12: a floating option list occludes, so the wheel scrolls the list and not the page under it; tested - [ ] G14 Issue #7: BlockEditor scrolls in its own `ScrollArea` with its scrollbar and keeps the caret in view as blocks are added; tested - [ ] G15 Issue #7: BlockEditor turns into Markdown and back; tested