Skip to content

Keep mouse and paste modes synchronized after terminal resets - #1276

Merged
nedtwigg merged 2 commits into
mainfrom
audit-mouse-mode-sync
Oct 21, 2026
Merged

nedtwigg merged 2 commits into
mainfrom
audit-mouse-mode-sync

Conversation

@nedtwigg

Copy link
Copy Markdown
Member

After a terminal program sends a hard reset, xterm clears mouse reporting and bracketed paste but Dormouse's cached modes stayed enabled. That left mouse overrides and program-owned selections active, and could wrap the next paste in markers the program no longer expected. A soft reset similarly left the paste cache stale.

Read xterm's resolved modes from its parsed-output event. This removes the two escape handlers and queued microtasks, covers reset sequences automatically, and preserves xterm's distinction that a soft reset leaves mouse tracking active.

Validation: real-xterm hard- and soft-reset regressions failed before the fix. All 206 targeted mouse, clipboard, replay, and lifecycle tests pass; library TypeScript, spec lint, Markdown lint, and diff checks pass. The observer tests now exercise all four mouse modes, paste enable/disable, reset cleanup, and disposal through real parsing.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: 437a919
Status: ✅  Deploy successful!
Preview URL: https://232dbf5d.mouseterm.pages.dev
Branch Preview URL: https://audit-mouse-mode-sync.mouseterm.pages.dev

View logs

dormouse-bot
dormouse-bot previously approved these changes Oct 21, 2026
it.each([[9, 'x10'], [1000, 'vt200'], [1002, 'drag'], [1003, 'any']] as const)(
'tracks mouse mode %i through real xterm parsing', async (mode, expected) => {
const { terminal } = setup();
await write(terminal, `[?${mode}h[?2004h`);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Raw ESC bytes here are invisible in editors and make gh pr diff refuse to print without --allow-escape-sequences; the other tests in this file spell them \x1b.

Suggested change
await write(terminal, `[?${mode}h[?2004h`);
await write(terminal, `\x1b[?${mode}h\x1b[?2004h`);

const { terminal } = setup();
await write(terminal, `[?${mode}h[?2004h`);
expect(getMouseSelectionState('a')).toMatchObject({ mouseReporting: expected, bracketedPaste: true });
await write(terminal, `[?${mode}l[?2004l`);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
await write(terminal, `[?${mode}l[?2004l`);
await write(terminal, `\x1b[?${mode}l\x1b[?2004l`);

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Build & Test is red because of this change. standalone/src/workspace-move.test.ts mocks @xterm/xterm with its own Terminal class, which has no onWriteParsed. Every adoption and resume path in that file now throws TypeError: terminal.onWriteParsed is not a function when it reaches attachMouseModeObserver, and 12 of its tests fail (job log). The website test: Failed line in the same log is only pnpm's recursive run aborting after the first package failed.

The mock in lib/src/lib/xterm-test-mock.ts already got the fix. The standalone mock needs the same stub next to its onRender():

onWriteParsed(): { dispose: () => void } { return { dispose: () => {} }; }

The observer no longer uses that mock's parser = { registerCsiHandler: ... } stub, so it can go too. The file isn't in this PR's diff, so I can't attach a suggestion to it. I can push the fix if you'd like.

@dormouse-bot
dormouse-bot dismissed their stale review October 21, 2026 07:11

CI failed — standalone xterm mock lacks onWriteParsed

@nedtwigg
nedtwigg merged commit 198f984 into main Oct 21, 2026
15 checks passed
@nedtwigg
nedtwigg deleted the audit-mouse-mode-sync branch October 21, 2026 15:45
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.

2 participants