cmux NEXT keys: a focused text field keeps Return, Esc and ↑ from unscoped defaults
Leo pressed ⌘↩ in the chat composer to steer and got the toast "the workspace checklist has no item to do". The composer never saw the key: toggleChecklistItemComplete has ⌘↩ as its default and took it first.
#22616 (Austin) fixes this for the agent chat and web pages by surface. This PR is the general rule Leo asked for, on top of it and without touching its lines: a default binding on a key a text field or composer uses itself steps aside while text input has the keyboard. The keys are ↩, ⌘↩, ⇧↩, ⌥↩, Esc and ↑. The exception is an action scoped to a surface through requires (the omnibar's ⌘↩, the file explorer's ↩), which keeps its key.
This also covers what #22616 leaves out: the Home/Chief composer (surfaceKind == home), the terminal TextBox, sidebar fields and the rename sheet.
KeyBindingDefaults.textInputKeysandnotTextInput(textInputFocusortextBoxFocusedunset).RegistryKeyBindings.makeTableaddsnotTextInputto the default entry of any action with norequireswhose key is intextInputKeys. A user binding keeps its ownwhen.- Today this changes only the checklist toggle's ⌘↩. A guard test fails if a later unscoped default lands on one of these keys.
Changelog
Fixed: ⌘Return in a chat or Home composer, or any focused text field, reaches the field instead of toggling a checklist item.
Testing
Packages/macOS/CmuxNext/Tests/CmuxNextAppTests/TextInputKeysYieldTests.swift sends ⌘↩ through KeyRouter.decide, the dispatcher's real decision path.
Command: cmux-ci run --class light --script scripts/ci/run-swift-testing-suites.sh --arg=Packages/macOS/CmuxNext --ref <sha>
- Red, at 1986c238ef4f (test only), step 6996c7dd3dfdd75a8eea7756:
theChatComposerGetsCommandReturn,theHomeComposerGetsCommandReturnandaSidebarFieldGetsCommandReturnfail (== "deliver").theTodoPageStillTogglespasses. - Green, at ca52c47cc84e (the same tree as the head 36b8bd14588c, before I split the guard test out of the red commit), step 4cb61a00f92a2c942b949d67:
TextInputKeysYieldTestspasses all 5, includingnoUnscopedDefaultTakesATextFieldKey.
Observed / Not run
- Observed: the red and green runs above. Other suites failed in the green run as well (AccountsCmuxRowTests, AgentPaneSendPickedFolderPromptTests, BrowserImportFolderGrantTests, DebugPaletteCaptureTests, SidebarOneMorphingCardTests and others). They are about accounts, folders, sidebar motion and capture, not key routing. I did not run them on base to compare.
- Not run: the head SHA itself on the fleet (same tree as ca52c47), and a live ⌘↩ in a tagged build.
Agent session: cosmic-gray
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fixes key routing so a focused text field or composer keeps its own keys (Return and its ⌘/⇧/⌥ forms, Esc, ↑) instead of an unscoped default binding taking them. Previously ⌘Return in the chat composer triggered the checklist toggle, which refused with a "no todo items" toast.
- Default bindings on those keys now add a
notTextInputcondition unless the action is scoped to a surface throughrequires(the omnibar's ⌘Return, the file explorer's Return keep their keys). - Covers the Home/Chief composer, terminal TextBox, sidebar fields, and the rename sheet, which the existing surface-specific fix leaves out.
- Adds tests for the chat and Home composers and a sidebar field, plus a guard test that fails if a later unscoped default lands on one of these keys.