niri-scratchpad: pull shown window to focused output; don't drop tiles

Two fixes found reviewing the paths the acceptance suite couldn't cover.

Show-while-shown-elsewhere used activate_window, which sets
active_monitor_idx and so dragged *focus* to whichever output the window
was parked on. A scratchpad should come to you: if the window is on
another monitor, remove and re-add it floating on the active workspace;
if it is already on the active monitor, focus in place as before.

add_removed_tile_floating dropped the RemovedTile on both of its early
returns (NoOutputs, monitor-not-found), destroying the window while its
client was still alive and leaving it wedged with no surface anywhere.
Both were unreachable via scratchpad_show's guards, but it is a
window-loss footgun for the next caller. It now returns
Result<(), RemovedTile<W>> so callers can stash the tile instead.

Adds two layout tests (they simulate outputs, so multi-monitor is
covered without a second physical display) and corrects the acceptance
suite's test-8 skip message, which claimed the code used active_output
— it never did; it uses active_workspace.

cargo test --lib scratchpad: 10/10. acceptance.py: 8 passed, 0 failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-07-18 16:47:06 -07:00
parent 640deb397e
commit d0fef1478d
2 changed files with 129 additions and 15 deletions
+4 -2
View File
@@ -306,8 +306,10 @@ def main():
os.unlink(cfg.name)
# #8 multi-monitor cannot be exercised nested (single winit output).
print(" [SKIP] 8 multi-monitor: needs a physical 2nd output; "
"code uses active_output (correct by construction).")
print(" [SKIP] 8 multi-monitor: needs a physical 2nd output. Covered by the "
"layout unit tests instead (scratchpad_shows_on_the_focused_output, "
"scratchpad_show_pulls_already_shown_window_to_focused_output), which "
"simulate outputs: `cargo test --lib scratchpad`.")
passed = sum(1 for _, ok, _ in results if ok)
failed = sum(1 for _, ok, _ in results if not ok)