Skip to content

🐛 fix(dpad): blank the debug overlay on a non-finite focus rect - #9

Open
fkrhzbllh wants to merge 1 commit into
fluttercandies:mainfrom
fkrhzbllh:fix/debug-overlay-non-finite-rect
Open

fkrhzbllh wants to merge 1 commit into
fluttercandies:mainfrom
fkrhzbllh:fix/debug-overlay-non-finite-rect

Conversation

@fkrhzbllh

Copy link
Copy Markdown

What

debugOverlay: true can throw UnsupportedError: Infinity or NaN toInt once per frame, from _DpadDebugOverlayState.build.

The overlay rounds the focused node's rect for its w×h label and positions the outline with the same rect. That rect comes from DpadMarks.rectOf, which returns whatever the node's global transform maps to — and an ancestor transform can be non-finite for a frame. The framework's stretch-overscroll effect does exactly that while a fling is in flight, so the overlay's per-frame repaint reads a non-finite rect for a node that is still legitimately focused.

I hit it in a Flutter TV app whose D-pad audit runs as widget tests: overlay on (debugOverlay: !kReleaseMode), a synthetic fling overscrolls a list mid-sweep, and the overlay then threw once per frame on a route that was otherwise clean.

Fix

Two guards, so the inspector can never be the thing that takes a frame down:

  • DpadMarks.rectOf returns null for a non-finite rect. Non-finite geometry is not usable geometry, and every caller already treats null as "no rect yet" (?? _lastRect, continue, …).
  • _DpadDebugOverlayState.build also blanks the frame (SizedBox.shrink()) for a non-finite rect instead of rounding/positioning it.

Test

test/debug_overlay_test.dart focuses a node under a non-finite ancestor transform and asserts no exception across the overlay's per-frame repaints. Before the fix it fails with exactly:

Actual: UnsupportedError:<Unsupported operation: Infinity or NaN toInt>

flutter analyze and flutter test are clean on the branch (110 tests).

Happy to reshape this if you would rather have the guard in only one of the two places.

`_DpadDebugOverlayState.build` rounds the focused node's rect for its size
label and positions the outline with it. That rect comes from
`DpadMarks.rectOf`, which returns whatever the node's global transform maps
to — and an ancestor transform can go non-finite for a frame. The
framework's stretch-overscroll effect does exactly that while a fling is in
flight, so with `debugOverlay: true` the overlay then threw
`UnsupportedError: Infinity or NaN toInt` once per frame.

`rectOf` now returns null for non-finite geometry (every caller already
treats null as "no rect yet"), and the overlay blanks the frame instead of
rounding or positioning a non-finite rect: the inspector must never be what
takes a frame down.

`test/debug_overlay_test.dart` pins the regression — a focused node under a
non-finite transform, asserting no exception across the per-frame repaints.
It failed with the exact `Infinity or NaN toInt` before these changes.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

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