v0.9.0: Tasks 74, 75, 98 — broadcast input, per-pane env, close guard#349
Merged
Conversation
Add a per-tab broadcast_input bool (default false) to Tab, initialize it in Tab::new, and add a toggle_broadcast() helper that flips the flag and returns the new state. Include the field in the Debug impl. Two unit tests cover the default and the toggle behavior.
Register the ToggleBroadcastInput key action following the BindingMap convention: enum variant, name(), display_label(), FromStr, ALL, and a default Ctrl+Shift+I binding in register_tab_bindings. Dispatch in actions.rs toggles the active tab's broadcast_input flag and surfaces an info toast. Document the binding in config_example.toml. Update the ALL count (60->61) and default-binding count (47->48) assertions; add round-trip and default-binding tests.
When the active tab has broadcast_input enabled, mirror the active pane's keyboard input to every other leaf pane. write_input_to_terminal gains a key_broadcast_targets slice; a broadcast_key_bytes helper fans out each encoded InputEvent::Key (KKP release path and the main text/key/paste encode path). Mouse, scroll-derived, resize, focus, and selection events are never broadcast. The app_impl render loop collects per-pane senders once per frame and passes the other-pane senders only to the active pane's show() call. The tab bar prepends a satellite-antenna glyph when broadcast is active. Four unit tests cover the fan-out helper.
When the active tab is broadcasting input, tint every split border yellow (instead of the usual blue/gray) and paint a small "BROADCAST" tag in the top-right corner of each visible pane (including a zoomed pane). Top-right placement avoids colliding with the password-prompt lock icon in the tab bar. Purely visual; verified manually.
Add a confirm_broadcast bool to TabsConfig (default false), wired through config_example.toml, the Settings Tabs panel, the Nix home-manager module, and a round-trip test. The Tabs settings tab gains a Broadcast Input section showing the current shortcut (with a jump-to-keybindings button) and the confirm toggle. A new broadcast_guard module provides a per-window confirm dialog (mirroring the paste-guard pattern); when confirm_broadcast is set, enabling broadcast opens the dialog instead of toggling immediately. The dialog is registered in ui_overlay_open so Escape/Enter do not leak to the terminal. Disabling broadcast never prompts.
Record all five 74.x subtask commits in PLAN_VERSION_090.md with design notes, update the task-summary status to Complete, and point tasks 74/75/98 at the combined task-74-75-98/v090-finish branch. Update MASTER_PLAN.md task-summary status (Pending merge) and add a Completion Tracking row.
Add regression tests for the existing LayoutPane env plumbing (load, variable substitution, resolve, and serialize round-trips) and document the per-pane env substitution behavior in LAYOUT_FORMAT.md. No production code change -- Task 75 in v0.9.0 is verification + documentation only.
Read-only audit mapping every pane/tab/window close and app-quit entry point, the modal/dialog pattern to follow (broadcast_guard.rs), snapshot read path, and the key finding that there is no multi-window app-quit path (Quit closes only the focused window). No code change.
Add CloseGuardConfig (enabled / unknown_blocks / guard_app_quit) with the full ConfigPartial + apply_partial merge wiring, the partial-merge guard test entry, two dedicated round-trip tests, config_example.toml documentation, and the Nix home-manager mkOption mirror.
…ands Add the close-on-running-command guard: a new close_guard module with lock-free snapshot detection of running foreground commands, a confirmation dialog (Cancel / Force Close) mirroring broadcast_guard, and wiring into pane close, tab close, and window close. A pane counts as running only when its most recent OSC 133 block has seen C (output start) and not D -- an idle prompt with no command does not block close.
Add an unbound ForceClose key action that resolves an open close-guard dialog as Force Close without the mouse or Ctrl+Enter. Sets a per-window pending_force_close flag drained where the dialog resolves.
Add a Close Guard section to the Security settings tab with enabled / unknown_blocks / guard_app_quit toggles, mirroring the Paste Guard section. Mark Task 98 (and Task 75) complete in the plan and MASTER_PLAN.
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the remaining v0.9.0 "Modern Workflow Terminal" work on the combined
task-74-75-98/v090-finishbranch. SeeDocuments/PLAN_VERSION_090.mdfor thefull per-subtask breakdown and completion notes.
Task 74 — Broadcast Input to Panes ✅
Per-tab toggle that fans out keyboard
InputEvent::Keyevents to every leafpane in the active tab. Mouse/scroll/resize/focus events stay pane-local.
Tab::broadcast_inputflag +KeyAction::ToggleBroadcastInput(Ctrl+Shift+I)."BROADCAST" indicator.
[tabs] confirm_broadcastopt-in confirmation dialog (mirrors paste guard).Task 75 — Verify Per-Pane Env Round-Trip ✅
Verification + documentation only (no production code change). The reduced
v0.9.0 scope: confirm the existing
LayoutPane::envplumbing round-trips anddocument it.
and empty-env omission.
envsubstitution ($1,${named},$ENV{…}) inLAYOUT_FORMAT.md.Task 98 — Block Close on Running Commands ✅
Confirmation dialog when closing a pane/tab/window that has a running
foreground command (detected via OSC 133 markers).
[close_guard]config section (enabled/unknown_blocks/guard_app_quit) with fullConfigPartialmerge wiring + Nix mirror.close_guardmodule: lock-free snapshot detection (a pane is "running"only when its latest OSC 133 block saw C but not D — an idle prompt never
blocks), Cancel / Force-Close dialog, and wiring into pane/tab/window close.
KeyAction::ForceClose(unbound) + a Close Guard section in the Securitysettings tab.
Notable deviations (documented in the plan)
guard_app_quithas noseparate gate — window-close guarding covers every exit.
<unknown command>) becauseCommandBlockdoes not capture the command-line text.Verification
cargo test --all— 103 suites green, 0 failurescargo clippy --all-targets --all-features -- -D warnings— cleancargo fmt --all -- --check— cleancargo machete— cleannixfmt --check/statix check/deadnix --failon the home-manager module — clean