Skip to content

fix(windows): remove Cap Target Select from default excluded windows to prevent ghost overlay#1965

Merged
richiemcilroy merged 5 commits into
CapSoftware:mainfrom
ManthanNimodiya:fix/windows-ghost-overlay
Jul 2, 2026
Merged

fix(windows): remove Cap Target Select from default excluded windows to prevent ghost overlay#1965
richiemcilroy merged 5 commits into
CapSoftware:mainfrom
ManthanNimodiya:fix/windows-ghost-overlay

Conversation

@ManthanNimodiya

@ManthanNimodiya ManthanNimodiya commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Problem

On Windows, a transparent ghost overlay persists on screen after every recording ends. ESC doesn't dismiss it. Removing "Cap" from Settings → Excluded Windows instantly surfaces it, confirming the mechanism.

Root Cause

"Cap Target Select" was in DEFAULT_EXCLUDED_WINDOW_TITLES, so apply_content_protection sets WDA_EXCLUDEFROMCAPTURE on the overlay at recording start — even though it's already hidden. When recording ends and WDA_NONE is restored, Windows re-surfaces the hidden window before hide_overlay can suppress it again.

Fix

Remove "Cap Target Select" from the default exclusion list. The overlay is always hidden before recording starts, so content protection on it is a no-op for capture and only causes this side effect on Windows.

Greptile Summary

This PR fixes a Windows ghost overlay bug by removing "Cap Target Select" from DEFAULT_EXCLUDED_WINDOW_TITLES and adds a one-time migration to clean up the entry for existing users. Two companion doctor.rs compile fixes — making the Duration import conditional on macOS and suppressing the unused checks parameter warning via #[cfg_attr] — are also included.

  • Removed "Cap Target Select" from the default exclusion list with a protective comment explaining the Windows-specific reason, so future contributors won't re-add it accidentally.
  • Added a REMOVE_TARGET_SELECT_MIGRATION_KEY migration in init following the established raw_store pattern, ensuring existing users' persisted settings are cleaned up on the next launch.
  • Fixed both previously flagged doctor.rs compile errors: std::time::Duration is now gated with #[cfg(target_os = "macos")], and the checks parameter keeps its name while #[cfg_attr(not(target_os = "macos"), allow(unused_variables))] silences the warning on non-macOS platforms.

Confidence Score: 5/5

Safe to merge — the fix is correctly scoped, all previously raised issues have been addressed, and the migration follows the established pattern already in production.

All three issues flagged in earlier review rounds have been resolved: the Duration import is now correctly conditional, the checks parameter compile error is fixed with #[cfg_attr], and a one-time migration strips "Cap Target Select" from existing users' stored settings. The core logic — removing the window title from the default exclusion list — is straightforward and low-risk. No new issues were found.

No files require special attention.

Important Files Changed

Filename Overview
apps/cli/src/doctor.rs Makes Duration import conditional on macOS (matching its only usage in screen_capture_kit_check), and suppresses the unused-variable warning for the checks parameter on non-macOS via #[cfg_attr] instead of renaming — resolving both previously flagged compile issues.
apps/desktop/src-tauri/src/general_settings.rs Removes "Cap Target Select" from DEFAULT_EXCLUDED_WINDOW_TITLES with an explanatory comment, and adds a one-time migration following the established raw_store pattern to strip the entry from existing users' stored settings — resolving the previously flagged gap for users who already had the entry persisted.

Comments Outside Diff (3)

  1. apps/desktop/src-tauri/src/general_settings.rs, line 116-127 (link)

    P1 Fix is ineffective for existing users

    append_missing_default_excluded_windows only ever adds entries that are missing from the stored list — it never removes entries that have been dropped from DEFAULT_EXCLUDED_WINDOW_TITLES. Any user who installed Cap before this change already has "Cap Target Select" persisted in their excluded_windows store, so on startup the function finds it present and leaves it untouched. The ghost overlay bug will persist for all such users; only fresh installs or users who manually reset their settings will benefit.

    A one-time migration is needed in init, similar to the NATIVE_PREVIEW_MIGRATION_KEY migration at line 424, to remove "Cap Target Select" from the stored list if it is found there.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src-tauri/src/general_settings.rs
    Line: 116-127
    
    Comment:
    **Fix is ineffective for existing users**
    
    `append_missing_default_excluded_windows` only ever **adds** entries that are missing from the stored list — it never removes entries that have been dropped from `DEFAULT_EXCLUDED_WINDOW_TITLES`. Any user who installed Cap before this change already has `"Cap Target Select"` persisted in their `excluded_windows` store, so on startup the function finds it present and leaves it untouched. The ghost overlay bug will persist for all such users; only fresh installs or users who manually reset their settings will benefit.
    
    A one-time migration is needed in `init`, similar to the `NATIVE_PREVIEW_MIGRATION_KEY` migration at line 424, to remove `"Cap Target Select"` from the stored list if it is found there.
    
    How can I resolve this? If you propose a fix, please make it concise.
  2. apps/cli/src/doctor.rs, line 456-475 (link)

    P1 macOS compile error: checks renamed to _checks but still referenced by old name

    The parameter was renamed to _checks to suppress the unused-variable warning on non-macOS platforms, but the #[cfg(target_os = "macos")] block on line 470 still refers to the old name checks. On macOS, that block is compiled and checks is not in scope — this is an unresolved name compile error that breaks the macOS CLI build.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/cli/src/doctor.rs
    Line: 456-475
    
    Comment:
    **macOS compile error: `checks` renamed to `_checks` but still referenced by old name**
    
    The parameter was renamed to `_checks` to suppress the unused-variable warning on non-macOS platforms, but the `#[cfg(target_os = "macos")]` block on line 470 still refers to the old name `checks`. On macOS, that block is compiled and `checks` is not in scope — this is an unresolved name compile error that breaks the macOS CLI build.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
  3. apps/desktop/src-tauri/src/general_settings.rs, line 116-127 (link)

    P1 Fix is ineffective for existing users

    append_missing_default_excluded_windows only ever adds entries absent from the stored list — it never removes entries that were dropped from DEFAULT_EXCLUDED_WINDOW_TITLES. Any user who installed Cap before this change already has "Cap Target Select" persisted in their excluded_windows store; on startup the function finds it present and leaves it untouched. The ghost overlay bug will persist for all such users; only fresh installs benefit.

    A one-time migration in init (similar to the NATIVE_PREVIEW_MIGRATION_KEY pattern at line 424) is needed to strip "Cap Target Select" from the stored list when it is found there.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src-tauri/src/general_settings.rs
    Line: 116-127
    
    Comment:
    **Fix is ineffective for existing users**
    
    `append_missing_default_excluded_windows` only ever **adds** entries absent from the stored list — it never removes entries that were dropped from `DEFAULT_EXCLUDED_WINDOW_TITLES`. Any user who installed Cap before this change already has `"Cap Target Select"` persisted in their `excluded_windows` store; on startup the function finds it present and leaves it untouched. The ghost overlay bug will persist for all such users; only fresh installs benefit.
    
    A one-time migration in `init` (similar to the `NATIVE_PREVIEW_MIGRATION_KEY` pattern at line 424) is needed to strip `"Cap Target Select"` from the stored list when it is found there.
    
    How can I resolve this? If you propose a fix, please make it concise.

Reviews (5): Last reviewed commit: "fix(cli): restore Duration import as cfg..." | Re-trigger Greptile

@@ -96,7 +96,6 @@ const DEFAULT_EXCLUDED_WINDOW_TITLES: &[&str] = &[
"Cap Settings",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice root-cause writeup in the PR description.

One thing to double-check: changing DEFAULT_EXCLUDED_WINDOW_TITLES only affects new configs — existing users likely already have "Cap Target Select" persisted in excluded_windows (and append_missing_default_excluded_windows won’t remove it). If the ghost overlay reproduces for upgraded users, a small one-time migration on Windows to retain everything except that entry could make the fix apply universally.

Also, to prevent reintroducing this accidentally later, it might be worth leaving a short note here:

Suggested change
"Cap Settings",
// NOTE: Avoid excluding "Cap Target Select" by default; on Windows this can cause a ghost overlay to reappear after recording ends.
const DEFAULT_EXCLUDED_WINDOW_TITLES: &[&str] = &[

@ManthanNimodiya

Copy link
Copy Markdown
Contributor Author

@greptileai

Comment thread apps/cli/src/doctor.rs
@@ -456,7 +453,7 @@ fn install_check(install: &Result<cap_cli_install::CliInstallStatus, String>) ->
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rename looks like it’ll break macOS builds: the #[cfg(target_os = "macos")] block in this function still references checks.

Suggested change
}
fn capture_ready(permissions: &Permissions, checks: &[Check]) -> bool {
#[cfg(not(target_os = "macos"))]
let _ = checks;

@ManthanNimodiya

Copy link
Copy Markdown
Contributor Author

please re-review @greptileai

@ManthanNimodiya

Copy link
Copy Markdown
Contributor Author

please re-review @greptileai

Comment thread apps/cli/src/doctor.rs
path::{Path, PathBuf},
time::Duration,
};
use std::path::{Path, PathBuf};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 std::time::Duration import removed but still needed on macOS. The screen_capture_kit_check function is #[cfg(target_os = "macos")] and calls Duration::from_secs(3) at two sites inside it (lines 362 and 385). With the import gone, the macOS build will fail with "cannot find type/value Duration in this scope". The correct fix is to make the import conditional rather than drop it entirely.

Suggested change
use std::path::{Path, PathBuf};
use std::path::{Path, PathBuf};
#[cfg(target_os = "macos")]
use std::time::Duration;
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/cli/src/doctor.rs
Line: 2

Comment:
`std::time::Duration` import removed but still needed on macOS. The `screen_capture_kit_check` function is `#[cfg(target_os = "macos")]` and calls `Duration::from_secs(3)` at two sites inside it (lines 362 and 385). With the import gone, the macOS build will fail with "cannot find type/value `Duration` in this scope". The correct fix is to make the import conditional rather than drop it entirely.

```suggestion
use std::path::{Path, PathBuf};
#[cfg(target_os = "macos")]
use std::time::Duration;
```

How can I resolve this? If you propose a fix, please make it concise.

@ManthanNimodiya

Copy link
Copy Markdown
Contributor Author

please re-review @greptileai

@richiemcilroy richiemcilroy merged commit b62439b into CapSoftware:main Jul 2, 2026
14 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants