macOS: target thumbnail screenshot can hang, leaving the screen-recording indicator (and "Your screen is being observed") stuck — even after Cap quits
还没有人认领这个 Issue。
评估
调研方向
The issue is in the thumbnail capture code in apps/desktop/src-tauri/src/thumbnails/mod.rs and mac.rs. The capture_sample_buf call hangs, blocking the command. Start by examining the async flow and the block_in_place usage in recording.rs. Look for how to add a timeout or switch to using SCStream with explicit stopCapture. Test by running the app and monitoring replayd logs to see if a hung session is created and if the fix releases it. 'Done' means the screen-recording indicator clears after the app quits, even after a simulated hang.
由索引模型根据 Issue 内容生成。
描述
Summary
On launch (no recording started), Cap captures display/window thumbnails with SCScreenshotManager. One of those screenshot requests never completed. While it was pending, macOS kept a screen-capture session open for Cap, so the purple screen-recording indicator stayed on and the lock screen showed "Your screen is being observed".
After Cap quit, replayd ran its per-client cleanup (stopAllStreamsWithError), but the stuck screenshot stream was not released. The indicator kept attributing screen capture to so.cap.desktop until I force-restarted replayd.
The hang itself looks like a ScreenCaptureKit/macOS issue, and so does the missing cleanup on exit. On Cap's side, the Tauri app awaits each thumbnail with no timeout. Once a request hangs, nothing on Cap's side can end it.
Environment
- Cap desktop 0.6.0 (Tauri app,
/Applications/Cap.app, bundle idso.cap.desktop) - macOS 27.0 (build 26A428)
- MacBookPro18,3 (Apple Silicon), single built-in display
Steps to reproduce
- Make sure Cap is not running and no screen-recording indicator is shown.
- In Terminal, start watching the indicator and capture sessions:
log stream --style compact --predicate '(process == "ControlCenter" AND category == "sensor-indicators") OR (process == "replayd" AND eventMessage CONTAINS "SLContentStream")' - Launch Cap. Do not start a recording.
- Count
SLContentStream start:againstSLContentStream stop:lines, and watch whetherActive activity attributionsstays at["scr:so.cap.desktop"]. - Quit Cap and check whether the indicator clears.
This reproduced on my first attempt. I have not measured how often it happens.
What I observed
Clean launch at 08:06:18, no recording:
08:06:18.441 SLContentStream start -> 08:06:18.459 stop (ok)
08:06:18.566 SLContentStream start -> 08:06:18.567 stop (ok)
08:06:18.679 SLContentStream start -> 08:06:18.681 stop (ok)
08:06:18.743 SLContentStream start -> never stopped <-- hung
08:06:46.545 SLContentStream start -> 08:06:46.550 stop (ok)
08:07:10.690 SLContentStream start -> 08:07:10.702 stop (ok)
Every start came from +[SCScreenShotSession captureSLContentStreamScreenshot:withCompletionHandler:], so these are screenshot sessions, not recording streams. From 08:06:18.743 on, ControlCenter reported:
Active activity attributions changed to ["scr:so.cap.desktop"]
Quit at 08:07:39:
08:07:39.443 replayd invalidated because the client process (pid 23425) either cancelled the connection or exited
08:07:39.444 replayd -[RPClient stopAllStreamsWithError:stopReason:] stopReason=0
08:08:06.150 ControlCenter Sorted active attributions from SystemStatus update: [[scr] Cap (so.cap.desktop)] <-- Cap is gone, indicator still on
The indicator only cleared after replayd was killed. launchd then restarted it.
Earlier, in normal use (before I knew the cause)
- ControlCenter attributed 2–3 concurrent
scrsessions to Cap for about 17 hours. Cap's own log (~/Library/Logs/so.cap.desktop) shows only two short studio recordings (5–6 s each) in that period, and both pipelines shut down cleanly. - The long-lived sessions started shortly after a sleep/wake. Cap logged
System woke from sleep; scheduling recovery refreshat that point. - Cap exited normally (
Exit cleanup completed elapsed_ms=11). Onescrattribution then stayed for more than 3 hours untilreplaydwas restarted.
My guess is that each thumbnail refresh (for example after wake) can leak one more hung session. I could not confirm this because the detailed logs from that period had already rotated.
Relevant code (tag cap-v0.6.0)
- Thumbnails are captured one by one and each one is awaited with no timeout:
apps/desktop/src-tauri/src/thumbnails/mod.rs#L89-L136 - The capture call is
sc::ScreenshotManager::capture_sample_buf(...).await, at a flat 320x180:
apps/desktop/src-tauri/src/thumbnails/mac.rs#L22-L42 list_*_with_thumbnailsrun this throughblock_in_place+block_on, so a hung request also blocks the command:
apps/desktop/src-tauri/src/recording.rs#L1122-L1157- The GPUI app already records that
capture_sample_bufcan hang for some sizes without an error ("never resolves -- no error, the future hangs"):
apps/desktop-gpui/src/target_thumbnails.rs#L423-L424
In my case the request used the flat 320x180 size that comment treats as safe, and it still hung.
What I don't know
- Which display or window the hung request was for.
replaydlogs the filter as<private>. - Whether this reproduces on macOS 26.x, or only on 27.0.
Possible mitigations
- Put a per-thumbnail timeout around
capture_sample_buf(for example 2 s) and skip that target on timeout. This keeps the picker from blocking. It probably does not clear the indicator, becauseSCScreenshotManagerhas no cancel API and dropping the future leaves the system session open. - For thumbnails, use a short-lived
SCStream(the existingscap_screencapturekit::Capturer): take the first frame, then callstopCaptureexplicitly, including on timeout. Cap then owns the session's lifetime. I have not verified thatstopCapturereleases a stream that never delivered a frame. - The missing cleanup on exit (the screenshot session survives the client's
stopAllStreams) looks like a macOS bug. It is probably worth a Feedback Assistant report to Apple as well.
Workaround for affected users: quit Cap, then reboot, or run killall -9 replayd (launchd restarts it).
- 主要语言
- Rust
- 星标
- 22.5k
- 派生
- 1.9k
- 平均合并
- 7 小时 43 分钟
- 30 天内合并 PR
- 80
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
CapSoftware/Cap 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 88/100
CapSoftware/Cap#2305 · 2 条评论 ·
-
难度 2/5 1-3 小时 新手友好度 68/100
CapSoftware/Cap#1714 · 3 条评论 ·
-
难度 4/5 3-5 天 新手友好度 45/100
CapSoftware/Cap#2340 · 1 条评论 ·
-
难度 3/5 1-2 天 新手友好度 58/100
CapSoftware/Cap#2329 · 2 条评论 ·
-
难度 5/5 一周以上 新手友好度 35/100
CapSoftware/Cap#2328 · 1 条评论 ·
相似的 Issue
-
bug github_actions
难度 2/5 1-3 小时 新手友好度 75/100
registrystack/registry-stack#1393 ·
-
难度 2/5 1-3 小时 新手友好度 75/100
longbridge/gpui-kit#3223 ·
-
bug engine
难度 2/5 1-3 小时 新手友好度 65/100
rocky-data/rocky#2181 ·
-
难度 2/5 1-3 小时 新手友好度 70/100
oasisprotocol/oasis-sdk#2523 ·
-
bot:ai-assisted component:indexer QA-roadmap status:untriaged
难度 2/5 1-3 小时 新手友好度 75/100
midnightntwrk/midnight-indexer#1557 ·