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

+25 -1
View File
@@ -560,9 +560,13 @@ impl Coordinator {
}
pub(crate) fn terminate_all(&mut self) -> Vec<u64> {
self.terminate_all_with_reason("Screenshot cancelled: the session was locked")
}
pub(crate) fn terminate_all_with_reason(&mut self, reason: &str) -> Vec<u64> {
let ids: Vec<u64> = self.requests.keys().copied().collect();
for id in &ids {
self.reject_inner(*id, "Screenshot cancelled: the session was locked");
self.reject_inner(*id, reason);
}
ids
}
@@ -1029,6 +1033,26 @@ mod completion {
assert!(harness.response().is_none(), "no late success is delivered");
}
#[test]
fn privacy_change_cancels_encoding_and_discards_late_results() {
let mut harness = Harness::new(1);
let id = harness.coordinator.next_id;
harness.coordinator.on_part(id, 0, Ok(buffer(2, 2)));
assert!(harness.coordinator.is_encoding(id));
assert_eq!(
harness.coordinator.terminate_all_with_reason("Capture privacy changed"),
vec![id]
);
assert!(harness.response().unwrap().error.is_some());
assert!(matches!(
harness
.coordinator
.on_encoded(id, Ok(PathBuf::from("/tmp/private.png"))),
Action::DiscardFile(_)
));
assert!(harness.response().is_none());
}
#[test]
fn encoded_result_is_delivered_once() {
let mut harness = Harness::new(1);