input: Refactor window.focused_input by use better way to ensure update. (#809)

This commit is contained in:
Jason Lee 2025-04-22 19:34:41 +08:00 committed by GitHub
parent 373d97ddf0
commit a195795978
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 39 additions and 13 deletions

View file

@ -9,7 +9,7 @@ use gpui_component::{
button::{Button, ButtonVariant, ButtonVariants as _}, button::{Button, ButtonVariant, ButtonVariants as _},
h_flex, h_flex,
input::{InputEvent, TextInput}, input::{InputEvent, TextInput},
v_flex, FocusableCycle, Icon, IconName, Sizable, v_flex, ContextModal, FocusableCycle, Icon, IconName, Root, Sizable,
}; };
actions!(input_story, [Tab, TabPrev]); actions!(input_story, [Tab, TabPrev]);
@ -200,7 +200,7 @@ impl Focusable for InputStory {
} }
impl Render for InputStory { impl Render for InputStory {
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement { fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
v_flex() v_flex()
.key_context(CONTEXT) .key_context(CONTEXT)
.id("input-story") .id("input-story")
@ -239,6 +239,16 @@ impl Render for InputStory {
.max_w_md() .max_w_md()
.child(self.input_esc.clone()), .child(self.input_esc.clone()),
) )
.child(
section("Focused Input")
.max_w_md()
.whitespace_normal()
.overflow_hidden()
.child(div().child(format!(
"Value: {:?}",
window.focused_input(cx).map(|input| input.read(cx).text())
))),
)
.child( .child(
h_flex() h_flex()
.items_center() .items_center()

View file

@ -5,7 +5,7 @@ use gpui::{
}; };
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::ActiveTheme as _; use crate::{ActiveTheme as _, ContextModal as _, Root};
use super::TextInput; use super::TextInput;
@ -502,6 +502,31 @@ impl Element for TextElement {
cx, cx,
); );
// Set Root focused_input when self is focused
if focused {
let input_view = self.input.clone();
if Root::read(window, cx).focused_input.as_ref() != Some(&input_view) {
Root::update(window, cx, |root, _, cx| {
root.focused_input = Some(input_view);
cx.notify();
});
}
}
// And reset focused_input when next_frame start
window.on_next_frame({
let input_view = self.input.clone();
move |window, cx| {
if !focused && Root::read(window, cx).focused_input.as_ref() == Some(&input_view) {
Root::update(window, cx, |root, _, cx| {
root.focused_input = None;
cx.notify();
});
}
}
});
// Paint selections // Paint selections
if let Some(path) = prepaint.selection_path.take() { if let Some(path) = prepaint.selection_path.take() {
window.paint_path(path, cx.theme().selection); window.paint_path(path, cx.theme().selection);

View file

@ -1478,12 +1478,7 @@ impl TextInput {
self.focus_handle.is_focused(window) && self.blink_cursor.read(cx).visible() self.focus_handle.is_focused(window) && self.blink_cursor.read(cx).visible()
} }
fn on_focus(&mut self, window: &mut Window, cx: &mut Context<Self>) { fn on_focus(&mut self, _: &mut Window, cx: &mut Context<Self>) {
let input_entity = cx.entity();
Root::update(window, cx, |root, _, _| {
root.focused_input = Some(input_entity)
});
self.blink_cursor.update(cx, |cursor, cx| { self.blink_cursor.update(cx, |cursor, cx| {
cursor.start(cx); cursor.start(cx);
}); });
@ -1491,10 +1486,6 @@ impl TextInput {
} }
fn on_blur(&mut self, window: &mut Window, cx: &mut Context<Self>) { fn on_blur(&mut self, window: &mut Window, cx: &mut Context<Self>) {
Root::update(window, cx, |root, _, _| {
root.focused_input = None;
});
self.unselect(window, cx); self.unselect(window, cx);
self.blink_cursor.update(cx, |cursor, cx| { self.blink_cursor.update(cx, |cursor, cx| {
cursor.stop(cx); cursor.stop(cx);