Skip to content

Commit

Permalink
feat: add support for string one byte hex codes
Browse files Browse the repository at this point in the history
  • Loading branch information
iholston committed Dec 28, 2024
1 parent 869ca3e commit e4f0984
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 14 deletions.
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,39 @@ fn main() {
hkm.event_loop();
}
```
## Keys
`win-hotkeys` provides a `VKey` and `ModKey` enum that abstracts the Windows Virtual Key (VK) codes. These keys
are used to specify the hotkeys available for registration.

```rust
fn main() {
let vk_a1 = VKey::A;
let vk_a2 = VKey::from_keyname("a").unwrap();
let vk_a3 = VKey::from_keyname("A").unwrap();
let vk_a4 = VKey::from_keyname("0x41").unwrap();
let vk_a5 = VKey::from_vk_code(0x41);
let vk_a6 = VKey::CustomKeyCode(0x41);

assert_eq!(vk_a1, vk_a2);
assert_eq!(vk_a1, vk_a3);
assert_eq!(vk_a1, vk_a4);
assert_eq!(vk_a1, vk_a5);
assert_eq!(vk_a1, vk_a6);

let mod_alt1 = ModKey::Alt;
let mod_alt2 = ModKey::from_keyname("alt").unwrap();
let mod_alt3 = ModKey::from_keyname("VK_LMENU").unwrap();
let mod_alt4 = ModKey::from_keyname("OxA4").unwrap();
let mod_alt5 = ModKey::from_vk_code(0xA4).unwrap();

assert_eq!(mod_alt1, mod_alt2);
assert_eq!(mod_alt1, mod_alt3);
assert_eq!(mod_alt1, mod_alt4);
assert_eq!(mod_alt1, mod_alt5);
}
```

For a full list of supported keys, refer to the [Microsoft Virtual-Key Codes](https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes)

## Examples
Up-to-date examples can always be found in the [examples directory](https://github.com/iholston/win-hotkeys/tree/main/examples)
Expand Down
27 changes: 15 additions & 12 deletions src/keys/modkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,22 @@ pub enum ModKey {
impl ModKey {
/// Creates a `ModKey` from a string representation.
///
/// # Supported Values
/// - "CTRL" or "CONTROL"
/// - "SHIFT"
/// - "ALT"
/// - "WIN", "WINDOWS", or "SUPER"
/// # See Also
/// - [Microsoft Virtual-Key Codes](https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes)
pub fn from_keyname(name: &str) -> Result<ModKey, WHKError> {
Ok(match name.to_ascii_uppercase().as_ref() {
"CTRL" | "CONTROL" => ModKey::Ctrl,
"SHIFT" => ModKey::Shift,
"ALT" => ModKey::Alt,
"WIN" | "WINDOWS" | "SUPER" => ModKey::Win,
val => return Err(WHKError::InvalidModKey(val.to_string())),
})
Ok(
match name.to_ascii_uppercase().trim_start_matches("VK_").as_ref() {
"CTRL" | "CONTROL" | "LCONTROL" | "RCONTROL" => ModKey::Ctrl,
"OX11" | "OXA2" | "OXA3" => ModKey::Ctrl,
"SHIFT" | "LSHIFT" | "RSHIFT" => ModKey::Shift,
"OX10" | "OXA0" | "OXA1" => ModKey::Shift,
"ALT" | "MENU" | "LMENU" | "RMENU" => ModKey::Alt,
"OX12" | "OXA4" | "OXA5" => ModKey::Alt,
"WIN" | "WINDOWS" | "SUPER" | "LWIN" | "RWIN" => ModKey::Win,
"OX5B" | "OX5C" => ModKey::Win,
val => return Err(WHKError::InvalidModKey(val.to_string())),
},
)
}

/// Converts the `ModKey` to its corresponding Windows virtual key (VK) code.
Expand Down
16 changes: 14 additions & 2 deletions src/keys/vkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,16 @@ impl VKey {
///
pub fn from_keyname(name: &str) -> Result<VKey, WHKError> {
let name = name.to_ascii_uppercase();

// 1 byte hex code => Use the raw keycode value
if name.len() >= 3 && name.len() <= 6 && name.starts_with("0x") || name.starts_with("0X") {
if let Ok(val) = u16::from_str_radix(&name[2..], 16) {
return Ok(Self::CustomKeyCode(val));
} else {
return Err(WHKError::InvalidKey(name));
}
}

Ok(match name.trim_start_matches("VK_") {
"BACK" => VKey::Back,
"TAB" => VKey::Tab,
Expand Down Expand Up @@ -841,7 +851,6 @@ impl TryInto<ModKey> for VKey {

impl std::str::FromStr for VKey {
type Err = WHKError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
VKey::from_keyname(s)
}
Expand Down Expand Up @@ -879,6 +888,10 @@ mod tests {
assert_eq!(VKey::from_keyname("BACK").unwrap(), VKey::Back);
assert_eq!(VKey::from_keyname("VK_BACK").unwrap(), VKey::Back);
assert_eq!(VKey::from_keyname("RETURN").unwrap(), VKey::Return);
assert_eq!(
VKey::from_keyname("0x29").unwrap(),
VKey::CustomKeyCode(0x29)
);
assert!(VKey::from_keyname("INVALID_KEY").is_err());
}

Expand Down Expand Up @@ -913,7 +926,6 @@ mod tests {
#[test]
fn test_from_str() {
use std::str::FromStr;

assert_eq!(VKey::from_str("BACK").unwrap(), VKey::Back);
assert_eq!(VKey::from_str("VK_BACK").unwrap(), VKey::Back);
assert_eq!(VKey::from_str("INVALID_KEY").is_err(), true);
Expand Down

0 comments on commit e4f0984

Please sign in to comment.