Skip to content

fix(tui): make Ctrl+L and Ctrl+N fire from chat input via priority bindings#450

Open
manuel-goepfi wants to merge 1 commit into
pieces-app:mainfrom
manuel-goepfi:fix/tui-keybinding-priority-ctrl-l-n
Open

fix(tui): make Ctrl+L and Ctrl+N fire from chat input via priority bindings#450
manuel-goepfi wants to merge 1 commit into
pieces-app:mainfrom
manuel-goepfi:fix/tui-keybinding-priority-ctrl-l-n

Conversation

@manuel-goepfi
Copy link
Copy Markdown

Summary

Screen-level Binding(...) declarations are consultative by default — focused widgets get first crack at every keypress and can swallow it. The chat input (a TextArea descendant) inherits readline-style bindings that consume Ctrl+L (clear-line) and Ctrl+N (next-line), so those keypresses never reach action_toggle_ltm / action_new_chat.

The visible symptom was that pressing Ctrl+L appeared to do nothing until the user opened another modal (e.g. Ctrl+Shift+M model selection) which transferred focus off the input. After that modal closed, focus landed on the screen and Ctrl+L finally bubbled up to the binding.

Adding priority=True to both bindings tells Textual to fire the screen action before the focused widget gets to consume the key, so the shortcut works regardless of where focus currently lives.

Why not all bindings?

Ctrl+Shift+M (change model), Ctrl+Shift+W (workstream), and Ctrl+C (stop streaming) keep their default priority:

  • Ctrl+Shift+M and Ctrl+Shift+W are rare enough that no widget binds them.
  • Ctrl+C is special-cased in Textual; elevating it could interfere with focus-aware copy/cancel flows.

Test plan

  • Verified Ctrl+L toggles LTM from inside the chat input on a fresh TUI launch (previously only worked after opening model selection).
  • Verified Ctrl+N creates a new chat from inside the chat input.
  • Other shortcuts unaffected.

…ndings

Screen-level `Binding(...)` declarations are consultative by default —
focused widgets get first crack at every keypress and can swallow it.
The chat input (a TextArea descendant) inherits readline-style bindings
that consume Ctrl+L (clear-line) and Ctrl+N (next-line), so those
keypresses never reach `action_toggle_ltm` / `action_new_chat`.

The visible symptom was that pressing Ctrl+L appeared to do nothing
until the user opened another modal (e.g. Ctrl+Shift+M model selection)
which transferred focus off the input. After that modal closed, focus
landed on the screen and Ctrl+L finally bubbled up to the binding.

Adding `priority=True` to both bindings tells Textual to fire the
screen action before the focused widget gets to consume the key, so
the shortcut works regardless of where focus currently lives.

Ctrl+Shift+M (change model), Ctrl+Shift+W (workstream), and Ctrl+C
(stop streaming) keep their default priority: the first two are rare
enough that no widget binds them; Ctrl+C in Textual is special-cased
and elevating it could interfere with focus-aware copy/cancel flows.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants