Add IME underline, I-beam cursor, and horizontal scroll to Input

This commit is contained in:
2026-10-29 15:59:42 +07:00
parent b57547ab8c
commit 2ecde30ae2
3 changed files with 150 additions and 22 deletions
+47 -2
View File
@@ -1,6 +1,7 @@
use gpui::{
Entity, KeyBinding, Modifiers, MouseButton, MouseDownEvent, MouseUpEvent, ParentElement as _,
Render, Styled as _, TestAppContext, VisualTestContext, Window, div, point, px,
Entity, EntityInputHandler as _, KeyBinding, Modifiers, MouseButton, MouseDownEvent,
MouseUpEvent, ParentElement as _, Render, ScrollDelta, ScrollEvent, Styled as _,
TestAppContext, VisualTestContext, Window, div, point, px,
};
use gpui_native_core::input::{
INPUT_CONTEXT, Input, InputBindings, InputState, InputStateEvent, Submit, bind_input_keys,
@@ -302,6 +303,50 @@ fn caret_blinks_while_focused_and_holds_solid_while_typing() {
assert!(!caret_unfocused);
}
#[test]
fn horizontal_scroll_follows_the_caret_and_wheels_back() {
let text = "a".repeat(300);
let (_cx, state, mut visual) = input_window(&text, false);
focus(&mut visual, &state);
let draw = |visual: &mut VisualTestContext| {
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});
};
// The text index at the field's left edge, through the last paint.
let left_edge_index = |visual: &mut VisualTestContext| -> usize {
visual
.update(|window, cx| {
state.update(cx, |state, cx| {
state.character_index_for_point(point(px(2.), px(14.)), window, cx)
})
})
.unwrap_or(0)
};
// The caret starts at the end; the view scrolls to keep it in view, so
// the left edge shows a later character.
draw(&mut visual);
let scrolled_index = left_edge_index(&mut visual);
assert!(scrolled_index > 0, "left edge index: {scrolled_index}");
// Moving to the start scrolls the view back: the left edge is index 0.
visual.simulate_keystrokes("home");
draw(&mut visual);
assert_eq!(left_edge_index(&mut visual), 0);
// A wheel scroll pans the view right without moving the caret.
visual.simulate_event(ScrollEvent {
position: point(px(200.), px(20.)),
delta: ScrollDelta::Pixels(point(px(-20.), px(0.))),
..Default::default()
});
draw(&mut visual);
let panned_index = left_edge_index(&mut visual);
assert!(panned_index > 0, "left edge index: {panned_index}");
}
#[test]
fn read_only_blocks_undo_redo_but_set_value_still_writes() {
let (cx, state, mut visual) = input_window("", false);