crossterm-rs / crossterm

Cross platform terminal library rust
MIT License
3.27k stars 280 forks source link

How to restrict `crossterm::event::read` to future events? #704

Open Lioness100 opened 2 years ago

Lioness100 commented 2 years ago

crossterm::event::read is picking up key presses that occur before the function is even called. How do I prevent this?

Piturnah commented 2 years ago

Do you have a (minimum) working example?

TimonPost commented 2 years ago

I am not entirely sure what you mean. Read will return directly if there are events to be read. You can use poll to check if there are events to read. Read is not meant to be an always blocking read waiting for the next event to occur.

Lioness100 commented 2 years ago

Do you have a (minimum) working example?

Run the example event-read and press a key immediately, while it's still building. The key event will still be grabbed by read

Read is not meant to be an always blocking read waiting for the next event to occur

Is there any way to get this behavior?

sigmaSd commented 2 years ago

Why you wold care about this though? programs are not meant to be used when they're building

You can build then run the executable from target/debug/exe so you don't get this behavior

Also what you're describing is something that's not due to crossterm but its the way that all shell works, they buffer any pending key input and give it to the next available reader.

Lioness100 commented 2 years ago

The example of tracking keys whilst building was just a convenient example that was easy to reproduce, not my real use case. Regardless, I think I fixed it by collecting all buffered input before the read function is used for real:

while event::poll(Duration::from_millis(1)).unwrap() {
    event::read().unwrap();
}

loop {
    if let Ok(...) = event::read() {
        // ...
    }
}

When using Duration::from_millis(0) it only worked sometimes, which I don't understand, but it seems? to be fixed with from_millis(1). Is there anything definitely bad about this approach?