Skip to content

Support SGR-Pixels mouse reporting (DECSET 1016), bump to 2.0.4 - #161

Merged
tomlm merged 4 commits into
mainfrom
tomlm/sgr-pixels-mouse
Oct 6, 2026
Merged

tomlm merged 4 commits into
mainfrom
tomlm/sgr-pixels-mouse

Conversation

@tomlm

@tomlm tomlm commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • CSI ? 1016 h/l selects/resets a new MouseEncoding.SGRPixels: SGR-format reports (CSI < b ; x ; y M/m) with 1-based pixel coordinates, matching xterm (EmitMousePosition adds 1 in both 1006 and 1016 modes). It's mutually exclusive with 1005/1006/1015.
  • DECRQM now answers set/reset for 1016 instead of "not recognised" (Ps=0), so apps that probe before switching see it as supported.
  • New Terminal.GenerateMouseEvent(button, x, y, pixelX, pixelY, eventType, modifiers) overload for hosts that know the pointer's pixel position. Other encodings ignore the pixels and still report cells.
  • The existing cell-only overload still works under 1016: it reports the clicked cell's top-left corner from CellWidthPixels/CellHeightPixels, so dividing by the CSI 16 t cell size lands back on that cell.
  • Bumps version to 2.0.4.

Tests

  • 1016 moved from the "not recognised" DECRQM theory to "untouched mode reports reset"; added a test for 1016 and 1006 replacing each other.
  • New encoding tests: pixel reports (press and release), the cell-only fallback, and the pixel overload under plain 1006.
  • Full suite: 2229 passed, 1 skipped.

Host follow-up (Avalonia.Terminal)

TerminalView.Mouse.cs should call the pixel overload. Its once-per-cell motion dedupe also needs to compare pixel positions when MouseEncoding == SGRPixels.

🤖 Generated with Claude Code

tomlm and others added 2 commits October 6, 2026 11:53
?1016 selects a fourth mouse encoding: SGR reports carrying 1-based pixel
coordinates instead of cells, as xterm does. DECRQM now answers set/reset
for 1016 instead of "not recognised".

A new GenerateMouseEvent overload takes the pointer's pixel position; the
cell-only overload reports the clicked cell's top-left corner from
CellWidthPixels/CellHeightPixels so existing hosts keep working.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The new tests embed raw ESC control bytes that should be replaced with escaped source representations.

Review effort: Balanced
Findings: 1 Low severity

Open (1)
What changed in this PR

Adds DECSET 1016 SGR-Pixels mouse reporting and releases it as version 2.0.4.

Changes:

  • Adds pixel-coordinate SGR event generation with a cell-based fallback.
  • Implements mode selection, reset, and DECRQM reporting.
  • Adds coverage for pixel reporting and encoding transitions.
File Description
src/​XTerm.NET/​XTerm.NET.csproj Bumps version to 2.0.4.
src/​XTerm.NET/​Terminal.cs Exposes the pixel-coordinate mouse overload.
src/​XTerm.NET/​InputHandler.Modes.cs Adds 1016 query/reset handling.
src/​XTerm.NET/​InputHandler.cs Enables SGR-Pixels mode.
src/​XTerm.NET/​Input/​MouseTracker.cs Generates pixel-coordinate reports and fallback coordinates.
src/​XTerm.NET/​Input/​MouseInput.cs Adds the SGR-Pixels encoding value.
src/​XTerm.NET.Tests/​RequestModeTests.cs Tests 1016 mode reporting and exclusivity.
src/​XTerm.NET.Tests/​MouseTrackingTests.cs Tests pixel reports and fallback behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

public void MouseEvent_SGRPixels_ReportsOneBasedPixelPosition()
{
var terminal = CreateTerminal();
terminal.Write("[?1000h[?1016h");
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Perf comparison — this change, against its base

3 run(s) of each side, alternating on one machine. Allocation is a count and is gated exactly. Time is a measurement, so its gate is derived from the spread this job just observed in itself rather than fixed in advance.

corpus bytes/char gen0/Mchar ns/char Δ time noise gate
scroll-ascii 0.00 → 0.00 0.00 → 0.00 3.54 → 3.54 -0.2% ±1% 4%
sgr-churn 0.00 → 0.00 0.00 → 0.00 8.91 → 8.90 -0.1% ±5% 15%
truecolor 0.00 → 0.00 0.00 → 0.00 9.16 → 9.10 -0.6% ±1% 4%
alt-redraw 0.00 → 0.00 0.00 → 0.00 13.57 → 13.60 +0.2% ±5% 16%
unicode 7.66 → 7.66 0.30 → 0.30 32.80 → 32.85 +0.2% ±4% 13%
flood 0.00 → 0.00 0.00 → 0.00 104.58 → 103.77 -0.8% ±2% 6%

Each corpus is gated at max(4%, 3 × its own noise). A wide noise column means this runner was busy and the timing half of the table should be read as advisory; the allocation half is exact either way.

assemblies measured
  • base: XTerm.NET 2.0.3.0 mvid:49f84c34-f27d-4cac-b5ec-43bdd387e050
  • head: XTerm.NET 2.0.4.0 mvid:f2608658-7693-4306-9a40-b279ada246b1

Perf comparison — cumulative, everything since 2.0.3

3 run(s) of each side, alternating on one machine. Allocation is a count and is gated exactly. Time is a measurement, so its gate is derived from the spread this job just observed in itself rather than fixed in advance.

corpus bytes/char gen0/Mchar ns/char Δ time noise gate
scroll-ascii 0.00 → 0.00 0.00 → 0.00 3.58 → 3.54 -1.1% ±2% 7%
sgr-churn 0.00 → 0.00 0.00 → 0.00 8.89 → 8.90 +0.2% ±3% 10%
truecolor 0.00 → 0.00 0.00 → 0.00 9.01 → 9.10 +1.1% ±6% 19%
alt-redraw 0.00 → 0.00 0.00 → 0.00 13.59 → 13.60 +0.0% ±4% 11%
unicode 7.66 → 7.66 0.30 → 0.30 33.89 → 32.85 -3.1% ±5% 15%
flood 0.00 → 0.00 0.00 → 0.00 104.82 → 103.77 -1.0% ±1% 5%

Each corpus is gated at max(5%, 3 × its own noise). A wide noise column means this runner was busy and the timing half of the table should be read as advisory; the allocation half is exact either way.

assemblies measured
  • base: XTerm.NET 2.0.3.0 mvid:9ba0ce98-0d1e-4424-8aa1-9ab012cdc07a
  • head: XTerm.NET 2.0.4.0 mvid:f2608658-7693-4306-9a40-b279ada246b1

tomlm and others added 2 commits October 6, 2026 12:01
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@tomlm
tomlm merged commit 23ab8fc into main Oct 6, 2026
4 checks passed
@tomlm
tomlm deleted the tomlm/sgr-pixels-mouse branch October 6, 2026 19:19
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