feat(action): add --no-focus flag to new-pane - #5109
Draft
zh4ngx wants to merge 1 commit into
Draft
Conversation
Add a `--no-focus` CLI flag to `zellij action new-pane` (and `zellij action edit`) so scripted multi-pane workflows can spawn new panes without stealing focus from the user's interactive pane. Threading: a new `should_focus_pane: bool` field is added to `Action::NewPane`, `Action::NewBlockingPane`, `Action::NewFloatingPane`, `Action::NewTiledPane`, `Action::NewStackedPane`, and `Action::EditFile`. The field is wired through `PtyInstruction::SpawnTerminal` -> `ScreenInstruction::NewPane`, replacing the previously hardcoded `true` literals at screen.rs ClientId and TabIndex branches. The PaneId branch is unchanged (already used `false`). CLI flag conflicts with `--in-place` (in-place replaces the focused pane, making "no focus" semantically meaningless). Compatible with `--blocking` and `--near-current-pane`. `Action::NewInPlacePane` is intentionally not threaded — its semantics imply focus. Backward compat: legacy default is `should_focus_pane: true` everywhere. Protobuf fields added at the next free tag as `optional bool` so older clients deserialize as `None`, mapped back to `true`. KDL keybindings preserve the legacy default. Tests: 6 new round-trip tests in actions.rs covering Tiled/Floating/Stacked/ Blocking/Edit paths plus default-focuses-pane regression test. Existing roundtrip_tests.rs and screen_tests.rs fixtures updated. Insta snapshots regenerated for KDL and screen instruction debug output. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Motivation
Scripted multi-pane workflows (orchestrators that spawn helpers via
zellij action new-pane …) currently steal focus from the interactiveuser every time a new pane is spawned. The internal
Tab::new_panealready takes a
should_focus_pane: bool, but the action layer hardcodestrueregardless of caller intent — seezellij-server/src/screen.rsClientId and TabIndex branches. This PR exposes that switch at the CLI.
Change
Add a
--no-focusflag tozellij action new-pane(andzellij action editfor parity, sinceEditFilefollows the same focus path).Internally, a new
should_focus_pane: boolfield is added to:Action::NewPane(legacy KDL keybind variant)Action::NewBlockingPaneAction::NewFloatingPaneAction::NewTiledPaneAction::NewStackedPaneAction::EditFileThe field is threaded through
PtyInstruction::SpawnTerminalandScreenInstruction::NewPane, replacing the hardcodedtrueliterals atscreen.rs ClientId and TabIndex branches. The PaneId branch (used when
--near-current-paneresolves to a pane) is unchanged — it alreadyhardcodes
false.Action::NewInPlacePaneis intentionally not threaded: in-placereplaces the focused pane, so "no focus" is semantically meaningless.
The CLI enforces this via
clap'sconflicts_with(\"in-place\").Backward compatibility
--no-focusisfalse, so omitting the flag yieldsthe existing focus-stealing behavior.
set
should_focus_pane: trueto preserve current behavior.optional bool—older clients deserialize as
None, which maps back totrueon thereceiver side. No wire-format break.
Compatibility with related flags
--no-focus --near-current-pane: allowed. Orthogonal: focus vs.placement.
--no-focus --blocking: allowed. Caller wants to wait for commandexit but not steal focus from interactive user.
--no-focus --in-place: rejected at CLI parse time (clap conflict).Tests added/updated
zellij-utils/src/input/actions.rs:test_new_pane_no_focus_threads_through_tiledtest_new_pane_default_focuses_panetest_new_pane_no_focus_threads_through_floatingtest_new_pane_no_focus_threads_through_stackedtest_new_pane_no_focus_threads_through_blockingtest_edit_no_focus_threads_throughzellij-utils/src/ipc/tests/roundtrip_tests.rsfixtures updated.zellij-server/src/unit/screen_tests.rsfixtures updated.debug output.
Test results
cargo test -p zellij-utils --lib: 384 passedcargo test -p zellij-server --lib: 1066 passedcargo test -p zellij-client --lib: 111 passedVerification
Out of scope
NewTiledPluginPane,NewFloatingPluginPane,NewInPlacePluginPane) use a separate code path throughPtyInstruction::FillPluginCwd, which already has its ownOption<bool>for plugin focus. Threading--no-focusthrough pluginpanes would be a larger change touching the plugin-loading flow; not
covered here. CLI
--no-focusonly affects terminal panes.