Skip to content

fix(windows): Cap UI appears as black rectangle in studio recordings (window exclusion is macOS-only) #1737

Open

Description

@MinitJain

Bug

On Windows, the Cap recording UI appears as a black rectangle in studio mode recordings, starting from the second recording session. The first recording may be unaffected if the Cap window wasn't visible at capture start.

Root cause

Window exclusion is gated entirely to macOS in apps/desktop/src-tauri/src/recording.rs:

#[cfg(target_os = "macos")]
let excluded_windows = { ... resolve_window_ids(...) };

// later:
#[cfg(target_os = "macos")]
{
    builder = builder.with_excluded_windows(excluded_windows.clone());
}

resolve_window_ids in window_exclusion.rs is also #[cfg(target_os = "macos")] only. On Windows, with_excluded_windows is never called, so Cap's own UI is always captured.

Expected behaviour

Cap's own windows (recording controls, camera overlay, etc.) should be excluded from the screen capture on Windows, matching the macOS behaviour.

Steps to reproduce

  1. Open Cap on Windows
  2. Start a studio mode recording
  3. Stop and open the editor — first recording may look fine
  4. Start a second studio mode recording while the Cap UI is visible
  5. Stop and check the recording — Cap UI appears as a black rectangle

Fix needed

Implement window exclusion for Windows using the appropriate screen capture API (Windows Graphics Capture / DXGI). The exclusion list is already built and available in general_settings::default_excluded_windows() — it just needs to be wired up for the Windows capture pipeline.

Relevant files:

  • apps/desktop/src-tauri/src/recording.rs:874-893 — macOS-only exclusion block
  • apps/desktop/src-tauri/src/window_exclusion.rs — resolve_window_ids is macOS-only

Activity

  1. linear commented on Apr 17, 2026

    @linear
  2. tembo commented on Apr 17, 2026

    @tembo

    This is a well-documented issue. For additional context, #1652 reports the same problem (the "black paddle" in recordings is the Cap recording controls toolbar being captured).

    Relevant code locations:

    • apps/desktop/src-tauri/src/recording.rs:874-893 - where excluded_windows is resolved and passed to the builder (macOS-only via #[cfg(target_os = "macos")])
    • apps/desktop/src-tauri/src/window_exclusion.rs:73-98 - resolve_window_ids() function that maps WindowExclusion to actual window IDs (also macOS-only)
    • crates/recording/src/sources/screen_capture/macos.rs:204-228 - where the exclusion actually happens using ScreenCaptureKit's as_content_filter_excluding_windows()

    PR #1179 context:
    The window exclusion system was added in PR #1179 ("feat: Implement new Window excluder system"). The PR description notes: "On macOS, users can exclude any window. However, on Windows, users can only exclude Windows owned by the app due to API limitations."

    Technical approach for Windows:
    The Windows capture pipeline uses scap-direct3d which wraps Windows.Graphics.Capture. Unlike ScreenCaptureKit on macOS (which has a native as_content_filter_excluding_windows API), Windows Graphics Capture doesn't have a built-in window exclusion filter for display captures.

    The codebase already has SetWindowDisplayAffinity available in the vendored tao (vendor/tao/src/platform_impl/windows/window.rs:1092) via set_content_protection(). This could be used to exclude Cap's own windows from capture by setting WDA_EXCLUDEFROMCAPTURE on Cap's window handles at creation time. This is actually how many Windows screen recording apps handle self-exclusion - by marking their own windows as excluded rather than filtering during capture.

    The default exclusion list in general_settings::default_excluded_windows() (general_settings.rs:62-72) already defines all Cap window titles that should be excluded (Cap, Cap Settings, Cap Recording Controls, Cap Camera, etc.), so the infrastructure is there - it just needs the Windows-specific implementation to call SetWindowDisplayAffinity(hwnd, WDA_EXCLUDEFROMCAPTURE) on these windows.

  3. richiemcilroy commented on Aug 3, 2026

    @richiemcilroy
    Member

    For visibility, we've consolidated #1747 and #1586 into this issue since they're reports of the same underlying problem, Windows recording self-exclusion not yet implemented. This stays open as the tracking issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions