From e68eef433b75dd6b5b016d17737226a0411a2f73 Mon Sep 17 00:00:00 2001 From: temportalflux Date: Sat, 6 Jun 2026 19:14:58 -0400 Subject: [PATCH] make layout information private --- crates/gpui_elements/src/input/paint.rs | 4 +-- crates/gpui_elements/src/input/state.rs | 34 +++++++++++++------ .../src/input/state_input_handler.rs | 6 ++-- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/crates/gpui_elements/src/input/paint.rs b/crates/gpui_elements/src/input/paint.rs index e9f0c09523..3d706fce83 100644 --- a/crates/gpui_elements/src/input/paint.rs +++ b/crates/gpui_elements/src/input/paint.rs @@ -192,7 +192,7 @@ impl InputStateSnapshot { let selected_range = input_state.selected_range().clone(); let marked_range = input_state.marked_range().cloned(); let cursor_position = input_state.cursor_position(); - let logical_lines = input_state.logical_lines.clone(); + let logical_lines = input_state.lines().clone(); let scroll_distance = input_state.distance_from_top(); let line_height = input_state.line_height(); let layout_axis = input_state.layout_style().axis(); @@ -296,7 +296,7 @@ impl<'app> PaintContext<'app> { let content_size = match axis { gpui::Axis::Horizontal => { let state = input.read(cx); - let line = state.logical_lines.first(); + let line = state.lines().first(); let line = line.and_then(|l| l.wrapped_line.as_ref()); line.map(|w| w.width()).unwrap_or(px(0.)) } diff --git a/crates/gpui_elements/src/input/state.rs b/crates/gpui_elements/src/input/state.rs index 84f9481ce7..fd0bbc5392 100644 --- a/crates/gpui_elements/src/input/state.rs +++ b/crates/gpui_elements/src/input/state.rs @@ -55,9 +55,9 @@ pub struct InputState { marked_range: Option>, // refreshed each update by the element, for conveinent access in mutations and painting - pub(super) layout_data: InputLayoutData, + layout_data: InputLayoutData, /// A reinterpretation of `content` as wrapped lines with layout information. Regenerated when content changes or the layout changes during element painting. - pub(super) logical_lines: Vec, + logical_lines: Vec, /// Tracks whether we were focused on the last update. was_focused: bool, @@ -204,13 +204,13 @@ impl InputState { pub fn set_content(&mut self, content: impl AsRef, cx: &mut Context) { let content = self.layout_style.sanitize_content(content.as_ref()); self.content = content.to_string().into(); + self.cached_utf16_len = None; self.selected_range = 0..0; self.selection_direction = NavigationDirection::Forward; self.marked_range = None; - self.layout_data.dirty = true; self.history_undo_stack.clear(); self.history_redo_stack.clear(); - self.cached_utf16_len = None; + self.mark_layout_dirty(); self.pause_cursor_blink(cx); cx.emit(InputStateEvent::TextChanged); cx.notify(); @@ -356,7 +356,8 @@ impl InputState { self.selected_range = range.start + text_to_insert.len()..range.start + text_to_insert.len(); self.marked_range.take(); - self.layout_data.dirty = true; + self.mark_layout_dirty(); + self.pause_cursor_blink(cx); cx.emit(InputStateEvent::TextChanged); cx.notify(); @@ -379,10 +380,11 @@ impl InputState { let redo_entry = entry.apply_undo(&mut self.content); self.history_redo_stack.push(redo_entry); + self.cached_utf16_len = None; self.selected_range = selected_range; self.selection_direction = selection_direction; - self.layout_data.dirty = true; - self.cached_utf16_len = None; + self.mark_layout_dirty(); + self.scroll_to_cursor(); cx.emit(InputStateEvent::Undo); cx.notify(); @@ -399,8 +401,10 @@ impl InputState { self.selection_direction = NavigationDirection::Forward; self.history_undo_stack.push(undo_entry); - self.layout_data.dirty = true; + self.cached_utf16_len = None; + self.mark_layout_dirty(); + self.scroll_to_cursor(); cx.emit(InputStateEvent::Redo); cx.notify(); @@ -423,8 +427,9 @@ impl InputState { // Restore selection state self.selected_range = selected_range; self.selection_direction = selection_direction; - self.layout_data.dirty = true; self.cached_utf16_len = None; + self.mark_layout_dirty(); + self.scroll_to_cursor(); cx.emit(InputStateEvent::Undo); cx.notify(); @@ -443,8 +448,9 @@ impl InputState { self.selection_direction = NavigationDirection::Forward; self.history_undo_stack.push(undo_entry); - self.layout_data.dirty = true; self.cached_utf16_len = None; + self.mark_layout_dirty(); + self.scroll_to_cursor(); cx.emit(InputStateEvent::Redo); cx.notify(); @@ -838,6 +844,10 @@ impl InputState { self.layout_data.line_height } + pub(super) fn lines(&self) -> &Vec { + &self.logical_lines + } + pub(super) fn set_marked_range(&mut self, range: Option>) { self.marked_range = range; } @@ -1047,6 +1057,10 @@ impl InputState { } } + pub(super) fn mark_layout_dirty(&mut self) { + self.layout_data.dirty = true; + } + pub(super) fn apply_layout_update(&mut self, layout_data: InputLayoutData, window: &Window) { let dirty = self.layout_data.dirty || self.layout_data.wrap_width != layout_data.wrap_width diff --git a/crates/gpui_elements/src/input/state_input_handler.rs b/crates/gpui_elements/src/input/state_input_handler.rs index 855772916f..b181b78f88 100644 --- a/crates/gpui_elements/src/input/state_input_handler.rs +++ b/crates/gpui_elements/src/input/state_input_handler.rs @@ -72,7 +72,7 @@ impl EntityInputHandler for super::InputState { range.start + text_to_insert.len()..range.start + text_to_insert.len(), ); self.set_marked_range(None); - self.layout_data.dirty = true; + self.mark_layout_dirty(); self.pause_cursor_blink(cx); cx.emit(InputStateEvent::TextChanged); @@ -111,8 +111,8 @@ impl EntityInputHandler for super::InputState { range.start + text_to_insert.len()..range.start + text_to_insert.len() }) }); + self.mark_layout_dirty(); - self.layout_data.dirty = true; cx.emit(InputStateEvent::TextChanged); cx.notify(); } @@ -126,7 +126,7 @@ impl EntityInputHandler for super::InputState { ) -> Option> { let range = self.utf_range_16to8(&range_utf16); - for line in &self.logical_lines { + for line in self.lines() { if line.text_range.is_empty() { if range.start == line.text_range.start { return Some(Bounds::from_corners(