src/events/WindowCaptureEventsSpecs.md
One-shot window screenshots for thumbnails and Preview. macOS 26+ captures through ScreenCaptureKit
(WindowCaptureScreenshots); older versions capture through the private CGSHWCaptureWindowList
(WindowCaptureScreenshotsPrivateApi), because SCK is unreliable there (macOS 14 crashes inside Apple's
code, macOS 15 leaks).
Two public one-shot APIs exist, each broken differently:
captureSampleBuffer returns a zero-copy IOSurface, but Apple implements each call by creating and
destroying a capture stream. On some machines that churn leaks WindowServer memory until macOS
force-logs-out the session (#5786). Each call also emits WindowServer Creating sharing context events
and Screenshots via streams are inefficient warnings.captureScreenshot (new in macOS 26) creates no per-call stream (zero of the above events), but:
SCStreamError -3811 for a fullscreen window whose Space is not frontmost (it succeeds
when that Space is frontmost, and for minimized, other-Space, partially-offscreen, and tabbed windows);CGImage instead of an IOSurface, which measurably slows full-resolution captures
of large windows (relevant to Preview; at thumbnail sizes it is slightly faster than
captureSampleBuffer).Routing: captureScreenshot for every window, except fullscreen windows and, when any shortcut's
effective settings enable preview-selected-window, all windows (full-resolution path) — those use
captureSampleBuffer.
isFullscreen is snapshotted on the main thread when the burst is built, so
a window mid-transition can be routed to captureScreenshot and fail with -3811. Deliberately no
fallback/retry: the thumbnail keeps its previous contents and the next refresh re-routes. A fallback
would silently reintroduce stream churn and hide new failure modes.captureSampleBuffer (Preferences.anyShortcutUsesPreview).updateScreenCaptureDidStart events per capture) and cost systemstatusd the same CPU (measured
within 2%). Switching APIs fixes the WindowServer leak, not the per-capture attribution overhead.| per run (~355 captures) | captureSampleBuffer | captureScreenshot |
|---|---|---|
| WindowServer sharing contexts / warnings | ~355 / ~355 | 0 / 0 |
| capture latency mean (thumbnail sizes) | 706 ms | 644 ms |
| capture latency mean (full-res, ≤5.2 MP) | 709 ms | 664 ms |
| replayd CPU | 2.0 s | 1.8 s |
| systemstatusd CPU | 4.8 s | 4.7 s |
| failures | 0 | only fullscreen-on-inactive-Space, always -3811 |