Forms · An IME composition restarts the caret's blink, as every edit does, and logs its ranges (#7)

This commit is contained in:
ZacharyZhang-NY committed 2026-10-05 00:35:46 -04:00
1 parent 1f297c7801
commit 2a18e9d0b3
4 files changed
+45 -1

No files matched your search

+30
View File
@@ -389,3 +389,33 @@ fn only_a_focused_field_blinks(cx: &mut TestAppContext) {
cx.run_until_parked();
assert!(redraws.get() > 2, "a focused one blinks");
}
#[gpui::test]
fn a_composition_shows_the_caret_as_typing_does(cx: &mut TestAppContext) {
let (fields, cx) = open(1, false, cx);
let field = fields[0].clone();
cx.update(|window, _| window.activate_window());
focus(&field, cx);
cx.run_until_parked();
let caret = |cx: &mut VisualTestContext| field.read_with(cx, |input, _| input.caret_on());
let blink_off = |cx: &mut VisualTestContext| {
cx.executor()
.advance_clock(std::time::Duration::from_millis(530));
cx.run_until_parked();
};
blink_off(cx);
assert!(!caret(cx), "the caret blinks off");
cx.update(|window, cx| {
field.update(cx, |input, cx| {
input.replace_text_in_range(None, "a", window, cx)
})
});
assert!(caret(cx), "typing shows the caret");
blink_off(cx);
cx.update(|window, cx| {
field.update(cx, |input, cx| {
input.replace_and_mark_text_in_range(None, "n", None, window, cx)
})
});
assert!(caret(cx), "a composition shows it too");
}
+7 -1
View File
@@ -94,6 +94,12 @@ impl EntityInputHandler for TextInput {
if self.disabled {
return;
}
log::debug!(
"text input {:?}: compose {range_utf16:?} selecting {selected_utf16:?} marked {:?} selection {:?}",
cx.entity_id(),
self.marked,
self.selection
);
let range = range_utf16
.map(|range| self.range_from_utf16(&range))
.or(self.marked.clone())
@@ -114,7 +120,7 @@ impl EntityInputHandler for TextInput {
None => range.start + text.len()..range.start + text.len(),
};
self.reversed = false;
cx.notify();
self.restart_blink(cx);
}
fn bounds_for_range(