vezel-dev / cathode

A terminal-centric replacement for the .NET console APIs.
https://docs.vezel.dev/cathode
BSD Zero Clause License
91 stars 7 forks source link

Delayed ReadLine after on enter with CMD (outside of Windows Terminal) #61

Closed xoofx closed 2 years ago

xoofx commented 2 years ago

Followup of #9 While trying this program with CMD outside of Windows Terminal:

Terminal.OutLine("Type some text:");
while (true)
{
    var line = Terminal.ReadLine();
    if (line == null) break;
    Terminal.OutLine(line);
}

The input seems to not always work on ENTER, sometimes it happens straight, sometimes it happens after the first inputted line. It works fine from the Windows Terminal though.

alexrp commented 2 years ago

I can reproduce this (in the scrolling sample also).

alexrp commented 2 years ago

This looks like a regression, actually. This used to work.

I suspect it's probably related to the whole ReadConsoleW workaround on Windows:

https://github.com/alexrp/system-terminal/blob/438cfb0311c25cf3bc75f0981b8bcaeb8cf7ab75/src/core/Terminals/Windows/WindowsTerminalReader.cs#L40-L156

alexrp commented 2 years ago

Stepping through the code, ReadConsoleW is doing exactly what it should be doing: Returning the pressed characters followed by \r and \n. Nothing unusual there.

Given that this works fine in Windows Terminal, I suspect a console host bug...

@xoofx I don't suppose you have a Windows 10 machine available to test on?

alexrp commented 2 years ago

OK, ignore all of the above; my original hunch in https://github.com/alexrp/system-terminal/issues/9#issuecomment-1002928394 was correct. WindowsCancellationEvent is the culprit. Removing the call to PollWithCancellation makes things work.

Now to figure out why WaitForMultipleObjects on the console input handle behaves differently between Windows Terminal and the Windows console host. Joy...

alexrp commented 2 years ago

It appears that the console input buffer either contains slightly different input records than what we see with Windows Terminal, or that the console host processes them differently. Either way, the logic here is not working under the console host:

https://github.com/alexrp/system-terminal/blob/438cfb0311c25cf3bc75f0981b8bcaeb8cf7ab75/src/core/Terminals/Windows/WindowsTerminalReader.cs#L55-L86

At this point I'm likely to just rip cancellation support out of the Windows driver. The amount of hacks I'm having to pile here to make what should be a simple poll(2) call kinda-sorta work on Windows is getting out of hand.