CNA-BUG-134: Inside a letterbox bar, Mouse::GetState reports the raw window coordinate on renderers whose transform declines the point

CNA snapshot 009d40f5  ·  Known Issues › Current bugs  ·  source links pinned to 009d40f5

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

EasyGL (every GL-family identity), OPENGL4, SDL_GPU, WEBGPU, SVG_DOM, HTML_DOM and GDI decline points outside the presented rectangle, and Mouse and the input bridge then report the untransformed window coordinate, which can look like a valid game position. The presented rectangle is smaller than the window only under CnaPresentationMode::Letterbox (the default mode) when the window aspect differs from the back buffer's; Overscan, Stretch, NativeBackBuffer and FixedHeightDynamicWidth present a rectangle that covers the whole window, so only a pointer outside the window itself is declined there.

Identifier
CNA-BUG-134
Category
Bug
Subsystem
Input
Status
Open
Verified against
CNA 009d40f5 (009d40f5dd085c4e674d3479675fac84b12b3e0a)
Severity
Low (a triage suggestion, not a project priority)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
Mouse::GetState() and touch positions under a letterboxed or overscanned presentation

Expected behaviour

A mouse position should always be in one coordinate space. Vulkan, Canvas and Direct2D return the logical coordinate even outside the presented rectangle (negative or beyond the back buffer), so a game can tell the pointer is in a bar.

Actual behaviour at TARGET

WindowToLogical in GlPresentationSurfaceState.hpp (EasyGL, OPENGL4) computes the logical coordinates and then returns windowX >= clientViewportX && ..., i.e. false inside a Letterbox bar; SDL_GPU, WebGPU, SVG_DOM, HTML_DOM and GDI (MapGdiWindowToLogical) do the same. On false, window_to_logical in Mouse.cpp leaves the output at the raw window coordinate, and to_logical_position in SdlInputBridge.cpp returns it too. With a 100-pixel left bar, a pointer at window x = 50 is reported as game x = 50, inside the playfield. Under Overscan the presented rectangle extends past every window edge, so in-window points always map.

Source locations

Evidence

Checked by reading every renderer's TransformWindowToLogical at 009d40f5; not executed.

Independent re-verification: Read every TransformWindowToLogical override and every RegisterForWindow call at 009d40f5; not executed. DIRECTX11, DIRECTX12 and METAL also decline outside the rectangle but never register for their window (CNA-BUG-133), so input never consults them; VULKAN, Canvas, Direct2D, FNA3D, the SDL renderer and FREEDIRECT return true without a range check.

Focused reproduction

No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.

Current tests

MouseInputTests.cpp tests the transform inside the presented rectangle only (CoordinateTransformPreservesLetterboxOffsetAndInverse).

Regression test

A test renderer that declines points in a bar, asserting that Mouse::GetState reports an out-of-range logical coordinate (or a documented clamp), never the raw one.

Blast radius

Letterboxed or overscanned windows on the six renderers named; clicks in the bars land on game coordinates.

Workaround

Ignore mouse input while the window aspect differs from the back buffer, or compute the bars in the game.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

User guide
Input: mouse
Known issues
Bug index