You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
text: expose selection and range geometry for TextView, Editor and Diff #3669
An application placing a floating toolbar beside selected text, or a clickable marker beside a saved range, needs visible range rectangles without changing selection.
In v0.8.0:
TextView exposes selected text and source ranges, but selection_points is crate-private.
Editor's range_to_bounds returns an endpoint bounding box, not visible wrapped-line fragments, and requires both endpoints to have layout.
Diff's selection handle is crate-private; line selection does not expose geometry.
Environment
GPUI: gpui-pre 0.3.9
GPUI Component: gpui-kit 0.8.0
Platform: macOS 27 (arm64)
Steps to Reproduce
Select several wrapped lines, then scroll the selection's first endpoint out of view. Inside an existing view callback:
let state = text_view.read(cx);// Entity<TextViewState>let source_range = state.selected_source_range();let text = state.selected_text();// Content is available, but no public query returns the visible// selection rectangles for positioning a toolbar.let state = editor.read(cx);// Entity<EditorState>let bounds = state.range_to_bounds(&state.selected_range());// An endpoint box cannot describe the remaining visible fragments.
Expected
Query visible rectangles for the current selection or an explicit range. A toolbar can follow wrapping and scrolling; a source marker can remain anchored after selection is cleared. Mouse and keyboard selections use the same API.
Actual
The public APIs provide content, source positions or endpoint bounds, but not clipped visual-line geometry. Pointer coordinates do not describe keyboard selections. An application would otherwise need to reconstruct component layout.
Suggested change
Expose a shared read-only geometry value, with private fields and accessors. Illustrative API:
implSelectionGeometry{pubfnline_bounds(&self) -> &[Bounds<Pixels>];pubfnfirst_visible_line(&self) -> Option<Bounds<Pixels>>;pubfnviewport(&self) -> Bounds<Pixels>;}// State methods on TextView, Editor and Diff:// selection_geometry(...) -> Option<SelectionGeometry>// range_geometry(range, ...) -> Result<Option<SelectionGeometry>, ...>
Use window coordinates and visible fragments only, preserving disjoint fragments and Diff side identity. TextView ranges can use rendered offsets, Editor buffer byte offsets, and Diff source coordinates. Document the frame phase in which both selection and geometry are committed; return unavailable for stale ranges or missing layout. This should not move selection, scroll, or focus. TextView/Editor support can precede Diff.
A related timing gap, in the same area as geometry:
In TextView, inline elements update their selected range during paint, while selected_text() and the source-range getters read the document. A getter called from a MouseUp handler, or from a defer scheduled there, can therefore still see the projection from the previous paint. The selection only becomes reliable after the next paint.
#3589 (included in v0.8.0) makes the Copy path refresh the projection synchronously. It does not give other callers a defined point at which the current selection is committed and safe to read.
When geometry is exposed, please also define when selection and geometry are committed, for example a selection-changed/committed notification or a documented post-paint query point. A consumer that places a toolbar beside the selection then doesn't have to guess the frame order.
Activity
suxiaoshao commentedon Oct 24, 2026
A related timing gap, in the same area as geometry:
In TextView, inline elements update their selected range during paint, while
selected_text()and the source-range getters read the document. A getter called from a MouseUp handler, or from adeferscheduled there, can therefore still see the projection from the previous paint. The selection only becomes reliable after the next paint.#3589 (included in v0.8.0) makes the Copy path refresh the projection synchronously. It does not give other callers a defined point at which the current selection is committed and safe to read.
When geometry is exposed, please also define when selection and geometry are committed, for example a selection-changed/committed notification or a documented post-paint query point. A consumer that places a toolbar beside the selection then doesn't have to guess the frame order.