13

I would use ncurses but I want it to run on Windows. In C++, I could use kbhit() and getch() from conio to first check if a character was pressed, then get it.

I would like something similar in Rust.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
ca1ek
  • 405
  • 1
  • 4
  • 14

2 Answers2

8

With the crate device_query you can query the keyboard state without requiring an active window. You just need to add in your Cargo.toml file the dependency to this crate:

[dependencies]
device_query = "0.1.0"

The usage is straightforward and similar to kbhit() and getch(). The difference is you'll receive a Vec of pressed keys (Keycode) and this Vec will be empty if no key is pressed. A single call covers the functionality of both kbhit() and getch() combined.

use device_query::{DeviceQuery, DeviceState, Keycode};

fn main() {
    let device_state = DeviceState::new();
    loop {
        let keys: Vec<Keycode> = device_state.get_keys();
        for key in keys.iter() {
            println!("Pressed key: {:?}", key);
        }
    }
}

This program will print out all pressed keys on the console. To instead just check if any key is pressed (like with kbhit() only), you could use is_empty() on the returned Vec<> like this:

let keys: Vec<Keycode> = device_state.get_keys();
if !keys.is_empty(){
    println!("kbhit");
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Constantin
  • 8,721
  • 13
  • 75
  • 126
  • it seems that method `get_keys()` is non-blocking , it will return immediately , so the main program keep polling ? – Chris.Huang Dec 01 '21 at 12:46
  • This method no longer works. I have tried the version in question (after using cargo add device_query, witch panicked with an error about how I do not have an X display). Then I ran cargo clean, wiped the lock file, and switched the version to 0.1.0, and I got a segmentation fault. – inyourface3445 Apr 13 '23 at 13:05
0

You still can do something like

extern {
    fn _getch() -> core::ffi::c_char;
}

fn getch() -> char {
    unsafe {
        _getch() as char
    }
}
Miiao
  • 751
  • 1
  • 8