Skip to content

fix(tab-configs): gate Space toggle binding so text params accept spaces (#11138)#11247

Open
maxmilian wants to merge 1 commit into
warpdotdev:masterfrom
maxmilian:fix/11138-tab-params-space-key
Open

fix(tab-configs): gate Space toggle binding so text params accept spaces (#11138)#11247
maxmilian wants to merge 1 commit into
warpdotdev:masterfrom
maxmilian:fix/11138-tab-params-space-key

Conversation

@maxmilian
Copy link
Copy Markdown
Contributor

@maxmilian maxmilian commented May 18, 2026

Summary

Fixes #11138. In a tab config that mixes a repo param with a text param, pressing Space while the text field is focused was opening the repo dropdown instead of inserting a literal space. This made multi-word text params impossible to enter.

Visual evidence

End-to-end recording with a tab config that mixes a repo dropdown and a text param. Same tab config TOML is used in both runs.

pr11247-before-after.mp4
  • Before (red label) — stable (v0.2026.05.18.05.32.stable_02): right-click + → "PR 11247 repro" → modal opens with the repo dropdown + tab_name text field. Clicking into tab_name and pressing Space pops the repo dropdown open instead of inserting a space — the modal-level ToggleDropdown binding fires even with EditorView focused.
  • After (green label) — this PR (local OSS build from fix/11138-tab-params-space-key): same config (copied to ~/.warp-oss/tab_configs/), same modal. Pressing Space in tab_name inserts a literal space (my tabmy tab my tab ); the dropdown stays closed. The Space binding is now scoped to id!(TabConfigParamsModalDropdownOnly), which is only emitted by keymap_context when the config has no Text param.

Tab config used in both runs:

name = "PR 11247 repro"

[[panes]]
id = "main"
type = "terminal"
directory = "{{repo}}"
commands = []

[params.repo]
type = "repo"
description = "Repository to open"

[params.tab_name]
type = "text"
description = "Tab name"
default = "my tab"

Root cause

app/src/tab_configs/params_modal.rs registered the modal-level Space binding with the scope predicate id!("TabConfigParamsModal") & !id!("EditorView"), on the assumption that the !id!("EditorView") clause would suppress the binding while a descendant text editor is focused.

But keystroke dispatch (crates/warpui_core/src/core/app.rs:1998-2034) evaluates each layer's ContextPredicate against that layer's own keymap_context only — it never merges ancestors with descendants. When the focused view is EditorView:

  1. At the EditorView layer the context contains "EditorView" but not "TabConfigParamsModal", so the predicate is false. The editor itself has no Space FixedBinding, so dispatch returns no match for the editor layer and continues up the chain.
  2. At the TabConfigParamsModal layer the context contains "TabConfigParamsModal" but never "EditorView" (the modal isn't an editor), so !id!("EditorView") is always true. The predicate matches, ToggleDropdown fires, the editor never sees the space.

Oz's triage on the issue flagged this exact concern: "whether fixed-binding scope matching is not recognizing the focused text input as an EditorView descendant." It isn't — by design.

(!id!("EditorView") was used nowhere else in the codebase; only the two bindings in this file relied on it.)

Fix

  • Introduce a TabConfigParamsModalDropdownOnly marker.
  • Override TabConfigParamsModal::keymap_context to insert that marker only when has_text_fields() is false (i.e. the config has no Text param at all).
  • Re-scope the Space binding to id!(DROPDOWN_ONLY_FLAG).

Dropdown-only modals (repo-only / branch-only configs) keep Space-to-toggle. Mixed configs no longer steal the space — it falls through to the focused editor as a literal character, which is what users expect.

Tests

4 new unit tests in app/src/tab_configs/params_modal_tests.rs:

  • keymap_context_omits_dropdown_only_flag_when_text_field_present — the modal's emitted context.
  • keymap_context_includes_dropdown_only_flag_when_no_text_fields — complement.
  • space_binding_predicate_blocks_when_text_field_present — the load-bearing regression test for pressing space on tab params switches input field #11138: with a text param present, the predicate must NOT match.
  • space_binding_predicate_fires_in_dropdown_only_modal — preserves the dropdown-only shortcut.

All 7 module tests pass locally (cargo test -p warp --lib tab_configs::params_modal::). cargo fmt --check and cargo clippy -p warp --lib are clean.

Scope

Deliberately not changed:

  • Enter binding keeps its !id!("EditorView") scope. The guard is also dead (same per-layer evaluation reason), but Enter is not reported as broken. The dispatch loop walks the responder chain in reverse, so the editor layer is hit first — EditorView has its own Enter binding that matches and short-circuits the loop, never reaching the modal-layer Enter binding. The modal still receives a separate EditorEvent::Enter via the subscription in handle_editor_event, which calls try_submit. Result: single submit, no double-fire. Touching the Enter binding here would expand the surface for non-reported behavior.
  • !id!("EditorView") framework semantics are left as-is. Fixing the framework so chain-wide negative scopes work is a much larger change.

Follow-up

  • Drop !id!("EditorView") from the Enter binding too — it's misleading dead code now that the mechanism is understood.
  • Consider auditing other callers that try to use !id!(...) against a descendant view's ui_name; this codebase only has the two in params_modal.rs, but the pitfall is easy to hit.
  • A view-harness integration test that actually dispatches a Space keystroke into a mixed-config modal would strengthen regression coverage. The current unit tests cover the predicate but not the full dispatch loop.
  • Pre-existing oddity (not introduced here): in dropdown-only modals, a Branch/Repo picker's filter EditorView cannot accept a literal Space either, because the modal-layer Space binding swallows it. Same root cause; out of scope for this PR.

@cla-bot cla-bot Bot added the cla-signed label May 18, 2026
@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label May 18, 2026
…ces (warpdotdev#11138)

Root cause: the modal-level Space and Enter `FixedBinding`s were scoped to
`id!("TabConfigParamsModal") & !id!("EditorView")` in an attempt to suppress
them while a descendant text editor is focused. But keystroke dispatch in
`crates/warpui_core/src/core/app.rs` evaluates each layer's
`ContextPredicate` against that layer's own `keymap_context` only — it does
not merge ancestors and descendants. The modal layer's context never contains
`"EditorView"`, so the `!id!("EditorView")` guard is always true on that
layer, the binding always matches, and `ToggleDropdown` fires before the
focused text editor can swallow the space.

Fix: introduce a `TabConfigParamsModalDropdownOnly` marker that the modal
adds to its own `keymap_context` when no `Text` param is present, and scope
the Space binding to `id!(DROPDOWN_ONLY_FLAG)`. Dropdown-only modals
continue to support Space-to-toggle; mixed configs no longer steal the
space, so it lands in the focused text editor as a literal character.

Enter binding is left alone: the focused editor emits `EditorEvent::Enter`
through the existing subscription, so submit still works.

4 new unit tests cover both `keymap_context` outputs and the `ContextPredicate`
behavior in both branches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@maxmilian maxmilian force-pushed the fix/11138-tab-params-space-key branch from 0f49e19 to 2709059 Compare May 19, 2026 00:02
@maxmilian maxmilian marked this pull request as ready for review May 19, 2026 00:03
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 19, 2026

@maxmilian

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

oz-for-oss[bot]
oz-for-oss Bot previously requested changes May 19, 2026
Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR narrows the tab-config params modal Space binding so mixed text/dropdown configs can type literal spaces in text params while preserving the dropdown-only shortcut.

Concerns

  • For this user-facing keyboard interaction change, please include screenshots or a short screen recording demonstrating the mixed-config modal accepting spaces end to end.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@maxmilian
Copy link
Copy Markdown
Contributor Author

pr11247-before-after.mp4

Visual evidence — end-to-end recording (per Oz review request)

Side-by-side comparison using a tab config that mixes a repo (dropdown) param with
a text param (~/.warp/tab_configs/pr11247-repro.toml):

  • Before (red label) — stable Warp (v0.2026.05.18.05.32.stable_02):

    1. Right-click + → select "PR 11247 repro" → modal opens with repo dropdown +
      tab_name text field.
    2. Click into tab_name (cursor visible after "my tab").
    3. Press Space → the repo dropdown pops open instead of inserting a space.
      Space is consumed by the modal-level ToggleDropdown binding even though the
      EditorView is focused — exactly the bug from pressing space on tab params switches input field #11138.
  • After (green label) — this PR (local OSS build from
    fix/11138-tab-params-space-key)
    :

    1. Same tab config (copied to ~/.warp-oss/tab_configs/), same modal.
    2. Click into tab_name, press Spacetab_name becomes my tab (literal
      space inserted, cursor advances).
    3. Press Space again → my tab (two spaces). The dropdown stays closed; the
      Space binding is now scoped to id!(TabConfigParamsModalDropdownOnly) and only
      applies to dropdown-only configs.

Tab config used in both runs:

name = "PR 11247 repro"

[[panes]]
id = "main"
type = "terminal"
directory = "{{repo}}"
commands = []

[params.repo]
type = "repo"
description = "Repository to open"

[params.tab_name]
type = "text"
description = "Tab name"
default = "my tab"

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 19, 2026

@maxmilian

I'm re-reviewing this pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

oz-for-oss[bot]
oz-for-oss Bot previously requested changes May 19, 2026
Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR changes the tab-config params modal so the modal-level Space binding only fires for dropdown-only configs, allowing text params in mixed configs to receive literal spaces. It also adds unit coverage for the new keymap-context behavior.

Concerns

  • For this user-facing behavior change, please include screenshots or a short screen recording demonstrating it working end to end. The PR description describes local tests, but it does not include visual evidence for the changed modal behavior.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@maxmilian
Copy link
Copy Markdown
Contributor Author

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 19, 2026

@maxmilian

I'm re-reviewing this pull request in response to a review request.

You can view the conversation on Warp.

I reviewed this pull request and requested human review from: @moirahuang.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@oz-for-oss oz-for-oss Bot dismissed stale reviews from themself May 19, 2026 15:56

Oz no longer requests changes for this pull request after the latest automated review.

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR scopes the tab config params modal's Space fixed binding to dropdown-only modals by adding a dedicated keymap-context marker when no text params are present. It also adds focused unit coverage for the keymap context and the binding predicate behavior, and the attached visual evidence demonstrates the mixed repo/text-param regression before and after the fix.

Concerns

  • No blocking correctness, security, or spec-alignment concerns found in the changed diff.

Verdict

Found: 0 critical, 0 important, 0 suggestions

Approve

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@oz-for-oss oz-for-oss Bot requested a review from moirahuang May 19, 2026 15:56
Copy link
Copy Markdown
Contributor

@moirahuang moirahuang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a higher level comment, i think a better fix would be to move the space handling out of the params modal and into the dropdown picker instead. the one thing we'd want to ensure is that if there's only 1 item in the modal, we're focused on that item.

the semantics of what i'd recommend is something like "if the dropdown is focused, the dropdown owns Space"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pressing space on tab params switches input field

2 participants