# Key codes enumeration
import enum
import re
# Matches the special <code[number]> syntax, like <code86> for non-printable or unknown keys.
_code_point_re = re.compile(r"<code(0|[1-9][0-9]*)>", re.UNICODE)
[docs]
@enum.unique
class Key(str, enum.Enum):
LEFT = "<left>"
RIGHT = "<right>"
UP = "<up>"
DOWN = "<down>"
BACKSPACE = "<backspace>"
TAB = "<tab>"
ENTER = "<enter>"
SCROLL_LOCK = "<scroll_lock>"
PRINT_SCREEN = "<print_screen>"
PAUSE = "<pause>"
MENU = "<menu>"
# Modifier keys
CONTROL = "<ctrl>"
ALT = "<alt>"
ALT_GR = "<alt_gr>"
SHIFT = "<shift>"
SUPER = "<super>"
HYPER = "<hyper>"
CAPSLOCK = "<capslock>"
NUMLOCK = "<numlock>"
META = "<meta>"
# Left Modifier Keys
LEFTCONTROL = "<left_ctrl>"
LEFTALT = "<left_alt>"
LEFTSHIFT = "<left_shift>"
LEFTSUPER = "<left_super>"
LEFTHYPER = "<left_hyper>"
LEFTCAPSLOCK = "<left_capslock>"
LEFTNUMLOCK = "<left_numlock>"
LEFTMETA = "<left_meta>"
# Right Modifier Keys
RIGHTCONTROL = "<right_ctrl>"
RIGHTALT = "<right_alt>"
RIGHTSHIFT = "<right_shift>"
RIGHTSUPER = "<right_super>"
RIGHTHYPER = "<right_hyper>"
RIGHTCAPSLOCK = "<right_capslock>"
RIGHTNUMLOCK = "<right_numlock>"
RIGHTMETA = "<right_meta>"
F1 = "<f1>"
F2 = "<f2>"
F3 = "<f3>"
F4 = "<f4>"
F5 = "<f5>"
F6 = "<f6>"
F7 = "<f7>"
F8 = "<f8>"
F9 = "<f9>"
F10 = "<f10>"
F11 = "<f11>"
F12 = "<f12>"
F13 = "<f13>"
F14 = "<f14>"
F15 = "<f15>"
F16 = "<f16>"
F17 = "<f17>"
F18 = "<f18>"
F19 = "<f19>"
F20 = "<f20>"
F21 = "<f21>"
F22 = "<f22>"
F23 = "<f23>"
F24 = "<f24>"
F25 = "<f25>"
F26 = "<f26>"
F27 = "<f27>"
F28 = "<f28>"
F29 = "<f29>"
F30 = "<f30>"
F31 = "<f31>"
F32 = "<f32>"
F33 = "<f33>"
F34 = "<f34>"
F35 = "<f35>"
# Other
ESCAPE = "<escape>"
INSERT = "<insert>"
DELETE = "<delete>"
HOME = "<home>"
END = "<end>"
PAGE_UP = "<page_up>"
PAGE_DOWN = "<page_down>"
# Numpad
NP_INSERT = "<np_insert>"
NP_DELETE = "<np_delete>"
NP_HOME = "<np_home>"
NP_END = "<np_end>"
NP_PAGE_UP = "<np_page_up>"
NP_PAGE_DOWN = "<np_page_down>"
NP_LEFT = "<np_left>"
NP_RIGHT = "<np_right>"
NP_UP = "<np_up>"
NP_DOWN = "<np_down>"
NP_DIVIDE = "<np_divide>"
NP_MULTIPLY = "<np_multiply>"
NP_ADD = "<np_add>"
NP_SUBTRACT = "<np_subtract>"
NP_5 = "<np_5>"
[docs]
@classmethod
def is_key(cls, key_string: str) -> bool:
"""
Returns if a string represents a key.
"""
# Key strings must be treated as case insensitive - always convert to lowercase
# before doing any comparisons
lowered_key_string = key_string.lower()
try:
cls(lowered_key_string)
except ValueError:
return _code_point_re.fullmatch(lowered_key_string) is not None
else:
return True
NAVIGATION_KEYS = [Key.LEFT, Key.RIGHT, Key.UP, Key.DOWN, Key.BACKSPACE, Key.HOME, Key.END, Key.PAGE_UP, Key.PAGE_DOWN]
# All known modifier keys. This is used to determine if a key is a modifier. Used by the Configuration manager
# to verify that only modifier keys are placed in the disabled modifiers list.
_ALL_MODIFIERS_ = (
Key.CONTROL, Key.ALT, Key.ALT_GR, Key.SHIFT, Key.SUPER, Key.HYPER, Key.CAPSLOCK, Key.NUMLOCK, Key.META
)
# Used to identify special keys in texts. Also include <codeXX> literals as defined in the _code_point_re.
KEY_FIND_RE = re.compile("|".join(("|".join(Key), _code_point_re.pattern)), re.UNICODE)
KEY_SPLIT_RE = re.compile("(<[^<>]+>\\+?)")
# these types of modifiers are accepted as either left or right versions when used in hotkeys
# when sent via keyboard they will send the LEFT version of the modifier
UNIVERSAL_MODIFIERS = [Key.CONTROL, Key.ALT, Key.SUPER, Key.SHIFT, Key.HYPER, Key.META]
MAPPED_UNIVERSAL_MODIFIERS = {
Key.CONTROL: [Key.LEFTCONTROL, Key.RIGHTCONTROL],
Key.ALT: [Key.LEFTALT, Key.RIGHTALT],
Key.SUPER: [Key.LEFTSUPER, Key.RIGHTSUPER],
Key.SHIFT: [Key.LEFTSHIFT, Key.RIGHTSHIFT],
Key.HYPER: [Key.LEFTHYPER, Key.RIGHTHYPER],
Key.META: [Key.LEFTMETA, Key.RIGHTMETA]
}
MODIFIERS = [
Key.CONTROL, Key.ALT, Key.ALT_GR, Key.SHIFT, Key.SUPER, Key.HYPER, Key.META, Key.CAPSLOCK, Key.NUMLOCK,
Key.LEFTCONTROL,Key.LEFTALT,Key.LEFTSHIFT,Key.LEFTSUPER,Key.LEFTHYPER,Key.LEFTMETA,
Key.RIGHTCONTROL,Key.RIGHTALT,Key.RIGHTSHIFT,Key.RIGHTSUPER,Key.RIGHTHYPER,Key.RIGHTMETA
]
HELD_MODIFIERS = [
Key.CONTROL, Key.ALT_GR, Key.ALT, Key.SUPER, Key.SHIFT, Key.HYPER, Key.META,
Key.LEFTCONTROL,Key.LEFTALT,Key.LEFTSHIFT,Key.LEFTSUPER,Key.LEFTHYPER,Key.LEFTMETA,
Key.RIGHTCONTROL,Key.RIGHTALT,Key.RIGHTSHIFT,Key.RIGHTSUPER,Key.RIGHTHYPER,Key.RIGHTMETA
]