diff --git a/GET_STARTED.md b/GET_STARTED.md index 548a5e9..a793041 100644 --- a/GET_STARTED.md +++ b/GET_STARTED.md @@ -1,6 +1,6 @@ # Get Started -The default hotkey for Qopy is Windows+V which is also the hotkey for the default clipboard manager to turn that off follow [this guide](https://github.com/0PandaDEV/Qopy/blob/main/GET_STARTED.md#disable-windowsv-for-default-clipboard-manager). +The default hotkey for Qopy is Windows+V which is also the hotkey for the default clipboard manager to turn that off follow [this guide](https://github.com/0PandaDEV/Qopy/blob/main/GET_STARTED.md#disable-windowsv-for-default-clipboard-manager). All the data of Qopy is stored inside of a SQLite database. @@ -12,7 +12,7 @@ All the data of Qopy is stored inside of a SQLite database. ## Disable Windows+V for default clipboard manager -https://github.com/user-attachments/assets/723f9e07-3190-46ec-9bb7-15dfc112f620 + To disable the default clipboard manager popup from windows open Command prompt and run this command diff --git a/pages/settings.vue b/pages/settings.vue index cf4771e..7a20eb1 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -33,7 +33,6 @@
@@ -44,7 +43,7 @@ class="key" :class="{ modifier: isModifier(key) }" v-for="(key, index) in keybind"> - {{ keyToDisplay(key) }} + {{ keyToLabel(key) }}
@@ -58,10 +57,11 @@ import { onMounted, onUnmounted, reactive, ref } from "vue"; import { platform } from "@tauri-apps/plugin-os"; import { useRouter } from "vue-router"; import { Key } from "wrdu-keyboard/key"; +import { KeyValues, KeyLabels } from "../types/keys"; -const activeModifiers = reactive>(new Set()); +const activeModifiers = reactive>(new Set()); const isKeybindInputFocused = ref(false); -const keybind = ref([]); +const keybind = ref([]); const keybindInput = ref(null); const lastBlurTime = ref(0); const os = ref(""); @@ -69,52 +69,27 @@ const router = useRouter(); const keyboard = useKeyboard(); const showEmptyKeybindError = ref(false); -const keyToDisplayMap: Record = { - " ": "Space", - Alt: "Alt", - AltLeft: "Alt L", - AltRight: "Alt R", - ArrowDown: "↓", - ArrowLeft: "←", - ArrowRight: "→", - ArrowUp: "↑", - Control: "Ctrl", - ControlLeft: "Ctrl L", - ControlRight: "Ctrl R", - Enter: "↵", - Meta: "Meta", - MetaLeft: "Meta L", - MetaRight: "Meta R", - Shift: "⇧", - ShiftLeft: "⇧ L", - ShiftRight: "⇧ R", -}; - const modifierKeySet = new Set([ - "Alt", - "AltLeft", - "AltRight", - "Control", - "ControlLeft", - "ControlRight", - "Meta", - "MetaLeft", - "MetaRight", - "Shift", - "ShiftLeft", - "ShiftRight", + KeyValues.AltLeft, + KeyValues.AltRight, + KeyValues.ControlLeft, + KeyValues.ControlRight, + KeyValues.MetaLeft, + KeyValues.MetaRight, + KeyValues.ShiftLeft, + KeyValues.ShiftRight, ]); -const isModifier = (key: string): boolean => { +const isModifier = (key: KeyValues): boolean => { return modifierKeySet.has(key); }; -const keyToDisplay = (key: string): string => { - return keyToDisplayMap[key] || key; +const keyToLabel = (key: KeyValues): string => { + return KeyLabels[key] || key; }; const updateKeybind = () => { - const modifiers = Array.from(activeModifiers).sort(); + const modifiers = Array.from(activeModifiers); const nonModifiers = keybind.value.filter((key) => !isModifier(key)); keybind.value = [...modifiers, ...nonModifiers]; }; @@ -133,9 +108,9 @@ const onFocus = () => { }; const onKeyDown = (event: KeyboardEvent) => { - const key = event.code; + const key = event.code as KeyValues; - if (key === "Escape") { + if (key === KeyValues.Escape) { if (keybindInput.value) { keybindInput.value.blur(); } @@ -155,8 +130,7 @@ const onKeyDown = (event: KeyboardEvent) => { const saveKeybind = async () => { if (keybind.value.length > 0) { - console.log("Saving keybind", keybind.value); - await invoke("save_keybind", { keybind: keybind }); + await invoke("save_keybind", { keybind: keybind.value }); } else { showEmptyKeybindError.value = true; } @@ -165,8 +139,13 @@ const saveKeybind = async () => { os.value = platform(); onMounted(() => { + keyboard.down([Key.All], (event) => { + if (isKeybindInputFocused.value) { + onKeyDown(event); + } + }); + keyboard.down([Key.Escape], (event) => { - console.log("Escape key pressed"); if (isKeybindInputFocused.value) { keybindInput.value?.blur(); } else { diff --git a/patches/wrdu-keyboard@3.0.0.patch b/patches/wrdu-keyboard@3.0.0.patch index e973647..bc77583 100644 --- a/patches/wrdu-keyboard@3.0.0.patch +++ b/patches/wrdu-keyboard@3.0.0.patch @@ -1,6 +1,6 @@ diff --git a/node_modules/wrdu-keyboard/.DS_Store b/.DS_Store new file mode 100644 -index 0000000000000000000000000000000000000000..fabbd951c2d14c46fd10fa167b8836d116bc0db6 +index 0000000000000000000000000000000000000000..4b7e9446f3580fab3e4feaba097bcdaf98c5833c Binary files /dev/null and b/.DS_Store differ diff --git a/dist/runtime/keyboard.d.ts b/dist/runtime/keyboard.d.ts index aeae40f3d2bc3efd459cce04c29c21c43884154d..6131bab4895ebb3048a5225f366430d23c5f1f13 100644 @@ -27,10 +27,10 @@ index aeae40f3d2bc3efd459cce04c29c21c43884154d..6131bab4895ebb3048a5225f366430d2 up: New; prevent: { diff --git a/dist/runtime/keyboard.js b/dist/runtime/keyboard.js -index e16f600258cee90d185ffc52777bed95c14bd93e..e4ce2678db649ec82e5a67fcdb74f5cdb37820aa 100644 +index e16f600258cee90d185ffc52777bed95c14bd93e..5ddec447a5dc66ffe063eb9f9dd765c9045bdaf7 100644 --- a/dist/runtime/keyboard.js +++ b/dist/runtime/keyboard.js -@@ -1,13 +1,14 @@ +@@ -1,45 +1,54 @@ import { Key } from "./types/keys.js"; import { defineNuxtPlugin } from "#app"; -const getKeyString = (keys) => keys[0] == Key.All ? keys.sort().join("+") : "All"; @@ -45,18 +45,31 @@ index e16f600258cee90d185ffc52777bed95c14bd93e..e4ce2678db649ec82e5a67fcdb74f5cd + const key = event.code; + pressedKeys.add(key); const pressedArray = Array.from(pressedKeys); - const keyString = getKeyString(pressedArray); - if (handlers.down[keyString]) { -@@ -17,13 +18,16 @@ const onKeydown = (event) => { - } - eventHandler.handler(event); - if (eventHandler.once) { +- const keyString = getKeyString(pressedArray); +- if (handlers.down[keyString]) { +- handlers.down[keyString].forEach((eventHandler) => { +- if (eventHandler.prevent) { +- event.preventDefault(); +- } +- eventHandler.handler(event); +- if (eventHandler.once) { - handlers.down[keyString] = handlers.down[keyString].filter((h) => h !== eventHandler); -+ handlers.down[keyString] = handlers.down[keyString].filter( -+ (h) => h !== eventHandler -+ ); - } - }); +- } +- }); ++ for (const keyString of [getKeyString(pressedArray), "All"]) { ++ if (handlers.down[keyString]) { ++ handlers.down[keyString].forEach((eventHandler) => { ++ if (eventHandler.prevent) { ++ event.preventDefault(); ++ } ++ eventHandler.handler(event); ++ if (eventHandler.once) { ++ handlers.down[keyString] = handlers.down[keyString].filter( ++ (h) => h !== eventHandler ++ ); ++ } ++ }); ++ } } }; const onKeyup = (event) => { @@ -64,18 +77,31 @@ index e16f600258cee90d185ffc52777bed95c14bd93e..e4ce2678db649ec82e5a67fcdb74f5cd + const key = event.code; + pressedKeys.delete(key); const releasedArray = Array.from(pressedKeys); - const keyString = getKeyString(releasedArray); - if (handlers.up[keyString]) { -@@ -33,13 +37,16 @@ const onKeyup = (event) => { - } - eventHandler.handler(event); - if (eventHandler.once) { +- const keyString = getKeyString(releasedArray); +- if (handlers.up[keyString]) { +- handlers.up[keyString].forEach((eventHandler) => { +- if (eventHandler.prevent) { +- event.preventDefault(); +- } +- eventHandler.handler(event); +- if (eventHandler.once) { - handlers.up[keyString] = handlers.up[keyString].filter((h) => h !== eventHandler); -+ handlers.up[keyString] = handlers.up[keyString].filter( -+ (h) => h !== eventHandler -+ ); - } - }); +- } +- }); ++ for (const keyString of [getKeyString(releasedArray), "All"]) { ++ if (handlers.up[keyString]) { ++ handlers.up[keyString].forEach((eventHandler) => { ++ if (eventHandler.prevent) { ++ event.preventDefault(); ++ } ++ eventHandler.handler(event); ++ if (eventHandler.once) { ++ handlers.up[keyString] = handlers.up[keyString].filter( ++ (h) => h !== eventHandler ++ ); ++ } ++ }); ++ } } }; const init = () => { @@ -84,36 +110,18 @@ index e16f600258cee90d185ffc52777bed95c14bd93e..e4ce2678db649ec82e5a67fcdb74f5cd window.addEventListener("keydown", onKeydown); window.addEventListener("keyup", onKeyup); }; -@@ -47,6 +54,20 @@ const stop = () => { +@@ -47,6 +56,10 @@ const stop = () => { window.removeEventListener("keydown", onKeydown); window.removeEventListener("keyup", onKeyup); }; +const unregisterAll = () => { -+ Object.keys(handlers.down).forEach((key) => { -+ handlers.down[key].forEach((handler) => { -+ console.log(`Unregistering ${key} ${handler.handler.toString()}`); -+ }); -+ }); -+ Object.keys(handlers.up).forEach((key) => { -+ handlers.up[key].forEach((handler) => { -+ console.log(`Unregistering ${key} ${handler.handler.toString()}`); -+ }); -+ }); + handlers.down = {}; + handlers.up = {}; +}; const down = (keys, handler, config = {}) => { if (keys.includes(Key.All)) { keys = [Key.All]; -@@ -59,6 +80,7 @@ const down = (keys, handler, config = {}) => { - handlers.down[key] = []; - } - const { once = false, prevent = false } = config; -+ console.log(key, handler.toString()); - handlers.down[key].push({ handler, prevent, once }); - }; - const up = (keys, handler, config = {}) => { -@@ -84,6 +106,7 @@ const keyboard = defineNuxtPlugin((nuxtApp) => { +@@ -84,6 +97,7 @@ const keyboard = defineNuxtPlugin((nuxtApp) => { keyboard: { init, stop, diff --git a/src-tauri/src/api/hotkeys.rs b/src-tauri/src/api/hotkeys.rs index 0470e24..52a276b 100644 --- a/src-tauri/src/api/hotkeys.rs +++ b/src-tauri/src/api/hotkeys.rs @@ -1,48 +1,61 @@ -use tauri_plugin_aptabase::EventTracker; use crate::utils::commands::center_window_on_current_monitor; +use crate::utils::keys::KeyCode; use global_hotkey::{ hotkey::{Code, HotKey, Modifiers}, GlobalHotKeyEvent, GlobalHotKeyManager, HotKeyState, }; -use std::cell::RefCell; +use lazy_static::lazy_static; use std::str::FromStr; +use std::sync::Mutex; use tauri::{AppHandle, Listener, Manager}; +use tauri_plugin_aptabase::EventTracker; -thread_local! { - static HOTKEY_MANAGER: RefCell> = RefCell::new(None); +lazy_static! { + static ref HOTKEY_MANAGER: Mutex> = Mutex::new(None); + static ref REGISTERED_HOTKEYS: Mutex> = Mutex::new(Vec::new()); } pub fn setup(app_handle: tauri::AppHandle) { let app_handle_clone = app_handle.clone(); - let manager = GlobalHotKeyManager::new().expect("Failed to initialize hotkey manager"); - HOTKEY_MANAGER.with(|m| *m.borrow_mut() = Some(manager)); + let manager = match GlobalHotKeyManager::new() { + Ok(manager) => manager, + Err(err) => { + eprintln!("Failed to initialize hotkey manager: {:?}", err); + return; + } + }; + + { + let mut manager_guard = HOTKEY_MANAGER.lock().unwrap(); + *manager_guard = Some(manager); + } let rt = app_handle.state::(); let initial_keybind = rt .block_on(crate::db::settings::get_keybind(app_handle_clone.clone())) .expect("Failed to get initial keybind"); - let initial_shortcut = initial_keybind.join("+"); - let initial_shortcut_for_update = initial_shortcut.clone(); - let initial_shortcut_for_save = initial_shortcut.clone(); + let initial_shortcut_for_update = initial_keybind.clone(); + let initial_shortcut_for_save = initial_keybind.clone(); - if let Err(e) = register_shortcut(&initial_shortcut) { + if let Err(e) = register_shortcut(&initial_keybind) { eprintln!("Error registering initial shortcut: {:?}", e); } app_handle.listen("update-shortcut", move |event| { - let payload_str = event.payload().to_string(); + let payload_str = event.payload(); if let Ok(old_hotkey) = parse_hotkey(&initial_shortcut_for_update) { - HOTKEY_MANAGER.with(|manager| { - if let Some(manager) = manager.borrow().as_ref() { - let _ = manager.unregister(old_hotkey); - } - }); + let manager_guard = HOTKEY_MANAGER.lock().unwrap(); + if let Some(manager) = manager_guard.as_ref() { + let _ = manager.unregister(old_hotkey); + } } - if let Err(e) = register_shortcut(&payload_str) { + let payload: Vec = serde_json::from_str(payload_str).unwrap_or_default(); + + if let Err(e) = register_shortcut(&payload) { eprintln!("Error re-registering shortcut: {:?}", e); } }); @@ -51,14 +64,14 @@ pub fn setup(app_handle: tauri::AppHandle) { let payload_str = event.payload().to_string(); if let Ok(old_hotkey) = parse_hotkey(&initial_shortcut_for_save) { - HOTKEY_MANAGER.with(|manager| { - if let Some(manager) = manager.borrow().as_ref() { - let _ = manager.unregister(old_hotkey); - } - }); + let manager_guard = HOTKEY_MANAGER.lock().unwrap(); + if let Some(manager) = manager_guard.as_ref() { + let _ = manager.unregister(old_hotkey); + } } - if let Err(e) = register_shortcut(&payload_str) { + let payload: Vec = serde_json::from_str(&payload_str).unwrap_or_default(); + if let Err(e) = register_shortcut(&payload) { eprintln!("Error registering saved shortcut: {:?}", e); } }); @@ -81,48 +94,36 @@ pub fn setup(app_handle: tauri::AppHandle) { }); } -fn register_shortcut(shortcut: &str) -> Result<(), Box> { +fn register_shortcut(shortcut: &[String]) -> Result<(), Box> { let hotkey = parse_hotkey(shortcut)?; - HOTKEY_MANAGER.with(|manager| { - if let Some(manager) = manager.borrow().as_ref() { - manager.register(hotkey)?; - } + + let manager_guard = HOTKEY_MANAGER.lock().unwrap(); + if let Some(manager) = manager_guard.as_ref() { + manager.register(hotkey.clone())?; + REGISTERED_HOTKEYS.lock().unwrap().push(hotkey); Ok(()) - }) + } else { + Err("Hotkey manager not initialized".into()) + } } -fn parse_hotkey(shortcut: &str) -> Result> { +fn parse_hotkey(shortcut: &[String]) -> Result> { let mut modifiers = Modifiers::empty(); let mut code = None; - let shortcut = shortcut.replace("\"", ""); - - for part in shortcut.split('+') { - let part = part.trim().to_lowercase(); + for part in shortcut { match part.as_str() { - "ctrl" | "control" | "controlleft" => modifiers |= Modifiers::CONTROL, - "alt" | "altleft" | "optionleft" => modifiers |= Modifiers::ALT, - "shift" | "shiftleft" => modifiers |= Modifiers::SHIFT, - "super" | "meta" | "cmd" | "metaleft" => modifiers |= Modifiers::META, + "ControlLeft" => modifiers |= Modifiers::CONTROL, + "AltLeft" => modifiers |= Modifiers::ALT, + "ShiftLeft" => modifiers |= Modifiers::SHIFT, + "MetaLeft" => modifiers |= Modifiers::META, key => { - let key_code = if key.starts_with("key") { - "Key".to_string() + &key[3..].to_uppercase() - } else if key.len() == 1 && key.chars().next().unwrap().is_alphabetic() { - "Key".to_string() + &key.to_uppercase() - } else { - key.to_string() - }; - - code = Some( - Code::from_str(&key_code) - .map_err(|_| format!("Invalid key code: {}", key_code))?, - ); + code = Some(Code::from(KeyCode::from_str(key)?)); } } } - let key_code = - code.ok_or_else(|| format!("No valid key code found in shortcut: {}", shortcut))?; + let key_code = code.ok_or_else(|| "No valid key code found".to_string())?; Ok(HotKey::new(Some(modifiers), key_code)) } @@ -144,7 +145,10 @@ fn handle_hotkey_event(app_handle: &AppHandle) { center_window_on_current_monitor(&window); } - let _ = app_handle.track_event("hotkey_triggered", Some(serde_json::json!({ - "action": if window.is_visible().unwrap() { "hide" } else { "show" } - }))); + let _ = app_handle.track_event( + "hotkey_triggered", + Some(serde_json::json!({ + "action": if window.is_visible().unwrap() { "hide" } else { "show" } + })), + ); } diff --git a/src-tauri/src/db/settings.rs b/src-tauri/src/db/settings.rs index bdd6f58..7fedf8c 100644 --- a/src-tauri/src/db/settings.rs +++ b/src-tauri/src/db/settings.rs @@ -30,11 +30,8 @@ pub async fn save_keybind( pool: tauri::State<'_, SqlitePool>, keybind: Vec, ) -> Result<(), String> { - let keybind_str = keybind.join("+"); - let keybind_clone = keybind_str.clone(); - app_handle - .emit("update-shortcut", &keybind_str) + .emit("update-shortcut", &keybind) .map_err(|e| e.to_string())?; let json = serde_json::to_string(&keybind).map_err(|e| e.to_string())?; @@ -46,7 +43,7 @@ pub async fn save_keybind( .map_err(|e| e.to_string())?; let _ = app_handle.track_event("keybind_saved", Some(serde_json::json!({ - "keybind": keybind_clone + "keybind": keybind }))); Ok(()) @@ -97,7 +94,7 @@ pub async fn get_keybind(app_handle: tauri::AppHandle) -> Result, St .map_err(|e| e.to_string())?; let json = row.map(|r| r.get::("value")).unwrap_or_else(|| { - serde_json::to_string(&vec!["Meta".to_string(), "V".to_string()]) + serde_json::to_string(&vec!["MetaLeft".to_string(), "KeyV".to_string()]) .expect("Failed to serialize default keybind") }); diff --git a/src-tauri/src/utils/keys.rs b/src-tauri/src/utils/keys.rs new file mode 100644 index 0000000..fffacdd --- /dev/null +++ b/src-tauri/src/utils/keys.rs @@ -0,0 +1,118 @@ +use global_hotkey::hotkey::Code; +use std::str::FromStr; + +pub struct KeyCode(Code); + +impl FromStr for KeyCode { + type Err = String; + + fn from_str(s: &str) -> Result { + let code = match s { + "Backquote" => Code::Backquote, + "Backslash" => Code::Backslash, + "BracketLeft" => Code::BracketLeft, + "BracketRight" => Code::BracketRight, + "Comma" => Code::Comma, + "Digit0" => Code::Digit0, + "Digit1" => Code::Digit1, + "Digit2" => Code::Digit2, + "Digit3" => Code::Digit3, + "Digit4" => Code::Digit4, + "Digit5" => Code::Digit5, + "Digit6" => Code::Digit6, + "Digit7" => Code::Digit7, + "Digit8" => Code::Digit8, + "Digit9" => Code::Digit9, + "Equal" => Code::Equal, + "KeyA" => Code::KeyA, + "KeyB" => Code::KeyB, + "KeyC" => Code::KeyC, + "KeyD" => Code::KeyD, + "KeyE" => Code::KeyE, + "KeyF" => Code::KeyF, + "KeyG" => Code::KeyG, + "KeyH" => Code::KeyH, + "KeyI" => Code::KeyI, + "KeyJ" => Code::KeyJ, + "KeyK" => Code::KeyK, + "KeyL" => Code::KeyL, + "KeyM" => Code::KeyM, + "KeyN" => Code::KeyN, + "KeyO" => Code::KeyO, + "KeyP" => Code::KeyP, + "KeyQ" => Code::KeyQ, + "KeyR" => Code::KeyR, + "KeyS" => Code::KeyS, + "KeyT" => Code::KeyT, + "KeyU" => Code::KeyU, + "KeyV" => Code::KeyV, + "KeyW" => Code::KeyW, + "KeyX" => Code::KeyX, + "KeyY" => Code::KeyY, + "KeyZ" => Code::KeyZ, + "Minus" => Code::Minus, + "Period" => Code::Period, + "Quote" => Code::Quote, + "Semicolon" => Code::Semicolon, + "Slash" => Code::Slash, + "Backspace" => Code::Backspace, + "CapsLock" => Code::CapsLock, + "Delete" => Code::Delete, + "Enter" => Code::Enter, + "Space" => Code::Space, + "Tab" => Code::Tab, + "End" => Code::End, + "Home" => Code::Home, + "Insert" => Code::Insert, + "PageDown" => Code::PageDown, + "PageUp" => Code::PageUp, + "ArrowDown" => Code::ArrowDown, + "ArrowLeft" => Code::ArrowLeft, + "ArrowRight" => Code::ArrowRight, + "ArrowUp" => Code::ArrowUp, + "NumLock" => Code::NumLock, + "Numpad0" => Code::Numpad0, + "Numpad1" => Code::Numpad1, + "Numpad2" => Code::Numpad2, + "Numpad3" => Code::Numpad3, + "Numpad4" => Code::Numpad4, + "Numpad5" => Code::Numpad5, + "Numpad6" => Code::Numpad6, + "Numpad7" => Code::Numpad7, + "Numpad8" => Code::Numpad8, + "Numpad9" => Code::Numpad9, + "NumpadAdd" => Code::NumpadAdd, + "NumpadDecimal" => Code::NumpadDecimal, + "NumpadDivide" => Code::NumpadDivide, + "NumpadMultiply" => Code::NumpadMultiply, + "NumpadSubtract" => Code::NumpadSubtract, + "Escape" => Code::Escape, + "PrintScreen" => Code::PrintScreen, + "ScrollLock" => Code::ScrollLock, + "Pause" => Code::Pause, + "AudioVolumeDown" => Code::AudioVolumeDown, + "AudioVolumeMute" => Code::AudioVolumeMute, + "AudioVolumeUp" => Code::AudioVolumeUp, + "F1" => Code::F1, + "F2" => Code::F2, + "F3" => Code::F3, + "F4" => Code::F4, + "F5" => Code::F5, + "F6" => Code::F6, + "F7" => Code::F7, + "F8" => Code::F8, + "F9" => Code::F9, + "F10" => Code::F10, + "F11" => Code::F11, + "F12" => Code::F12, + _ => return Err(format!("Unknown key code: {}", s)), + }; + Ok(KeyCode(code)) + } +} + +impl From for Code { + fn from(key_code: KeyCode) -> Self { + key_code.0 + } +} diff --git a/src-tauri/src/utils/mod.rs b/src-tauri/src/utils/mod.rs index b888b1f..9554229 100644 --- a/src-tauri/src/utils/mod.rs +++ b/src-tauri/src/utils/mod.rs @@ -2,3 +2,4 @@ pub mod commands; pub mod favicon; pub mod types; pub mod logger; +pub mod keys; \ No newline at end of file diff --git a/types/keys.ts b/types/keys.ts new file mode 100644 index 0000000..d81454f --- /dev/null +++ b/types/keys.ts @@ -0,0 +1,217 @@ +export enum KeyValues { + Backquote = 'Backquote', + Backslash = 'Backslash', + BracketLeft = 'BracketLeft', + BracketRight = 'BracketRight', + Comma = 'Comma', + Digit0 = 'Digit0', + Digit1 = 'Digit1', + Digit2 = 'Digit2', + Digit3 = 'Digit3', + Digit4 = 'Digit4', + Digit5 = 'Digit5', + Digit6 = 'Digit6', + Digit7 = 'Digit7', + Digit8 = 'Digit8', + Digit9 = 'Digit9', + Equal = 'Equal', + KeyA = 'KeyA', + KeyB = 'KeyB', + KeyC = 'KeyC', + KeyD = 'KeyD', + KeyE = 'KeyE', + KeyF = 'KeyF', + KeyG = 'KeyG', + KeyH = 'KeyH', + KeyI = 'KeyI', + KeyJ = 'KeyJ', + KeyK = 'KeyK', + KeyL = 'KeyL', + KeyM = 'KeyM', + KeyN = 'KeyN', + KeyO = 'KeyO', + KeyP = 'KeyP', + KeyQ = 'KeyQ', + KeyR = 'KeyR', + KeyS = 'KeyS', + KeyT = 'KeyT', + KeyU = 'KeyU', + KeyV = 'KeyV', + KeyW = 'KeyW', + KeyX = 'KeyX', + KeyY = 'KeyY', + KeyZ = 'KeyZ', + Minus = 'Minus', + Period = 'Period', + Quote = 'Quote', + Semicolon = 'Semicolon', + Slash = 'Slash', + AltLeft = 'AltLeft', + AltRight = 'AltRight', + Backspace = 'Backspace', + CapsLock = 'CapsLock', + ContextMenu = 'ContextMenu', + ControlLeft = 'ControlLeft', + ControlRight = 'ControlRight', + Enter = 'Enter', + MetaLeft = 'MetaLeft', + MetaRight = 'MetaRight', + ShiftLeft = 'ShiftLeft', + ShiftRight = 'ShiftRight', + Space = 'Space', + Tab = 'Tab', + Delete = 'Delete', + End = 'End', + Home = 'Home', + Insert = 'Insert', + PageDown = 'PageDown', + PageUp = 'PageUp', + ArrowDown = 'ArrowDown', + ArrowLeft = 'ArrowLeft', + ArrowRight = 'ArrowRight', + ArrowUp = 'ArrowUp', + NumLock = 'NumLock', + Numpad0 = 'Numpad0', + Numpad1 = 'Numpad1', + Numpad2 = 'Numpad2', + Numpad3 = 'Numpad3', + Numpad4 = 'Numpad4', + Numpad5 = 'Numpad5', + Numpad6 = 'Numpad6', + Numpad7 = 'Numpad7', + Numpad8 = 'Numpad8', + Numpad9 = 'Numpad9', + NumpadAdd = 'NumpadAdd', + NumpadDecimal = 'NumpadDecimal', + NumpadDivide = 'NumpadDivide', + NumpadMultiply = 'NumpadMultiply', + NumpadSubtract = 'NumpadSubtract', + Escape = 'Escape', + PrintScreen = 'PrintScreen', + ScrollLock = 'ScrollLock', + Pause = 'Pause', + AudioVolumeDown = 'AudioVolumeDown', + AudioVolumeMute = 'AudioVolumeMute', + AudioVolumeUp = 'AudioVolumeUp', + F1 = 'F1', + F2 = 'F2', + F3 = 'F3', + F4 = 'F4', + F5 = 'F5', + F6 = 'F6', + F7 = 'F7', + F8 = 'F8', + F9 = 'F9', + F10 = 'F10', + F11 = 'F11', + F12 = 'F12', +} + +export enum KeyLabels { + Backquote = '`', + Backslash = '\\', + BracketLeft = '[', + BracketRight = ']', + Comma = ',', + Digit0 = '0', + Digit1 = '1', + Digit2 = '2', + Digit3 = '3', + Digit4 = '4', + Digit5 = '5', + Digit6 = '6', + Digit7 = '7', + Digit8 = '8', + Digit9 = '9', + Equal = '=', + KeyA = 'A', + KeyB = 'B', + KeyC = 'C', + KeyD = 'D', + KeyE = 'E', + KeyF = 'F', + KeyG = 'G', + KeyH = 'H', + KeyI = 'I', + KeyJ = 'J', + KeyK = 'K', + KeyL = 'L', + KeyM = 'M', + KeyN = 'N', + KeyO = 'O', + KeyP = 'P', + KeyQ = 'Q', + KeyR = 'R', + KeyS = 'S', + KeyT = 'T', + KeyU = 'U', + KeyV = 'V', + KeyW = 'W', + KeyX = 'X', + KeyY = 'Y', + KeyZ = 'Z', + Minus = '-', + Period = '.', + Quote = "'", + Semicolon = ';', + Slash = '/', + AltLeft = 'Alt', + AltRight = 'Alt (Right)', + Backspace = 'Backspace', + CapsLock = 'Caps Lock', + ContextMenu = 'Context Menu', + ControlLeft = 'Ctrl', + ControlRight = 'Ctrl (Right)', + Enter = 'Enter', + MetaLeft = 'Meta', + MetaRight = 'Meta (Right)', + ShiftLeft = 'Shift', + ShiftRight = 'Shift (Right)', + Space = 'Space', + Tab = 'Tab', + Delete = 'Delete', + End = 'End', + Home = 'Home', + Insert = 'Insert', + PageDown = 'Page Down', + PageUp = 'Page Up', + ArrowDown = '↓', + ArrowLeft = '←', + ArrowRight = '→', + ArrowUp = '↑', + NumLock = 'Num Lock', + Numpad0 = 'Numpad 0', + Numpad1 = 'Numpad 1', + Numpad2 = 'Numpad 2', + Numpad3 = 'Numpad 3', + Numpad4 = 'Numpad 4', + Numpad5 = 'Numpad 5', + Numpad6 = 'Numpad 6', + Numpad7 = 'Numpad 7', + Numpad8 = 'Numpad 8', + Numpad9 = 'Numpad 9', + NumpadAdd = 'Numpad +', + NumpadDecimal = 'Numpad .', + NumpadDivide = 'Numpad /', + NumpadMultiply = 'Numpad *', + NumpadSubtract = 'Numpad -', + Escape = 'Esc', + PrintScreen = 'Print Screen', + ScrollLock = 'Scroll Lock', + Pause = 'Pause', + AudioVolumeDown = 'Volume Down', + AudioVolumeMute = 'Volume Mute', + AudioVolumeUp = 'Volume Up', + F1 = 'F1', + F2 = 'F2', + F3 = 'F3', + F4 = 'F4', + F5 = 'F5', + F6 = 'F6', + F7 = 'F7', + F8 = 'F8', + F9 = 'F9', + F10 = 'F10', + F11 = 'F11', + F12 = 'F12', +} \ No newline at end of file