Preview: screenshot timeout with rAF loops + click coordinate offset on Windows DPI scaling
Two bugs in Claude Preview (MCP)
---
Bug 1: preview_screenshot times out when requestAnimationFrame loop is active
Environment: Any web app with a persistent requestAnimationFrame loop (e.g. animation libraries like react-native-reanimated)
Behavior: preview_screenshot hangs for 30s then returns:
preview_screenshot timed out after 30s. The preview window may be stuck
Root cause: The screenshot tool appears to wait for the page to reach an "idle" state (no pending requestAnimationFrame callbacks). Libraries that run a continuous animation loop via requestAnimationFrame prevent the page from ever becoming idle.
Workaround:
// via preview_eval before each screenshot
window.requestAnimationFrame = () => 0;
Suggested fix: Use a timeout-based idle heuristic rather than waiting for zero pending rAF callbacks, or provide an option to force-capture regardless of idle state.
---
Bug 2: preview_click coordinates are offset by Windows display scaling factor
Environment: Windows with display scaling > 100% (reproduced at 125%, DPI=120)
Behavior: preview_click returns "Successfully clicked" but the actual click lands at the wrong position. All clicks are offset by the display scaling factor.
Evidence:
- Target element has bounding rect center at CSS pixel
(285, 416) - Actual
pointerdownevent landed at(356, 520)— exactly 1.25x the expected coordinates 356 / 285 = 1.249,520 / 416 = 1.250— matchesDPI / 96 = 120 / 96 = 1.25
Root cause: The tool computes the element center using CSS pixel coordinates (from getBoundingClientRect or equivalent) but dispatches the CDP Input.dispatchMouseEvent using those raw values as device coordinates, without dividing by the display scale factor.
Suggested fix: Account for window.devicePixelRatio or the OS-level DPI scaling when converting CSS coordinates to CDP input coordinates.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