Skip to content

fix(diffs): keep the native selection in sync with keyboard selections - #1245

Open
lucasmeijer wants to merge 1 commit into
pierrecomputer:mainfrom
lucasmeijer:fix/editor-native-selection-sync
Open

lucasmeijer wants to merge 1 commit into
pierrecomputer:mainfrom
lucasmeijer:fix/editor-native-selection-sync

Conversation

@lucasmeijer

Copy link
Copy Markdown

Hi, human Lucas here. I'm a very happy user of diffs!

Please consider this pull request a bug report that contains:

description of the problem i have as a user

  • a small repro case
  • a video of said repro case
  • code changes that when I apply them in my product, solves the problem for me
  • a video of the repro case working with the patch applied.
  • I'm not claiming the fix is done in the best possible way, I'm merely adding it as a data point that in this shape it solves the problem for me. You probably have better ideas on how to solve it.

Everything above here is me talking, everything below here is AI generated description. the patch is ai generated, the videos are screen recordings my agent made. I hope you find this a useful shape of a bug fix / contribution. Thanks for Diffs! Bye, Lucas.

Description

Two related bugs with keyboard selections in the editor. Both come from the editor collapsing the window (native) selection to the anchor while it shows a range.

  1. Shift+Arrow collapses the selection to its anchor, intermittently. Drag-select a few lines, then press Shift+Down. Often the selection collapses back to the anchor and then grows again from there. After each keyboard step, #focus(anchor) writes a collapsed window selection at the anchor. The resulting selectionchange is ignored only for two animation frames. Chromium sometimes delivers it later, and the handler then reads it as the user placing the caret at the anchor. While Shift is held, #selectionStart is set, so that path accepts it. On current main this happens in most runs. In our headless-shell runs it collapsed in 36 of 48 tries.
  2. Clicking the anchor of a keyboard selection doesn't clear it. Click, press Shift+Down a few times, then click exactly where the selection started. The selection stays. The window selection is already collapsed at that point, so the click doesn't change it and no selectionchange fires.

Before (current main):

selection-before.mp4

After (this PR):

selection-after.mp4

Fix, in editor.ts:

  • #focus() takes an optional selection, and the public focus() and #scrollToPrimaryCaret() pass the primary selection. The window selection now mirrors the whole range instead of a collapsed caret at the anchor. That fixes (2), and it also means a late echo carries the same bounds as the editor's selection.
  • #setWindowSelection() remembers the boundary points it applied (#windowSelectionEcho). The selectionchange handler ignores one event reporting exactly those points, however late it arrives. Any pointer press clears the remembered range, so real clicks always count. That fixes (1).
  • The composed-range read moved into a small getComposedWindowRange() helper. Behavior is unchanged, including the ShadowRoot.getSelection() fallback.

Motivation & Context

In the AgentsInTheCloud file editor, selecting text with Shift+Arrows looked random: sometimes it worked, sometimes it snapped back to where the selection started.

Type of changes

  • Bug fix (non-breaking change which fixes an issue)
  • Refactoring (non-breaking change)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would change existing functionality)
  • Documentation update

Checklist

  • I have read the contributing guidelines
  • My code follows the code style of the project (moon run root:lint)
  • My code is formatted properly (moon run root:format)
  • I have updated the documentation accordingly (if applicable)
  • I have added tests to cover my changes (if applicable)
  • All new and existing tests pass (moonx diffs:test)

Tests added (code-view-selection.pw.ts + fixture code-view-selection.html):

  • a late selectionchange keeps a Shift+Down selection: drag-select, hold Shift and press Down, wait out the ignore window, then dispatch a selectionchange. This simulates the late delivery deterministically. It fails on main, where the selection collapses to the anchor, and passes with the fix.
  • clicking the anchor of a keyboard selection clears it: it fails on main and passes with the fix.

diffs:test has 3 failures in CodeView item collapsed state in my environment. They fail the same way on main without this change. In the e2e suite, code-view-annotations (3 tests) and edit.pw.ts › programmatic refocus… also fail identically on main locally.

How was AI used in generating this PR

An AI coding agent (Claude) reproduced and root-caused the issue and wrote the change, the tests, the fixture and this description. It also recorded the before/after videos and wrote their captions. The videos are real screen recordings of the fixture in headless Chromium. I reviewed the change and the reasoning above.

Related issues

None that I could find.

@vercel

vercel Bot commented Oct 29, 2026

Copy link
Copy Markdown

@lucasmeijer is attempting to deploy a commit to the Pierre Computer Company Team on Vercel.

A member of the Team first needs to authorize it.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T09:47:14.610070Z 9e36acc PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9e36acc649

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +2181 to +2182
if (echo !== undefined && isSameRange(echo, composedRange)) {
return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not swallow a Shift-click on the selection anchor

When a ranged selection is active and the user Shift-clicks its anchor, the pointerdown path in #listenContentElement first calls #setWindowSelection with a collapsed range at that anchor. The browser's final range is the same collapsed range, so this branch classifies the only resulting selectionchange as an echo and returns before the #isContentMouseDown && #shiftKeyPressed / extendSelection path can collapse the editor selection; the old range therefore stays selected. Do not consume this echo during the Shift-click gesture (the existing extendSelection tests explicitly expect anchor clicks to collapse).

Useful? React with 👍 / 👎.

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant