Repository navigation
Conversation
Window targets on macOS were recorded as a display capture cropped to the window's bounds at start time, so moving the window or overlapping it with other apps changed what was recorded (CapSoftware#1754). Carry the window id into the macOS capture config and build a desktop-independent window SCContentFilter for it, skipping the display crop. The same filter is used when the capturer is rebuilt after a system stop. Display, Area and Camera Only targets are unchanged. Instant mode keeps the display crop when a camera is attached, because macOS Instant recordings have no camera compositing and the camera preview only appears through the display capture. Known limitations: - Studio custom cursor positions are still normalised against the window's start bounds, so the cursor overlay drifts after the window moves. - Output size is fixed at the window's size at start; resize behaviour is untested. - With system audio on, ScreenCaptureKit likely limits audio to the window's owning app. - If the window is missing from shareable content (initially or on restart), capture falls back to the previous display crop. Window-filter approach also explored in CapSoftware#2368.
| let captures_window = window_filter.is_some(); | ||
|
|
||
| let content_filter = match window_filter { | ||
| Some(filter) => filter, |
There was a problem hiding this comment.
The new window filter ignores excluded_windows. A user can select an excluded app from the window dropdown because that list does not apply saved exclusions. Studio, or Instant without a camera, then records that window despite the “Hide windows from recordings” setting. Sharing the recording can expose its contents.
Check the selected ID against excluded_windows before creating the window filter. Apply the same check in rebuild_capturer, which also bypasses the exclusions.
How this was verified: Saved exclusions reach the capturer, but both window-filter branches use the selected window without checking them.
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/recording/src/sources/screen_capture/macos.rs
Line: 253
Comment:
**Excluded windows get recorded**
The new window filter ignores `excluded_windows`. A user can select an excluded app from the window dropdown because that list does not apply saved exclusions. Studio, or Instant without a camera, then records that window despite the “Hide windows from recordings” setting. Sharing the recording can expose its contents.
Check the selected ID against `excluded_windows` before creating the window filter. Apply the same check in `rebuild_capturer`, which also bypasses the exclusions.
**How this was verified:** Saved exclusions reach the capturer, but both window-filter branches use the selected window without checking them.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.The window-only SCContentFilter ignored the "Hide windows from recordings" exclusions, so selecting an excluded window in Window mode recorded it. When the selected window is in the exclusion list, skip the window filter and use the display filter with exclusions, which hides it as before. The check runs both when capture starts and when the capturer is rebuilt.
|
Very nice! Will test this out when I'm at my Mac |
|
@richiemcilroy CI is green now. I merged main to pick up the clippy fix from #2463. Ready whenever you get to test it 🙏 |
Addresses #1754 (macOS).
Problem
On macOS, Window mode records a fixed region of the screen rather than the selected window. If the window is moved during recording, or another app is placed over it, the recording shows whatever now occupies the original rectangle.
Root cause
target_to_display_and_crop(capture_pipeline.rs) turns aScreenCaptureTarget::Windowinto its display plus the window's bounds at start time. The macOS capturer (sources/screen_capture/macos.rs) then builds a displaySCContentFilterand applies those bounds withset_src_rect, so the window id is never used for capture. The restart path (rebuild_capturer) does the same.As discussed with @richiemcilroy on Discord, the crop was intended at the time; this PR moves Window mode to capturing the window itself.
Change
Configgains a macOS-onlywindow: Option<WindowId>, passed throughScreenCaptureConfig::init.SCContentFilter::with_desktop_independent_windowfor that window and skips the displaysrc_rectcrop. The same filter is used inrebuild_capturer.The output size is still derived from the window's bounds at start, as before.
Intended behavior
In Window mode on macOS, the recording contains only the selected window, regardless of where it moves on screen or what overlaps it.
Known limitations
cursor.rs(similar to the Linux X11 one) and is left for a follow-up.Tests
Automated (all passing locally on macOS):
cargo fmt --all -- --checkcargo clippy -p cap-recording --all-targets(no warnings)cargo test -p cap-recording --lib: 563 passed, 4 ignored. Includes a new test,macos_window_target_captures_window_unless_camera_attached.The tests only cover how the capture configuration is selected. Real macOS recording behavior has not been verified yet.
Manual testing still required
cap record start --window <id>Related work
ScreenCaptureConfig::init; whichever lands second will need a small merge-conflict fix.
Confidence Score: 5/5
No blocking finding remains after the excluded-window fix.Summary
macOS Window recordings now use the selected window’s own capture filter in Studio and in Instant without a camera. Initial capture and restart both honor excluded-window settings.
Reviews (4) · Last reviewed commit: "Merge branch 'main' into fix/macos-windo..." · Reviewed by Greptile