NEW331092
Video disappears from off-Space ScreenCaptureKit captures of Safari/WKWebView; disabling occlusion detection prevents it
https://bugs.webkit.org/show_bug.cgi?id=331092
Summary Video disappears from off-Space ScreenCaptureKit captures of Safari/WKWebView...
Liudon
Reported 2026-11-11 04:23:54 PST

Created attachment 482283 [details]
WKWebView A: Default occlusion detection; recorded video disappears on an inactive Space and recovers on return.

Summary

A playing, local non-DRM HTML5 video disappears from an externally captured Safari/WKWebView window when the window is on another macOS Space. The recorded video region becomes blank/dark and recovers on return. Other window content can remain visible. We request investigation of the interaction between media visibility policy and external window capture.

Apple Feedback FB25368989 covers the Safari case. The following newer evidence isolates a visibility-dependent presentation path; it does not establish which component owns the compatibility fix.

Tested environment

  • macOS 26.6.2 (25G83), Apple Silicon.
  • Safari 26.6.2, bundle/WebKit build 21624.5.1.11.3.
  • Corresponding published WebKit tag: WebKit-7624.5.1.11.3, commit 26695efdefc6076049ec50713a2c4e54b90b4d47.
  • Local non-DRM H.264 moving frame-number video, capture-framecode-tag18251-300s.mp4 (6,738,711 bytes).
  • External recorder: Gecko frozen build 20261109030050, source f57315d6d2c0c4fc8195745ea979b02885555a0d; ScreenCaptureKit desktopIndependentWindow filter, 30 fps requested.
  • This recorder also runs a separate transparent Metal panel (“Pulse”) to improve off-Space frame supply. It was present in both comparisons; these results must not be described as a bare-SCStream-only experiment.

Reproduction

  1. Serve the attached HTML and JS together: python3 -m http.server 8877 --bind 127.0.0.1 --directory <fixture-directory>.
  2. Open http://127.0.0.1:8877/safari-canvas-preflight-v1.html?mode=control in a normal Safari window, or in the attached WKWebView host. Select the same local moving MP4. Use a file longer than 65 seconds.
  3. Use an external ScreenCaptureKit window recorder to capture this exact window. The measured runs used the Gecko build above; another recorder has not been validated as equivalent.
  4. Start playback/logging with button ①. After about five seconds, use button ② and manually switch to a different ordinary Space containing neither source nor recorder. Keep the display awake/unlocked; do not minimize, enter PiP, or enter native full screen.
  5. Remain away for about 25–30 seconds, return, use ③, then record another five seconds and stop. Use ④ to finalize page diagnostics.
  6. Inspect the recorded native video region across the away/return transition.

Expected: the selected window's playing video remains available to the active external capture, or a supported capture-aware mechanism is documented.

Actual: video content disappears while away and recovers on return.

Controlled observations

Test Result
Safari, no Canvas operation 27.476 seconds hidden; video region blank during away
Safari, one hidden-Canvas draw while still foreground, 439 ms before hidden Page remained hidden for 28.284 seconds, but original native video region kept updating
WKWebView, default occlusion detection Native window occluded and page hidden for 28.037 seconds; video region blank
Same WKWebView host, _setWindowOcclusionDetectionEnabled:false Native window still occluded for 38.082 seconds; page remained visible and recorded video kept updating

The private selector is used only as a diagnostic intervention inside our own WKWebView host, not proposed as a Safari or production recorder API. Both WKWebView runs use the control page with zero Canvas draws. For Safari's Canvas comparison, the Canvas is display:none, drawn exactly once without readback; it does not replace the visible video.

Runtime/source correlation

In the actual Safari baseline, view visibility changes to hidden, the media element reports visible=0, and the GPU/AVFoundation path receives setPageIsVisible(false). On return these states become true and the recording recovers. In the Canvas comparison the view still becomes hidden, but the corresponding media/backend false transition was not observed during the away interval.

The matching release implementation of platformSetVisible calls [m_videoLayer setHidden:!isVisible] when a video layer exists. Read-only disassembly of the installed WebCore in our own helper process confirms this implementation. We did not attach to Safari or directly read the historical player's final CALayer.hidden state. Newer main-branch attachment/detachment logic must not be substituted for this release implementation.

This supports visibility-driven suppression of video presentation. It does not show that all video sources, DRM content, or all OS/browser versions behave identically. Canvas persistence across source changes, seeking, and long recordings has not been established.

Requested investigation

Can external ScreenCaptureKit capture be coordinated with this visibility optimization so the selected window continues to provide video content without becoming foreground? Is a supported browser/platform signal available, or should this require a WebKit and ScreenCaptureKit integration change? We are not requesting permanent background rendering for all windows.

