niri-scratchpad: refresh patch with multi-monitor tests
Adds two synthetic multi-output tests (niri's layout harness supports several outputs) proving scratchpad_show targets the FOCUSED output, plus a control that it returns to the origin output when focus is unchanged. This is the substitute for manual multi-monitor verification on a single-display machine. 117 layout tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -302,7 +302,7 @@ index 5c4dd639..a90d9e6e 100644
|
||||
let mut seen_workspace_name = Vec::<String>::new();
|
||||
|
||||
diff --git a/src/layout/tests.rs b/src/layout/tests.rs
|
||||
index 31265dd9..65e02f2b 100644
|
||||
index 31265dd9..9037ff08 100644
|
||||
--- a/src/layout/tests.rs
|
||||
+++ b/src/layout/tests.rs
|
||||
@@ -753,6 +753,8 @@ enum Op {
|
||||
@@ -327,7 +327,7 @@ index 31265dd9..65e02f2b 100644
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3929,3 +3937,93 @@ proptest! {
|
||||
@@ -3929,3 +3937,169 @@ proptest! {
|
||||
check_ops_with_options(options, ops);
|
||||
}
|
||||
}
|
||||
@@ -421,3 +421,79 @@ index 31265dd9..65e02f2b 100644
|
||||
+ assert_eq!(layout.scratchpad.len(), 1, "closed window evicted from stash");
|
||||
+ assert_eq!(layout.scratchpad.front().unwrap().tile.window().id(), &1);
|
||||
+}
|
||||
+
|
||||
+#[test]
|
||||
+fn scratchpad_shows_on_the_focused_output() {
|
||||
+ // First, confirm that while stashed the window lives on no monitor at all (checked against
|
||||
+ // a standalone run so `check_ops`'s post-op invariant checks still see a fully-formed op
|
||||
+ // sequence).
|
||||
+ let stash_only_ops = [
|
||||
+ Op::AddOutput(1),
|
||||
+ Op::AddOutput(2),
|
||||
+ Op::FocusOutput(1),
|
||||
+ Op::AddWindow { params: TestWindowParams::new(0) }, // lands on output 1
|
||||
+ Op::ScratchpadStash(0),
|
||||
+ ];
|
||||
+ let stashed_layout = check_ops(stash_only_ops);
|
||||
+ {
|
||||
+ let MonitorSet::Normal { monitors, .. } = &stashed_layout.monitor_set else {
|
||||
+ unreachable!()
|
||||
+ };
|
||||
+ assert!(
|
||||
+ monitors.iter().all(|m| !m.windows().any(|w| *w.id() == 0)),
|
||||
+ "stashed window must not be present on any monitor"
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ // Stash on output 1, then switch focus to output 2 before showing.
|
||||
+ let ops = [
|
||||
+ Op::AddOutput(1),
|
||||
+ Op::AddOutput(2),
|
||||
+ Op::FocusOutput(1),
|
||||
+ Op::AddWindow { params: TestWindowParams::new(0) }, // lands on output 1
|
||||
+ Op::ScratchpadStash(0),
|
||||
+ Op::FocusOutput(2),
|
||||
+ Op::ScratchpadShow,
|
||||
+ ];
|
||||
+ let layout = check_ops(ops);
|
||||
+
|
||||
+ let MonitorSet::Normal { monitors, active_monitor_idx, .. } = &layout.monitor_set else {
|
||||
+ unreachable!()
|
||||
+ };
|
||||
+
|
||||
+ // The window must appear on whichever output is currently focused (output 2), not on the
|
||||
+ // output it was originally stashed from (output 1).
|
||||
+ for (idx, monitor) in monitors.iter().enumerate() {
|
||||
+ let has_window = monitor.windows().any(|w| *w.id() == 0);
|
||||
+ if idx == *active_monitor_idx {
|
||||
+ assert!(has_window, "shown window should be on the focused output");
|
||||
+ } else {
|
||||
+ assert!(!has_window, "shown window should not be on a non-focused output");
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#[test]
|
||||
+fn scratchpad_shows_on_origin_output_when_focus_unchanged() {
|
||||
+ let ops = [
|
||||
+ Op::AddOutput(1),
|
||||
+ Op::AddOutput(2),
|
||||
+ Op::FocusOutput(1),
|
||||
+ Op::AddWindow { params: TestWindowParams::new(0) }, // lands on output 1
|
||||
+ Op::ScratchpadStash(0),
|
||||
+ // no focus change here
|
||||
+ Op::ScratchpadShow,
|
||||
+ ];
|
||||
+ let layout = check_ops(ops);
|
||||
+
|
||||
+ let MonitorSet::Normal { monitors, active_monitor_idx, .. } = &layout.monitor_set else {
|
||||
+ unreachable!()
|
||||
+ };
|
||||
+
|
||||
+ // Focus never left output 1, so the window should reappear there.
|
||||
+ assert_eq!(*active_monitor_idx, 0, "output 1 should still be active");
|
||||
+ assert!(
|
||||
+ monitors[*active_monitor_idx].windows().any(|w| *w.id() == 0),
|
||||
+ "shown window should be on the still-focused origin output"
|
||||
+ );
|
||||
+}
|
||||
|
||||
Reference in New Issue
Block a user