LearnNewsExamplesServices
Frontmatter
id19585
titleSharedCanvas resize replaces the viewport pointer origin
stateClosed
labels
bugaicore
assigneesneo-gpt-emmy
createdAtOct 11, 2026, 3:52 AM
updatedAtOct 11, 2026, 4:15 AM
githubUrlhttps://github.com/neomjs/neo/issues/19585
authorneo-gpt-emmy
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtOct 11, 2026, 4:15 AM

SharedCanvas resize replaces the viewport pointer origin

neo-gpt-emmy
neo-gpt-emmy commented on Oct 11, 2026, 3:52 AM

Context

A browser witness at Engine 00b6f2aa6a placed a SharedCanvas at viewport (21,154), size 1038×799. After its resize notification, canvasRect instead held left:0, top:0. A click on a rendered target missed by the canvas's screen offset. Measuring the current DOM rectangle before converting that click restored the hit.

Triage decision: repair the shared coordinate contract, rather than retain a consumer-specific correction.

The Problem

onDomResize() passes data.contentRect to updateSize(), which caches the supplied rectangle. forwardPointer() then subtracts its origin from viewport clientX/clientY. ResizeObserver's content rectangle is relative to the element's padding origin, so it cannot serve as a viewport origin. Existing pointer tests start from an already-correct rectangle and omit this transition.

The Architectural Reality

Design authority: src/app/SharedCanvas.mjs#forwardPointer promises “the canvas-relative position”; updateSize says it caches “the bounding rect.” src/main/addon/ResizeObserver.mjs#createSyntheticEntry explicitly defines contentRect relative to the padding origin. ResizeObserver.dispatchResizeEvents already supplies data.rect from the observed element's viewport measurement. component.Base#getDomRect remains the initial/missing-size measurement path.

The App Worker host converts coordinates; the Canvas Worker consumes local coordinates. Renderer gestures and remote routing remain unchanged.

The Fix

Consume the resize payload's existing rect as the viewport pointer rectangle while retaining contentRect dimensions for renderer sizing, and cover resize → pointer forwarding in the existing test/playwright/unit/canvas/PointerInput.spec.mjs. Keep ordinary pointer forwarding synchronous; no DOM measurement per movement event.

Prescription checked: src/app/SharedCanvas.mjs — owns the concern. The independent read rejected replacing content-box dimensions with bounding-box dimensions. Its existing updateSize helper can accept the pointer rectangle separately, defaulting to the sizing rectangle for existing callers.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
SharedCanvas resize → canvasRect → forwardPointer SharedCanvas.mjs methods above; ResizeObserver.mjs contentRect contract Keep content-box dimensions and viewport pointer geometry separate after resize; forward local CSS coordinates and existing window/button/modifier facts Existing readiness and missing-rectangle guards Owning method JSDoc Red/green offset-resize unit control and browser pointer receipt

Decision Record impact

none; restore the existing coordinate contract.

Acceptance Criteria

  • After a resize whose contentRect origin is zero or padding-relative, pointer positions are relative to the canvas's current viewport origin.
  • Renderer size and devicePixelRatio delivery, window routing, and pointer facts remain intact.
  • A focused regression fails on the old source and passes after the fix; existing pointer and canvas lifecycle tests pass.
  • A browser witness at a nonzero canvas offset observes the corrected shared pointer payload after resize.

Out of Scope

New gestures, worker topology, new remote entry points, and generic position tracking without resize.

Avoided Traps

Do not change ResizeObserver's documented contentRect semantics, add per-mousemove DOM round trips, or hide the error in individual renderers.

Related and sweeps

#19173 / PR #19179 introduced the pointer transport; #9314 concerns resize-event routing. Live latest-20 open issues and latest-30 all-state A2A checked at 2026-10-11 01:51Z: no equivalent or overlapping claim. Own assignments: two open, neither this surface. Live SharedCanvas/open and canvas-pointer-resize searches found none. KB surfaced only related historical canvas issues. Three prior-art MC queries plus a final symptom query surfaced resize/canvas history, no decision covering this mismatch. No new .mjs file or Agent OS structure change.

Origin Session ID: 56e85f26-e03f-486f-8cd7-94db0602291c Retrieval Hint: SharedCanvas pointer position shifted after resize contentRect viewport origin

tobiu referenced in commit 5b958c3 - "fix(canvas): preserve pointer origin across resize (#19585) (#19586)" on Oct 11, 2026, 4:15 AM
tobiu closed this issue on Oct 11, 2026, 4:15 AM