Skip to content

Commit

Permalink
Merge pull request #247 from pentamassiv/unlisted_keys
Browse files Browse the repository at this point in the history
All: Allow using unlisted keys
  • Loading branch information
pentamassiv authored Nov 18, 2023
2 parents edd7136 + 5da6e50 commit 9e986aa
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "enigo"
version = "0.2.0-rc1"
version = "0.2.0-rc2"
authors = [
"pentamassiv <[email protected]>",
"Dustin Bensing <[email protected]>",
Expand Down
22 changes: 18 additions & 4 deletions src/keycodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use serde::{Deserialize, Serialize};
// A key on the keyboard.
/// Use [`Key::Unicode`] to enter arbitrary Unicode chars.
/// If a key is missing, please open an issue in our repo and we will quickly
/// add it. In the mean time, you can simulate that key by using the
/// [`crate::Keyboard::raw`] function. Some of the keys are only
/// add it. In the mean time, you can simulate that key by using [`Key::Other`]
/// or the [`crate::Keyboard::raw`] function. Some of the keys are only
/// available on a specific platform. Use conditional compilation to use them.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -573,6 +573,13 @@ pub enum Key {
/// Unicode character
#[doc(alias = "Layout")]
Unicode(char),
/// Use this for keys that are not listed here that you know the
/// value of. Let us know if you think the key should be listed so
/// we can add it
/// On Linux, this will result in a keysym,
/// On Windows, this will result in a Virtual_Key and
/// On macOS, this will yield a KeyCode
Other(u32),
}

#[cfg(target_os = "linux")]
Expand Down Expand Up @@ -674,6 +681,7 @@ impl From<Key> for xkeysym::Keysym {
Key::VolumeUp => Keysym::XF86_AudioRaiseVolume,
Key::VolumeMute => Keysym::XF86_AudioMute,
Key::Command | Key::Super | Key::Windows | Key::Meta => Keysym::Super_L,
Key::Other(v) => Keysym::from(v),
}
}
}
Expand All @@ -686,8 +694,8 @@ impl TryFrom<Key> for windows::Win32::UI::Input::KeyboardAndMouse::VIRTUAL_KEY {
#[allow(clippy::too_many_lines)]
fn try_from(key: Key) -> Result<Self, Self::Error> {
use windows::Win32::UI::Input::KeyboardAndMouse::{
VK__none_, VK_0, VK_1, VK_2, VK_3, VK_4, VK_5, VK_6, VK_7, VK_8, VK_9, VK_A,
VK_ABNT_C1, VK_ABNT_C2, VK_ACCEPT, VK_ADD, VK_APPS, VK_ATTN, VK_B, VK_BACK,
VK__none_, VIRTUAL_KEY, VK_0, VK_1, VK_2, VK_3, VK_4, VK_5, VK_6, VK_7, VK_8, VK_9,
VK_A, VK_ABNT_C1, VK_ABNT_C2, VK_ACCEPT, VK_ADD, VK_APPS, VK_ATTN, VK_B, VK_BACK,
VK_BROWSER_BACK, VK_BROWSER_FAVORITES, VK_BROWSER_FORWARD, VK_BROWSER_HOME,
VK_BROWSER_REFRESH, VK_BROWSER_SEARCH, VK_BROWSER_STOP, VK_C, VK_CANCEL, VK_CAPITAL,
VK_CLEAR, VK_CONTROL, VK_CONVERT, VK_CRSEL, VK_D, VK_DBE_ALPHANUMERIC,
Expand Down Expand Up @@ -978,6 +986,12 @@ impl TryFrom<Key> for windows::Win32::UI::Input::KeyboardAndMouse::VIRTUAL_KEY {
Key::XButton2 => VK_XBUTTON2,
Key::Zoom => VK_ZOOM,
Key::Unicode(_) => return Err("Unicode must be entered via scancodes"),
Key::Other(v) => {
let Ok(v) = u16::try_from(v) else {
return Err("virtual keycodes on Windows have to fit into u16");
};
VIRTUAL_KEY(v)
}
Key::Super | Key::Command | Key::Windows | Key::Meta | Key::LWin => VK_LWIN,
};

Expand Down
24 changes: 18 additions & 6 deletions src/macos/macos_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,11 @@ impl Keyboard for Enigo {
return Ok(());
}

let keycode = CGKeyCode::from(key);
let Ok(keycode) = CGKeyCode::try_from(key) else {
return Err(InputError::InvalidInput(
"virtual keycodes on macOS have to fit into u16",
));
};
self.raw(keycode, direction)?;

// TODO: The list of keys will contain the key and also the associated keycode.
Expand Down Expand Up @@ -501,14 +505,15 @@ impl Enigo {
}

/// Converts a `Key` to a `CGKeyCode`
#[cfg(target_os = "macos")]
impl From<Key> for core_graphics::event::CGKeyCode {
impl TryFrom<Key> for core_graphics::event::CGKeyCode {
type Error = ();

#[allow(clippy::too_many_lines)]
fn from(key: Key) -> Self {
fn try_from(key: Key) -> Result<Self, Self::Error> {
// A list of names is available at:
// https://docs.rs/core-graphics/latest/core_graphics/event/struct.KeyCode.html
// https://github.com/phracker/MacOSX-SDKs/blob/master/MacOSX10.13.sdk/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h
match key {
let key = match key {
Key::Alt | Key::Option => KeyCode::OPTION,
Key::Backspace => KeyCode::DELETE,
Key::CapsLock => KeyCode::CAPS_LOCK,
Expand Down Expand Up @@ -559,8 +564,15 @@ impl From<Key> for core_graphics::event::CGKeyCode {
Key::VolumeUp => KeyCode::VOLUME_UP,
Key::VolumeMute => KeyCode::MUTE,
Key::Unicode(c) => get_layoutdependent_keycode(&c.to_string()),
Key::Other(v) => {
let Ok(v) = u16::try_from(v) else {
return Err(());
};
v
}
Key::Super | Key::Command | Key::Windows | Key::Meta => KeyCode::COMMAND,
}
};
Ok(key)
}
}

Expand Down

0 comments on commit 9e986aa

Please sign in to comment.