Related report

A separate report describes a similar external live-thumbnail use case: https://stackoverflow.com/questions/79949880/macos-26-keep-a-captured-windows-content-live-while-its-on-an-inactive-space . This is a symptom report, not independent confirmation of the mechanism.

Attachments
WKWebView A: Default occlusion detection; recorded video disappears on an inactive Space and recovers on return. (4.71 MB, video/mp4)
2026-11-11 04:23 PST, Liudon
no flags
WKWebView B: Occlusion detection disabled; recorded video keeps updating while the window remains occluded. (6.28 MB, video/mp4)
2026-11-11 04:51 PST, Liudon
no flags
WKWebView A log: Native window occlusion, page visibility and playback state with default detection. (156.23 KB, text/plain)
2026-11-11 04:52 PST, Liudon
no flags
WKWebView B log: Window remains occluded while the page stays visible with detection disabled. (1.18 MB, text/plain)
2026-11-11 04:54 PST, Liudon
no flags
Diagnostic WKWebView host source, including the private occlusion-detection toggle used for the A/B comparison. Requires repository build context. (6.62 KB, text/plain)
2026-11-11 04:55 PST, Liudon
no flags
HTML test page for local video playback and visibility logging. Use mode=control for the WKWebView A/B comparison. (3.58 KB, text/html)
2026-11-11 04:57 PST, Liudon
no flags
JavaScript required by the test page; records visibility transitions and supports the single-Canvas-draw experiment. (7.37 KB, text/javascript)
2026-11-11 04:58 PST, Liudon
no flags
Local non-DRM moving frame-number video used as the playback source in the reported tests. (6.43 MB, video/mp4)
2026-11-11 05:01 PST, Liudon
no flags
Safari A: No Canvas draws; recorded video region becomes blank while the page is on an inactive Space. (4.45 MB, video/mp4)
2026-11-11 05:08 PST, Liudon
no flags
Safari B: One hidden-Canvas draw before switching Spaces; the original video region keeps updating while the page is hidden. (4.74 MB, video/mp4)
2026-11-11 05:09 PST, Liudon
no flags
Safari A page log: Control run with zero Canvas draws and a 27.476-second hidden interval. (59.95 KB, application/json)
2026-11-11 05:09 PST, Liudon
no flags
Safari B page log: Single Canvas draw 439 ms before hiding, followed by a 28.284-second hidden interval. (62.64 KB, application/json)
2026-11-11 05:10 PST, Liudon
no flags
Liudon
Comment 1 2026-11-11 04:51:12 PST
Created attachment 482284 [details] WKWebView B: Occlusion detection disabled; recorded video keeps updating while the window remains occluded.
Liudon
Comment 2 2026-11-11 04:52:54 PST
Created attachment 482285 [details] WKWebView A log: Native window occlusion, page visibility and playback state with default detection.
Liudon
Comment 3 2026-11-11 04:54:53 PST
Created attachment 482286 [details] WKWebView B log: Window remains occluded while the page stays visible with detection disabled.
Liudon
Comment 4 2026-11-11 04:55:29 PST
Created attachment 482287 [details] Diagnostic WKWebView host source, including the private occlusion-detection toggle used for the A/B comparison. Requires repository build context.
Liudon
Comment 5 2026-11-11 04:57:53 PST
Created attachment 482288 [details] HTML test page for local video playback and visibility logging. Use mode=control for the WKWebView A/B comparison.
Liudon
Comment 6 2026-11-11 04:58:24 PST
Created attachment 482289 [details] JavaScript required by the test page; records visibility transitions and supports the single-Canvas-draw experiment.
Liudon
Comment 7 2026-11-11 05:01:31 PST
Created attachment 482290 [details] Local non-DRM moving frame-number video used as the playback source in the reported tests.
Liudon
Comment 8 2026-11-11 05:08:47 PST
Created attachment 482291 [details] Safari A: No Canvas draws; recorded video region becomes blank while the page is on an inactive Space.
Liudon
Comment 9 2026-11-11 05:09:24 PST
Created attachment 482292 [details] Safari B: One hidden-Canvas draw before switching Spaces; the original video region keeps updating while the page is hidden.
Liudon
Comment 10 2026-11-11 05:09:53 PST
Created attachment 482293 [details] Safari A page log: Control run with zero Canvas draws and a 27.476-second hidden interval.
Liudon
Comment 11 2026-11-11 05:10:27 PST
Created attachment 482294 [details] Safari B page log: Single Canvas draw 439 ms before hiding, followed by a 28.284-second hidden interval.
Note You need to log in before you can comment on or make changes to this bug.