You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Escape always shuts the application down and never reaches an element, so Esc-to-cancel dialogs and edits are impossible #186
SpectreConsoleProvider.ReadInputAsync turns every Escape keypress into InputResult.Exit() before the application or any element sees it (TUI/Services/SpectreConsoleProvider.cs:89-93):
UIApplication.ProcessInputAsync checks input.IsExit first. If it is set, it calls Shutdown() and breaks without ever calling RootElement.HandleInput (TUI/Services/UIApplication.cs:402-414). The demo works around this in TUI.App/InteractiveDemo.cs:197,226: "Escape reaches ProcessInputAsync as an exit" and never reaches an element.
Failure scenario
Build a UI with a modal panel or text-entry element whose OnHandleInput returns true for ConsoleKey.Escape, meaning "close the modal" or "cancel the edit".
Run the app, open the modal, and press Esc.
The whole application exits. The element's handler is never called. The only way to change this is to write a custom IConsoleProvider.
Why it matters
Esc-to-cancel is one of the most common TUI conventions (dialogs, menus, search boxes, inline edits). The library currently cannot support it. The exit policy also sits in the console provider, which should only translate keys, rather than in the application.
Suggested fix / acceptance criteria
SpectreConsoleProvider reports Escape as ordinary keyboard input (InputResult.FromKey(ConsoleKey.Escape, ...)).
UIApplication offers the key to RootElement.HandleInput first, and treats it as exit only if nothing handled it. Alternatively, the exit key comes from a configurable option, for example UIApplicationBuilder.UseExitKey(ConsoleKey?), where null disables it.
Escape remains the default exit key, so existing apps behave the same.
Tests:
An element that handles Escape receives it, and the app keeps running.
Next step: Give Escape to the element tree first and exit only if nothing handles it, or make the exit key configurable. Keep Escape as the default exit key.
Activity
matt-edmondson commentedon Sep 30, 2026
Triage
IConsoleProvider, but existing apps are not broken.SpectreConsoleProvider.ReadInputAsyncandUIApplication.ProcessInputAsyncGenerated by Claude Code