fix(windows): remove Cap Target Select from default excluded windows to prevent ghost overlay#1965
Conversation
…to prevent ghost overlay after recording
| @@ -96,7 +96,6 @@ const DEFAULT_EXCLUDED_WINDOW_TITLES: &[&str] = &[ | |||
| "Cap Settings", | |||
There was a problem hiding this comment.
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:
| "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] = &[ |
| @@ -456,7 +453,7 @@ fn install_check(install: &Result<cap_cli_install::CliInstallStatus, String>) -> | |||
| } | |||
There was a problem hiding this comment.
This rename looks like it’ll break macOS builds: the #[cfg(target_os = "macos")] block in this function still references checks.
| } | |
| fn capture_ready(permissions: &Permissions, checks: &[Check]) -> bool { | |
| #[cfg(not(target_os = "macos"))] | |
| let _ = checks; |
|
please re-review @greptileai |
…ded_windows on startup
|
please re-review @greptileai |
| path::{Path, PathBuf}, | ||
| time::Duration, | ||
| }; | ||
| use std::path::{Path, PathBuf}; |
There was a problem hiding this 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.
| 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.|
please re-review @greptileai |
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"fromDEFAULT_EXCLUDED_WINDOW_TITLESand adds a one-time migration to clean up the entry for existing users. Two companiondoctor.rscompile fixes — making theDurationimport conditional on macOS and suppressing the unusedchecksparameter warning via#[cfg_attr]— are also included."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.REMOVE_TARGET_SELECT_MIGRATION_KEYmigration ininitfollowing the establishedraw_storepattern, ensuring existing users' persisted settings are cleaned up on the next launch.doctor.rscompile errors:std::time::Durationis now gated with#[cfg(target_os = "macos")], and thechecksparameter 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
Durationimport is now correctly conditional, thechecksparameter 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
Durationimport conditional on macOS (matching its only usage inscreen_capture_kit_check), and suppresses the unused-variable warning for thechecksparameter on non-macOS via#[cfg_attr]instead of renaming — resolving both previously flagged compile issues.DEFAULT_EXCLUDED_WINDOW_TITLESwith an explanatory comment, and adds a one-time migration following the establishedraw_storepattern 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)
apps/desktop/src-tauri/src/general_settings.rs, line 116-127 (link)append_missing_default_excluded_windowsonly ever adds entries that are missing from the stored list — it never removes entries that have been dropped fromDEFAULT_EXCLUDED_WINDOW_TITLES. Any user who installed Cap before this change already has"Cap Target Select"persisted in theirexcluded_windowsstore, 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 theNATIVE_PREVIEW_MIGRATION_KEYmigration at line 424, to remove"Cap Target Select"from the stored list if it is found there.Prompt To Fix With AI
apps/cli/src/doctor.rs, line 456-475 (link)checksrenamed to_checksbut still referenced by old nameThe parameter was renamed to
_checksto suppress the unused-variable warning on non-macOS platforms, but the#[cfg(target_os = "macos")]block on line 470 still refers to the old namechecks. On macOS, that block is compiled andchecksis not in scope — this is an unresolved name compile error that breaks the macOS CLI build.Prompt To Fix With AI
apps/desktop/src-tauri/src/general_settings.rs, line 116-127 (link)append_missing_default_excluded_windowsonly ever adds entries absent from the stored list — it never removes entries that were dropped fromDEFAULT_EXCLUDED_WINDOW_TITLES. Any user who installed Cap before this change already has"Cap Target Select"persisted in theirexcluded_windowsstore; 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 theNATIVE_PREVIEW_MIGRATION_KEYpattern at line 424) is needed to strip"Cap Target Select"from the stored list when it is found there.Prompt To Fix With AI
Reviews (5): Last reviewed commit: "fix(cli): restore Duration import as cfg..." | Re-trigger Greptile