Fixed: nonblocking first getch on Windows

The first event Windows receives is a \r when you press enter.

This makes the getNextEvent find that event, but when it returns, it returns null because it is a release event.

Since there is no other event, !more.length fails and executes a goto.
Because it executes that goto without knowing whether the operations is non blocking, it will start blocking.
This commit is contained in:
Marcelo Silva Nascimento Mancini 2025-10-02 21:05:55 -03:00 committed by GitHub
parent 93fb163d73
commit 5ade4616ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 7 additions and 3 deletions

View File

@ -3406,7 +3406,7 @@ struct RealTimeConsoleInput {
if(nonblocking && !anyInput_internal()) if(nonblocking && !anyInput_internal())
return dchar_invalid; return dchar_invalid;
auto event = nextEvent(); auto event = nextEvent(nonblocking);
while(event.type != InputEvent.Type.KeyboardEvent || event.keyboardEvent.pressed == false) { while(event.type != InputEvent.Type.KeyboardEvent || event.keyboardEvent.pressed == false) {
if(event.type == InputEvent.Type.UserInterruptionEvent) if(event.type == InputEvent.Type.UserInterruptionEvent)
throw new UserInterruptionException(); throw new UserInterruptionException();
@ -3418,7 +3418,7 @@ struct RealTimeConsoleInput {
if(nonblocking && !anyInput_internal()) if(nonblocking && !anyInput_internal())
return dchar_invalid; return dchar_invalid;
event = nextEvent(); event = nextEvent(nonblocking);
} }
return event.keyboardEvent.which; return event.keyboardEvent.which;
} }
@ -3561,7 +3561,7 @@ struct RealTimeConsoleInput {
/// Experimental: It is also possible to integrate this into /// Experimental: It is also possible to integrate this into
/// a generic event loop, currently under -version=with_eventloop and it will /// a generic event loop, currently under -version=with_eventloop and it will
/// require the module arsd.eventloop (Linux only at this point) /// require the module arsd.eventloop (Linux only at this point)
InputEvent nextEvent() { InputEvent nextEvent(bool nonblocking=false) {
terminal.flush(); terminal.flush();
wait_for_more: wait_for_more:
@ -3616,7 +3616,11 @@ struct RealTimeConsoleInput {
auto more = readNextEvents(); auto more = readNextEvents();
if(!more.length) if(!more.length)
{
if(nonblocking && !anyInput_internal())
return InputEvent.init;
goto wait_for_more; // i used to do a loop (readNextEvents can read something, but it might be discarded by the input filter) but now it goto's above because readNextEvents might be interrupted by a SIGWINCH aka size event so we want to check that at least goto wait_for_more; // i used to do a loop (readNextEvents can read something, but it might be discarded by the input filter) but now it goto's above because readNextEvents might be interrupted by a SIGWINCH aka size event so we want to check that at least
}
assert(more.length); assert(more.length);