Skip to content

gpui-base: Add TextSelection for window-level text selection - #2730

Merged
huacnlee merged 31 commits into
mainfrom
text-selection-base-architecture
Aug 16, 2026
Merged

huacnlee merged 31 commits into
mainfrom
text-selection-base-architecture

Conversation

@huacnlee

@huacnlee huacnlee commented Aug 15, 2026 •

Copy link
Copy Markdown
Member

Summary

  • add renderer-neutral, window-level text selection to gpui-base
  • migrate TextView to the shared selection engine while preserving rich-text parsing, source copy, virtualization, focus, and scrolling behavior
  • isolate background, Dialog, and Sheet selection with opaque per-window scopes
  • keep the existing gpui-component selection methods as deprecated forwarding shims
  • add a selectable-text showcase, integration documentation, and lifecycle/compatibility coverage
  • correct the release workflow to publish the renamed gpui-base crate

API design

The public API separates window coordination from renderer-owned state:

  • TextSelectionLayer is mounted once per window and retains the window selection state and pointer handlers.
  • TextSelection provides window-level query and control operations: selected_text, has_selection, clear, end, and activate_scope.
  • TextSelectionHandle is retained by each selectable participant and owns its snapshot, callbacks, local-selection state, and plain-text projection.
  • TextSelectionRegistration reports per-frame geometry, document order, scroll offset, and scope.
  • TextSelectionRun and TextSelectionProjection provide UTF-8-safe range projection for ordinary laid-out text.
  • TextSelectionSnapshot, TextSelectionEndpoint, TextSelectionCoverage, and TextSelectionContentKey support custom and virtualized renderers without exposing internal window state.
  • ElementExt::text_selection_scope marks modal or otherwise isolated subtrees.

The engine keeps participant identity stable, uses explicit logical ordering instead of paint or map order, stores endpoints in participant-relative content coordinates, expires registrations by frame, and keeps window registries weak so closed windows release their selection state.

Compatibility

Existing TextView behavior remains covered for click/drag and Shift extension, multi-click word/line selection, cross-participant copy, plain/source formats, virtualized blocks, focus, auto-scroll, drag-and-drop suppression, layout changes, modal scopes, and multi-window cleanup.

Applications using gpui_component::Root receive the TextSelectionLayer automatically. The former Root and WindowExt selection methods remain available as deprecated synchronous forwards to the single base-owned state.

Verification

  • cargo test -p gpui-base text_selection — 43 passed
  • cargo test --workspace --all-targets — passed
  • cargo check --workspace --all-targets — passed
  • cargo clippy --workspace --all-targets -- --deny warnings — passed
  • cargo fmt --all -- --check — passed
  • git diff --check — passed
  • bun run build in website — passed

Status

Kept as draft for maintainer API review.

@huacnlee huacnlee changed the title feat: move window text selection into gpui-base feat(base): add window-level text selection Aug 16, 2026
@huacnlee huacnlee changed the title feat(base): add window-level text selection gpui-base: Add TextSelection for window-level text selection Aug 16, 2026
@huacnlee
huacnlee marked this pull request as ready for review August 16, 2026 04:59
huacnlee and others added 27 commits August 16, 2026 13:09
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
huacnlee and others added 4 commits August 16, 2026 13:09
@huacnlee
huacnlee force-pushed the text-selection-base-architecture branch from f3db395 to 99a9af2 Compare August 16, 2026 05:09
@huacnlee
huacnlee merged commit fd3bc2b into main Aug 16, 2026
4 checks passed
@huacnlee
huacnlee deleted the text-selection-base-architecture branch August 16, 2026 05:25
Tryanks added a commit to Tryanks/tcode that referenced this pull request Aug 17, 2026
…tion

Bump gpui-component to the merge of longbridge/gpui-kit#2730 and
delete the markdown module's hand-rolled window selection engine
(window_selection.rs, selection.rs, per-char hit-testing, multi-click
machinery). Markdown views now participate natively: a per-state
TextSelectionHandle registers geometry each frame, inline paint projects
selections through TextSelectionRun, and the shell mounts
gpui_base::TextSelectionLayer. Copy composes virtualized blocks through
snapshot coverage and content keys.

Behavior fixes over the old engine and the initial port:
- dragging below the text no longer flickers between line-end and
  column-aligned selection (the buggy per-char geometry is gone)
- auto-scroll triggers at the clip viewport edge, not the anchor
  message's own bounds, driven by a participant-side loop
- an empty context menu no longer opens as a bare strip on right-click
  over non-link text; menu_popover dismisses empty menus for all callers

Also adapts input/composer callers to the bumped dependency's direct
InputBaseState API.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant