Add support for detecting press and release events in `livesplit-hotkey` via new API `register_specific`
Closes #633
Changes
Adds register_specific, which allows the developer to provide a callback that takes a single boolean argument that dictates whether the event was a press or release.
Disclaimer
I understand that the issue this is linked to was labelled "needs further discussion" due to it being a bit out of scope of the needs of livesplit, which is totally fair. I originally implemented this for my own use, but decided it was worth PR'ing just in case it would be considered.
The entire implementation is feature-gated, partly due to this concern:
especially in our case where the timing is really important.
which is valid! The feature gating means it should not effect the existing hotkey registration/performance in any way, so long as the feature is not explicitly enabled.
Other notes
- The reason I chose this crate over others is due to it having the most comprehensive keycode support I've seen, as well as the direct mapping from JS/browser keycodes to the Rust KeyCode struct you provide, both of which are important to my use-case. I might even say (as someone who has explored many) that this is one of the best global-keyboard-input-reading crates in the ecosystem right now, so thank you for providing it publicly!
- I have tested on my Windows, Linux, and macOS machines, but had trouble figuring out testing WASM (it's new to me), so that's untested
- I should also note that I am not married to the naming scheme I chose and would be happy to change it to whatever fits better. I don't totally think
register_specificis obvious enough in expressing what it actually does/allows haha
Test Program
use livesplit_hotkey::{ConsumePreference, Hook, Hotkey, KeyCode, Modifiers};
pub fn main() {
let hook = Hook::with_consume_preference(ConsumePreference::NoPreference).unwrap();
let hotkey = Hotkey {
key_code: KeyCode::ArrowUp,
modifiers: Modifiers::CONTROL,
};
hook.register_specific(hotkey, |pressed| {
if pressed {
println!("Control + Up Arrow was pressed!");
} else {
println!("Control + Up Arrow was released!");
}
}).unwrap();
loop {
std::thread::park();
std::thread::sleep(std::time::Duration::from_secs(1));
}
}