From ab4a31d1e7e8d18b8235687c5b0430b883962770 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Thu, 2 Apr 2026 10:59:51 -0500 Subject: [PATCH] [dotnet watch] Fix target framework selector being stuck PhysicalConsole runs Console.ReadKey() in a tight background loop, consuming all key presses and dispatching them via the KeyPressed event. When SpectreBuildParametersSelectionPrompt returned AnsiConsole.Console for non-redirected stdin, Spectre.Console would also call Console.ReadKey() internally, creating a race where PhysicalConsole steals every key press and the selection prompt appears completely stuck (arrow keys, typing, and search all do nothing). Fix by always using KeyPressedAnsiConsole, which reads keys from PhysicalConsole.KeyPressed events instead of competing for Console.ReadKey(). This ensures a single key reader (PhysicalConsole) distributes keys to all consumers including Spectre.Console. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../UI/SpectreBuildParametersSelectionPrompt.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/Dotnet.Watch/dotnet-watch/UI/SpectreBuildParametersSelectionPrompt.cs b/src/Dotnet.Watch/dotnet-watch/UI/SpectreBuildParametersSelectionPrompt.cs index 7119266ef65b..6ad7c6e35c86 100644 --- a/src/Dotnet.Watch/dotnet-watch/UI/SpectreBuildParametersSelectionPrompt.cs +++ b/src/Dotnet.Watch/dotnet-watch/UI/SpectreBuildParametersSelectionPrompt.cs @@ -74,15 +74,10 @@ internal static string FormatDevice(DeviceInfo device) private static IAnsiConsole CreateConsole(IConsole watchConsole) { - if (!Console.IsInputRedirected) - { - return AnsiConsole.Console; - } - - // When stdin is redirected (e.g. in integration tests), Spectre.Console detects - // non-interactive mode and refuses to prompt. Create a console with forced - // interactivity that reads keys from IConsole.KeyPressed (fed by - // PhysicalConsole.ListenToStandardInputAsync). + // Always read keys from IConsole.KeyPressed (fed by PhysicalConsole) instead of + // letting Spectre.Console call Console.ReadKey() directly. PhysicalConsole already + // owns the Console.ReadKey() loop, so a second reader would race with it and never + // receive any key presses, making the selection prompt appear stuck. var ansiConsole = AnsiConsole.Create(new AnsiConsoleSettings { Ansi = AnsiSupport.Yes,