Skip to content

Composer: bring an off-screen caret into view immediately after editing long pasted text #356

Description

@Tryanks

Status: OPEN — temporarily blocked on an upstream gpui-kit issue. The automatically opened upstream PR was closed pending complete root-cause analysis and review. This is an investigation record, not a fix/completion claim or a release gate.

Investigation progress — 2026-09-08

Native observation. In an isolated signed Tcode app on macOS 26.6.2 arm64, paste 100 newline-separated lines ending in END, keep the viewport at the top, then type X. The baseline displayed approximately lines 000–007; the edit moved only one line and left ENDX offscreen. A long wrapped sample (wrapped pasted content repeated 200 times, then END) also reproduced the problem. With the experimental candidate, the first edit revealed ENDX at normal and narrow widths in light/dark themes. Manual scrolling remained at the chosen position until another edit; native insertion, same-length replacement and deletion then revealed the caret while retaining the expected text.

Owner and findings. The tested baseline was gpui-base 9d9bd9bfa9b4c3af25475078458b3e3c7abd2981; ownership is InputBaseState<TextareaMode>/InputBase, specifically crates/base/src/input/base/element.rs and state.rs, rather than chat autoscroll. On that baseline, cursor-follow adjusted vertical scrolling by one line per layout after an edit. A same-offset replacement could also bypass reveal because the cached selected range remained equal. These mechanisms were reproduced in the actual input owner; their applicability to newer upstream implementations has not been fully reviewed.

Candidate and red/green evidence. AI-authored candidate 94ae00c59ac6e59e858882989c5c12e69863c569 directly targets the caret scroll position and invalidates the selected-range cache after accepted replacement/composition. The real InputView/clipboard-Paste regression failed without the fix (caret y=2575.95 outside viewport 0–400; scroll only −26 after editing). A first partial candidate still failed same-length replacement. The final experimental owner test passed across newline/wrapped samples at widths 720/320, insertion/replacement/deletion/IME marking and manual scrolling. The scoped input:: suite passed 153 tests, not the entire upstream suite. This count was rechecked in /tmp/tcode-interaction-published-input.log from a fresh clone of the published combined candidate.

Provenance and current disposition. The candidate was previously published to the user-owned fork; it is not unpublished. Combined experimental commit e12d6962f8b5b8807b7539e362608e79f55d73e1 also contains the separate #360 candidate. Upstream PR #3011 is closed; the proposal remains unreviewed and unaccepted as a fix. The temporary Tcode fork pin and candidate integration were withdrawn from #382. No durable candidate dependency pin or current-main fix was delivered for this issue. Local commits remain in /tmp/tcode-gpui-interactions; the verification clone is /tmp/tcode-gpui-published-verification.

Evidence limits / paused work. Native before/after screenshots exist only in the prior CUA transcript, not as independently retained issue-specific PNGs; the retained #354 PNGs do not evidence this bug. Native IME-picker behavior was not exercised (the actual composition handler was tested). Resizing was observed without oscillation, but there is no retained systematic resize trace. Baseline binary /tmp/tcode-interaction-before-bin and the original wrapper probe /tmp/tcode-input-regression-probe.rs remain. Upstream had since introduced multi-cursor layout/selection changes: a separate merge attempt in /tmp/tcode-gpui-caret-upstream has unresolved element.rs/state.rs conflicts and was explicitly stopped, with no resolution published. Current-upstream adaptation and complete root-cause review remain paused; no resubmission is being performed here.

Historical record — superseded and non-authoritative

The body below is preserved for historical reproduction/context only. Its former next-release requirement, acceptance checklist and other AI-authored constraints were explicitly withdrawn by the user and are not authoritative requirements or release gates. Statements that GUI reproduction had not yet occurred describe the earlier audit and are superseded by the dated investigation above.

Temporarily blocked on an upstream gpui-kit issue. The automatically opened upstream PR was closed pending complete root-cause analysis and review; a reviewed proposal will be submitted later.

Closed upstream proposal: longbridge/gpui-kit#3011

Next-release requirement (2026-09-08): This issue must be completed before the next release. The existing scope, diagnosis and acceptance criteria below remain in force.

Reported reproduction

  1. Paste text long enough to overflow the composer viewport.
  2. With the caret at the final character, leave or scroll the viewport at the top.
  3. Type one character, then continue typing.

Actual: each keystroke moves the viewport down only a small amount; the active caret remains out of view.

Expected: the first edit scrolls far enough to reveal the caret line, and subsequent edits keep it visible. Reading older text without editing should still allow independent scrolling.

Code context and investigation boundary

The composer uses TextareaState; tcode's input wrapper re-exports it from gpui_base and renders it through InputBase. Inspect the dependency's caret-reveal/layout behavior together with tcode's composer sizing and draft/paste selection updates. Do not assume that the application's chat autoscroll is the owner of text-input scrolling.

This is a user-reported behavior, not a GUI reproduction established by this audit. OS, app revision, input method and a minimal triggering text sample remain to be captured.

Acceptance criteria

  • One edit reveals a far-off caret after a long paste, both for newline-heavy text and visually wrapped long lines.
  • Caret visibility works after replacement, deletion and IME composition without disturbing text or selection.
  • Manual scrolling while not editing remains possible; resizing the composer does not cause oscillation.
  • Exercise the real input component at normal and narrow widths and record a before/after reproduction. Put any regression at the actual owner of caret visibility.

Code context

Reviewed against main at b4c549787da6 (2026-09-08).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions