Skip to content

fix(web): returning to the window keeps a text selection - #31710

Open
juliusmarminge wants to merge 4 commits into
mainfrom
fix/issue-31698
Open

juliusmarminge wants to merge 4 commits into
mainfrom
fix/issue-31698

Conversation

@juliusmarminge

Copy link
Copy Markdown
Member

Problem

Text selected in a reply was lost after switching to another window and back. Steps: select text in an assistant reply, focus another window, then return to T3 Code. Once the window regained focus, the selection was gone. People use that selection as a bookmark while they look something up elsewhere.

Change

When the window regains focus, ChatView moves the caret into the composer. Focusing the composer moves the document selection into the editor, which wipes the user's selection. shouldRefocusComposerOnWindowFocus now also takes the current selection. It returns false when that selection is not collapsed, so the composer is not refocused. With no selection, or a collapsed one, the existing rules run unchanged and returning to the window still lands the caret in the composer.

Scope and approval

Fixes #31698

Verification

Focused test, apps/web/src/components/ChatView.logic.browser.test.ts, run with vp test run src/components/ChatView.logic.browser.test.ts:

  • New: "leaves a text selection in the timeline alone on window return". It makes a real triple-click selection in a focusable timeline element. On main it fails with refocusing the composer would clear the selected reply text: expected true to be false; with this change it passes.
  • Existing: "keeps keyboard focus on a sidebar row on window return, but not a clicked row" still passes.
  • vp run check:changed passes (format, lint, knip, typecheck, tests, react compiler).

Runtime check on the Linux desktop app: Electron dev build on Xvfb, fresh database, and one thread with a three-paragraph reply. Input was real X mouse input and real focus changes to another X window, using the same driver on both sides. The transcript reads getSelection().toString() and document.activeElement after each step.

Selection in the reply Before, main 25b5329 After, 8e3d768
Drag across "Steel bridges are also easy to recycle a" kept on blur; "" after return, caret in composer kept on blur; kept after return
Double-click "bridges" kept on blur; "" after return, caret in composer kept on blur; kept after return
Triple-click the paragraph kept on blur; "" after return, caret in composer kept on blur; kept after return
No selection (control) caret in composer after return caret in composer after return (unchanged)

Still screenshots of these runs were taken but are not attached. The transcript above records what each step produced.

Not checked:

  • cannot-verify macos. In the report's video on macOS, the highlight disappears when the other window takes focus. On Linux the selection survives blur, with the grey inactive highlight painted, and was lost only on return. This change fixes the loss on return. Whether macOS also drops or hides the selection at blur still needs checking on a Mac.
  • Windows was not run.

AI-assisted; verified with the tests and tools listed above.

🤖 Generated with Claude Code

juliusmarminge and others added 2 commits November 5, 2026 22:16
Adds a failing browser test: with reply text selected in the timeline,
shouldRefocusComposerOnWindowFocus still asks to refocus the composer,
which clears the selection when the window regains focus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refocusing the composer on window focus moved the document selection into
the editor, wiping text the user had selected in a reply. Skip the refocus
while the document holds a non-collapsed selection; otherwise the existing
refocus rules are unchanged.

Fixes #31698

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Nov 5, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Nov 5, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 2297ace

Macroscope's review found this PR approvable — Returning to the window now preserves selected text instead of automatically focusing the composer. The change is limited to focus handling and retains existing focus safeguards.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The window-focus handler now passes the document selection to the composer-refocus check. If text is selected, the check returns false. Browser tests cover selected timeline text and existing sidebar and workspace focus cases.

Changes: Window focus and text selection

Layer / File(s) Summary
Selection-aware composer refocus
apps/web/src/components/ChatView.logic.ts, apps/web/src/components/ChatView.tsx, apps/web/src/components/ChatView.logic.browser.test.ts
shouldRefocusComposerOnWindowFocus now accepts the current selection and returns false when it is non-collapsed. The window-focus handler passes document.getSelection(). Browser tests cover selected timeline text and sidebar and workspace focus checks.

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix · Severity of issue fixed: Low

Possibly related PRs

Suggested reviewers: t3dotgg

Merge Risk: Minimal · up to 2297a

Selected timeline text should remain selected when the window regains focus. No actionable merge-blocking issue is established.

Pre-merge checks: Passed 3 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Linked Issues check Inconclusive Issue #31698 requires selected AI output text to remain selected after the app loses and regains focus. ChatView now passes document.getSelection() to shouldRefocusComposerOnWindowFocus, which s… Verify on macOS whether the selection remains non-collapsed after the window loses focus and remains selected after focus returns.
Passed Passed checks: 3 passed

Check name Status Explanation
Title check Passed The title clearly describes the main change: preserving text selections when returning to the window.
Description check Passed The description covers the problem, change, linked issue, and focused verification in detail. It also states that macOS and Windows were not checked. The required before-and-after screenshots for the …
Out of Scope Changes check Passed The changes are limited to composer-refocus logic in ChatView, its focused browser tests, and the related comment. These changes support issue #31698. No unrelated changes appear in the whole-PR dif…
Full details: Description check

Explanation

The description covers the problem, change, linked issue, and focused verification in detail. It also states that macOS and Windows were not checked. The required before-and-after screenshots for the UI change were taken but are not attached.

Full details: Out of Scope Changes check

Explanation

The changes are limited to composer-refocus logic in ChatView, its focused browser tests, and the related comment. These changes support issue #31698. No unrelated changes appear in the whole-PR diff.

Full details: Linked Issues check

Explanation

Issue #31698 requires selected AI output text to remain selected after the app loses and regains focus. ChatView now passes document.getSelection() to shouldRefocusComposerOnWindowFocus, which skips composer refocus for a non-collapsed selection. The browser test covers that behavior, and the PR reports a successful Linux runtime check. The issue reports macOS, but the PR states that macOS selection behavior during blur was not checked. If macOS clears or collapses the selection on blur, this change cannot preserve it. The evidence does not establish the required behavior on the reported platform.

Resolution

Verify on macOS whether the selection remains non-collapsed after the window loses focus and remains selected after focus returns.

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 8e3d768 and 2297ace.

Files selected for processing: 3

  • apps/web/src/components/ChatView.logic.browser.test.ts
  • apps/web/src/components/ChatView.logic.ts
  • apps/web/src/components/ChatView.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.

@shivamhwp

Copy link
Copy Markdown
Collaborator

[GPT-6.1 Sol][Codex] on behalf of shivam.

Read-only findings from the issue-watch investigation at main 25b53299b75d4d8d1d0667ad47e9cfed3749776e: the window-focus callback in ChatView.tsx permits composer focus when the active element is BODY. That reaches Tiptap's focus/caret assignment and can replace a selection in the reply. I found no unconditional blur handler clearing that selection; the Cite toolbar's blur handler only dismisses its own state. This agrees with your fix.

No device reproduction or runtime tests completed in this thread, and no screenshots or recordings were produced. The macOS reproduction job was still queued, so I cancelled it on takeover. The reporter's recording shows the highlight disappearing while T3 is inactive, without returning to T3; it does not establish whether the DOM range survives blur. macOS inactive painting remains unverified by this investigation. No code changes or pushes were made.

@juliusmarminge juliusmarminge added bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed labels Nov 5, 2026
@macroscopeapp
macroscopeapp Bot dismissed their stale review November 10, 2026 21:34

Dismissing prior approval to re-evaluate 2297ace

Copy link
Copy Markdown
Member Author

Evidence

Select assistant reply text by dragging, Alt+Tab to another application, then Alt+Tab back without clicking the conversation. Repeat with double-click, triple-click, and no selection.

Both recordings: real Linux Electron app under headless-desktop, Xvfb/Openbox, 1280×800, light theme, identical synthetic replay replies in fresh isolated databases.

Before After
9cd7a04797 2297ace725
Before recording After recording
All three selections collapse on return; composer receives focus. All three selections remain selected on return.
No-selection control focuses composer. No-selection control focuses composer.

Interaction driver, desktop RPC seed, thread seed. Base observations, head observations.

AI-assisted; verified with the tests and tools listed above.

Not shown:

  • macOS inactive-highlight and selection-range behavior was not verified because this environment runs Linux.
  • Standalone browsers, Windows desktop, and existing autofocus exceptions for inputs, dialogs, terminals, and keyboard-focused regions were not exercised in this desktop reproduction.

This branch has not been deployed

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

Labels

bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Text selection is lost when window loses focus

2 participants