Protect selected windows from screen capture

Add capture privacy rules for windows, transient children, overview previews and client cursors, with separate capture rendering and deferred-frame invalidation. Keep detached close snapshots out of captures after clients leave the registry.

Validated with release workspace tests, private compositor/EGL regressions, and an isolated release PipeWire capture test.
This commit is contained in:
Samuel Onoja authored and GitHub committed 2026-10-03 10:49:01 +01:00
1 parent bffd538dd4
commit 453ec16583
24 files changed
+1132 -41

No files matched your search

+6
View File
@@ -116,6 +116,7 @@ impl Ferese {
}
self.windows.register_window(window.clone(), id);
self.refresh_capture_privacy();
self.windows.update(id, |w| w.placement_anchor = Some(anchor));
if rule.width.is_none() && rule.height.is_none() && client_size(&window).is_none() && remembered_work.is_none()
@@ -157,6 +158,7 @@ impl Ferese {
}
self.windows.register_window(window.clone(), id);
self.refresh_capture_privacy();
self.window_stack.insert(id);
if focus_new_window {
self.focused_window = Some(id);
@@ -197,6 +199,7 @@ impl Ferese {
}
self.windows.register_window(window.clone(), id);
self.refresh_capture_privacy();
self.window_stack.insert(id);
if client_size(&window).is_none() {
self.windows.update(id, |w| w.natural_floating_pending = true);
@@ -417,6 +420,7 @@ impl Ferese {
}
pub fn remove_tiled_window(&mut self, window: &Window) {
self.update_capture_cursor_privacy();
self.retain_closed_window(window);
// Uncommitted toplevels have not entered a workspace yet.
self.space.unmap_elem(window);
@@ -424,11 +428,13 @@ impl Ferese {
return;
};
self.refresh_capture_privacy();
self.focus_history.remove(id);
#[cfg(feature = "resize-metrics")]
self.resize_metrics
.end(id, self.start_time.elapsed(), crate::resize_metrics::End::Cancelled);
self.render.remove_window(id);
self.capture_render.remove_window(id);
self.window_stack.remove(id);
self.floating_above_fullscreen.remove(&id);
if let Err(error) = self.workspaces.remove_window(id) {