Summary
With enhanced_detection enabled on macOS, Chrome incognito windows are captured (frames, OCR text, accessibility text) even though ignore_incognito_windows is on. Basic title based detection is not affected: opting into enhanced detection is what opens the gap, which is the opposite of what a user enabling it would expect.
Root cause
In crates/screenpipe-a11y/src/incognito/macos.rs, is_incognito() treats any answer from the AppleScript strategy as final:
if self.enhanced_detection && Self::is_chromium_browser(app_name) {
if let Some(is_private) = self.check_with_cache(app_name, window_title) {
return is_private;
}
// AppleScript failed — fall through to title check.
}
check_with_cache compares titles by exact match (titles.contains(window_title)). The AppleScript query returns tab titles (for example Privacy - Wikipedia), while the AX window title passed in by the tree walk carries a suffix (Privacy - Wikipedia - Google Chrome (Incognito)). The lookup misses, Some(false) is returned, and the localized title fallback is_title_private() never runs, even though it would have matched the (Incognito) marker in that same title.
The fallback only runs when AppleScript errors out (None), not when it succeeds with a non matching answer.
Reproduction
macOS 26, Chrome, ignore_incognito_windows on, enhanced detection on:
screenpipe record --data-dir ./data --use-all-monitors
- Open a Chrome incognito window, focus it, browse two tabs for a minute
sqlite3 ./data/db.sqlite "SELECT id, window_name, text_source FROM frames WHERE window_name LIKE '%Incognito%';"
Observed (reproduced three times, 6 to 9 rows each run):
id window_name text_source
-- ----------------------------------------------- -------------
3 Example Domain - Google Chrome (Incognito) accessibility
4 Privacy - Wikipedia - Google Chrome (Incognito) accessibility
5 Privacy - Wikipedia - Google Chrome (Incognito) accessibility
...
Page text from those windows is present in the extracted text as well. Expected: TreeWalkResult::Skipped(SkipReason::Incognito) and no capture.
Suggested fix
Treat a negative AppleScript answer as non final and let the localized title check have the last word. A false positive skips one window; a false negative records private browsing.
if self.enhanced_detection && Self::is_chromium_browser(app_name) {
if let Some(true) = self.check_with_cache(app_name, window_title) {
return true;
}
// A negative answer is not trusted as final: the AppleScript query
// returns tab titles, while the AX title carries a browser suffix,
// so the exact match lookup can miss a window that is private.
}
is_title_private(window_title)
An alternative is to make the cache lookup tolerant (window_title.contains(title) in addition to the exact match), but falling through is the smaller and safer change.
Happy to open a PR if useful.
Summary
With
enhanced_detectionenabled on macOS, Chrome incognito windows are captured (frames, OCR text, accessibility text) even thoughignore_incognito_windowsis on. Basic title based detection is not affected: opting into enhanced detection is what opens the gap, which is the opposite of what a user enabling it would expect.Root cause
In
crates/screenpipe-a11y/src/incognito/macos.rs,is_incognito()treats any answer from the AppleScript strategy as final:check_with_cachecompares titles by exact match (titles.contains(window_title)). The AppleScript query returns tab titles (for examplePrivacy - Wikipedia), while the AX window title passed in by the tree walk carries a suffix (Privacy - Wikipedia - Google Chrome (Incognito)). The lookup misses,Some(false)is returned, and the localized title fallbackis_title_private()never runs, even though it would have matched the(Incognito)marker in that same title.The fallback only runs when AppleScript errors out (
None), not when it succeeds with a non matching answer.Reproduction
macOS 26, Chrome,
ignore_incognito_windowson, enhanced detection on:screenpipe record --data-dir ./data --use-all-monitorssqlite3 ./data/db.sqlite "SELECT id, window_name, text_source FROM frames WHERE window_name LIKE '%Incognito%';"Observed (reproduced three times, 6 to 9 rows each run):
Page text from those windows is present in the extracted text as well. Expected:
TreeWalkResult::Skipped(SkipReason::Incognito)and no capture.Suggested fix
Treat a negative AppleScript answer as non final and let the localized title check have the last word. A false positive skips one window; a false negative records private browsing.
An alternative is to make the cache lookup tolerant (
window_title.contains(title)in addition to the exact match), but falling through is the smaller and safer change.Happy to open a PR if useful.