fix(panels): anchor caret blink on per-frame search inputs

The component/icon/font/image search boxes rebuild their TextInputState
from the filter String each frame; with_text left the blink anchor at 0,
so the caret could be in its hidden phase right after a keystroke. touch()
the rebuilt state with now_ms so the caret stays steadily visible while
the box is focused (codex review follow-up).
This commit is contained in:
Kayshen-X 2026-06-20 23:26:21 +08:00
parent 81f6d126ab
commit d41cf9c61f
4 changed files with 16 additions and 3 deletions

View file

@ -520,6 +520,10 @@ impl<'a> ComponentBrowserPanel<'a> {
let mut search_input = jian_core::text_input::TextInputState::with_text(
self.state.editor_ui.component_browser_search.clone(),
);
// Anchor the blink to this frame so the caret stays visible while the
// box is focused (the buffer is rebuilt each frame, so there is no
// per-keystroke anchor to thread).
search_input.touch(self.now_ms);
if self.state.editor_ui.component_browser_select_all && !search_input.text().is_empty() {
search_input.select_all();
}

View file

@ -346,6 +346,9 @@ impl<'a> IconPickerPanel<'a> {
let mut search_input = jian_core::text_input::TextInputState::with_text(
self.state.editor_ui.icon_picker_search.clone(),
);
// Anchor the blink to this frame so the caret stays visible while the
// box is focused (the buffer is rebuilt each frame).
search_input.touch(self.now_ms);
if self.state.editor_ui.icon_picker_select_all && !search_input.text().is_empty() {
search_input.select_all();
}

View file

@ -109,7 +109,9 @@ pub fn paint_search_popover(
cx.backend
.stroke_round_rect(layout.input, 5.0, theme.border, 1.0);
let baseline = layout.input.origin.y + layout.input.size.y / 2.0 + 4.0;
let search_input = jian_core::text_input::TextInputState::with_text(state.search_query.clone());
let mut search_input =
jian_core::text_input::TextInputState::with_text(state.search_query.clone());
search_input.touch(now_ms); // keep the caret visible while the popover is open
crate::widgets::property_panel_text_input::paint_text_input_view(
cx,
theme,
@ -321,8 +323,9 @@ pub fn paint_generate_popover(
// rebuilt from the prompt String each frame; the open popover
// owns the keyboard, so it reads as focused.
let line = Rect::xywh(ta.origin.x, ta.origin.y, ta.size.x, 26.0);
let generate_input =
let mut generate_input =
jian_core::text_input::TextInputState::with_text(state.generate_prompt.clone());
generate_input.touch(now_ms); // keep the caret visible while open
crate::widgets::property_panel_text_input::paint_text_input_view(
cx,
theme,

View file

@ -345,7 +345,10 @@ pub fn paint_font_picker(
// Draft + placeholder + caret render through the unified jian TextInputView
// (family-aware caret, no hand-rolled drift). The buffer is rebuilt from the
// search String each frame; the open picker reads as focused.
let search_input = jian_core::text_input::TextInputState::with_text(search.to_string());
let mut search_input = jian_core::text_input::TextInputState::with_text(search.to_string());
// Anchor the blink to this frame so the caret stays visible while the
// picker is open (the buffer is rebuilt each frame).
search_input.touch(now_ms);
crate::widgets::property_panel_text_input::paint_text_input_view(
cx,
theme,