Skip to content

[dotnet watch] Fix target framework selector being stuck#53675

Merged
jonathanpeppers merged 1 commit intorelease/10.0.3xxfrom
dev/peppers/fix-dotnet-watch-input
Apr 2, 2026
Merged

[dotnet watch] Fix target framework selector being stuck#53675
jonathanpeppers merged 1 commit intorelease/10.0.3xxfrom
dev/peppers/fix-dotnet-watch-input

Conversation

@jonathanpeppers
Copy link
Copy Markdown
Member

Testing dotnet-watch end-to end on a dotnet new maui project:

image

I found the Spectre.Console input was just "stuck", neither up/down arrows or typing to search did anything!

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.

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>
@jonathanpeppers jonathanpeppers requested review from a team and tmat as code owners April 2, 2026 16:19
Copilot AI review requested due to automatic review settings April 2, 2026 16:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes dotnet watch interactive selection prompts (target framework / device) becoming unresponsive by ensuring Spectre.Console reads keystrokes via PhysicalConsole’s KeyPressed event stream rather than competing with a second Console.ReadKey() loop.

Changes:

  • Removes the conditional that returned AnsiConsole.Console when stdin isn’t redirected.
  • Always constructs a Spectre console wrapper (KeyPressedAnsiConsole) that sources input from IConsole.KeyPressed.
Comments suppressed due to low confidence (1)

src/Dotnet.Watch/dotnet-watch/UI/SpectreBuildParametersSelectionPrompt.cs:88

  • CreateConsole now forces AnsiSupport.Yes and sets Profile.Capabilities.Ansi/Interactive = true for all runs. That bypasses Spectre.Console’s normal capability detection (e.g., output redirection / NO_COLOR / terminals without ANSI), and can lead to escape sequences or interactive prompting in contexts where the default AnsiConsole.Console would correctly downgrade. Consider keeping auto-detection for ANSI/output and only swapping the input source (wrap AnsiConsole.Console and override Input, and only force Interactive when you specifically need to override redirected-stdin behavior).
        var ansiConsole = AnsiConsole.Create(new AnsiConsoleSettings
        {
            Ansi = AnsiSupport.Yes,
            Interactive = InteractionSupport.Yes,
        });
        ansiConsole.Profile.Capabilities.Interactive = true;
        ansiConsole.Profile.Capabilities.Ansi = true;
        return new KeyPressedAnsiConsole(ansiConsole, watchConsole);

@jonathanpeppers jonathanpeppers merged commit 8d3f653 into release/10.0.3xx Apr 2, 2026
32 checks passed
@jonathanpeppers jonathanpeppers deleted the dev/peppers/fix-dotnet-watch-input branch April 2, 2026 18:16
jonathanpeppers added a commit that referenced this pull request Apr 27, 2026
Testing `dotnet-watch` end-to end on a `dotnet new maui` project...

I found the Spectre.Console input was just "stuck", neither up/down arrows or typing to search did anything!

`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>
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.

3 participants