What's wrong
SpectreConsoleProvider.ReadInputAsync turns every Escape keypress into InputResult.Exit() before the application or any element sees it (TUI/Services/SpectreConsoleProvider.cs:89-93):
if (keyInfo.Key == ConsoleKey.Escape ||
(keyInfo.Key == ConsoleKey.C && keyInfo.Modifiers.HasFlag(ConsoleModifiers.Control)))
{
return InputResult.Exit();
}
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.
- With no handler, Escape still ends
RunAsync.
What's wrong
SpectreConsoleProvider.ReadInputAsyncturns every Escape keypress intoInputResult.Exit()before the application or any element sees it (TUI/Services/SpectreConsoleProvider.cs:89-93):UIApplication.ProcessInputAsyncchecksinput.IsExitfirst. If it is set, it callsShutdown()and breaks without ever callingRootElement.HandleInput(TUI/Services/UIApplication.cs:402-414). The demo works around this inTUI.App/InteractiveDemo.cs:197,226: "Escape reaches ProcessInputAsync as an exit" and never reaches an element.Failure scenario
OnHandleInputreturnstrueforConsoleKey.Escape, meaning "close the modal" or "cancel the edit".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
SpectreConsoleProviderreports Escape as ordinary keyboard input (InputResult.FromKey(ConsoleKey.Escape, ...)).UIApplicationoffers the key toRootElement.HandleInputfirst, and treats it as exit only if nothing handled it. Alternatively, the exit key comes from a configurable option, for exampleUIApplicationBuilder.UseExitKey(ConsoleKey?), wherenulldisables it.RunAsync.