From 6d5b99d78dbf0428eea2ca425f30f1a3038e42ef Mon Sep 17 00:00:00 2001 From: Gigahawk Date: Tue, 18 May 2021 19:15:20 -0700 Subject: [PATCH] Dynamically create core key definitions as required (#200) * Dynamically allocate keys as required * Restore comments * Run linter * Move key definitions into a dict * Revert "Move key definitions into a dict" This reverts commit 49ac7c2e40f0222be63d1102b0584e0c15b085c2. --- kmk/keys.py | 796 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 502 insertions(+), 294 deletions(-) diff --git a/kmk/keys.py b/kmk/keys.py index 068c854..adac12f 100644 --- a/kmk/keys.py +++ b/kmk/keys.py @@ -16,9 +16,510 @@ KEY_SIMPLE = const(0) KEY_MODIFIER = const(1) KEY_CONSUMER = const(2) + +class KeyAttrDict(AttrDict): + def __getattr__(self, key): + try: + return super(KeyAttrDict, self).__getattr__(key) + except: + pass + # Modifiers + if key in ('LEFT_CONTROL', 'LCTRL', 'LCTL'): + make_mod_key(code=0x01, names=('LEFT_CONTROL', 'LCTRL', 'LCTL')) + elif key in ('LEFT_SHIFT', 'LSHIFT', 'LSFT'): + make_mod_key(code=0x02, names=('LEFT_SHIFT', 'LSHIFT', 'LSFT')) + elif key in ('LEFT_ALT', 'LALT'): + make_mod_key(code=0x04, names=('LEFT_ALT', 'LALT')) + elif key in ('LEFT_SUPER', 'LGUI', 'LCMD', 'LWIN'): + make_mod_key(code=0x08, names=('LEFT_SUPER', 'LGUI', 'LCMD', 'LWIN')) + elif key in ('RIGHT_CONTROL', 'RCTRL', 'RCTL'): + make_mod_key(code=0x10, names=('RIGHT_CONTROL', 'RCTRL', 'RCTL')) + elif key in ('RIGHT_SHIFT', 'RSHIFT', 'RSFT'): + make_mod_key(code=0x20, names=('RIGHT_SHIFT', 'RSHIFT', 'RSFT')) + elif key in ('RIGHT_ALT', 'RALT'): + make_mod_key(code=0x40, names=('RIGHT_ALT', 'RALT')) + elif key in ('RIGHT_SUPER', 'RGUI', 'RCMD', 'RWIN'): + make_mod_key(code=0x80, names=('RIGHT_SUPER', 'RGUI', 'RCMD', 'RWIN')) + # MEH = LCTL | LALT | LSFT# MEH = LCTL | + elif key in ('MEH',): + make_mod_key(code=0x07, names=('MEH',)) + # HYPR = LCTL | LALT | LSFT | LGUI + elif key in ('HYPER', 'HYPR'): + make_mod_key(code=0x0F, names=('HYPER', 'HYPR')) + + # Basic ASCII letters + elif key in ('A',): + make_key(code=4, names=('A',)) + elif key in ('B',): + make_key(code=5, names=('B',)) + elif key in ('C',): + make_key(code=6, names=('C',)) + elif key in ('D',): + make_key(code=7, names=('D',)) + elif key in ('E',): + make_key(code=8, names=('E',)) + elif key in ('F',): + make_key(code=9, names=('F',)) + elif key in ('G',): + make_key(code=10, names=('G',)) + elif key in ('H',): + make_key(code=11, names=('H',)) + elif key in ('I',): + make_key(code=12, names=('I',)) + elif key in ('J',): + make_key(code=13, names=('J',)) + elif key in ('K',): + make_key(code=14, names=('K',)) + elif key in ('L',): + make_key(code=15, names=('L',)) + elif key in ('M',): + make_key(code=16, names=('M',)) + elif key in ('N',): + make_key(code=17, names=('N',)) + elif key in ('O',): + make_key(code=18, names=('O',)) + elif key in ('P',): + make_key(code=19, names=('P',)) + elif key in ('Q',): + make_key(code=20, names=('Q',)) + elif key in ('R',): + make_key(code=21, names=('R',)) + elif key in ('S',): + make_key(code=22, names=('S',)) + elif key in ('T',): + make_key(code=23, names=('T',)) + elif key in ('U',): + make_key(code=24, names=('U',)) + elif key in ('V',): + make_key(code=25, names=('V',)) + elif key in ('W',): + make_key(code=26, names=('W',)) + elif key in ('X',): + make_key(code=27, names=('X',)) + elif key in ('Y',): + make_key(code=28, names=('Y',)) + elif key in ('Z',): + make_key(code=29, names=('Z',)) + + # Numbers + # Aliases to play nicely with AttrDict, since KC.1 isn't a valid + # attribute key in Python, but KC.N1 is + elif key in ('1', 'N1'): + make_key(code=30, names=('1', 'N1')) + elif key in ('2', 'N2'): + make_key(code=31, names=('2', 'N2')) + elif key in ('3', 'N3'): + make_key(code=32, names=('3', 'N3')) + elif key in ('4', 'N4'): + make_key(code=33, names=('4', 'N4')) + elif key in ('5', 'N5'): + make_key(code=34, names=('5', 'N5')) + elif key in ('6', 'N6'): + make_key(code=35, names=('6', 'N6')) + elif key in ('7', 'N7'): + make_key(code=36, names=('7', 'N7')) + elif key in ('8', 'N8'): + make_key(code=37, names=('8', 'N8')) + elif key in ('9', 'N9'): + make_key(code=38, names=('9', 'N9')) + elif key in ('0', 'N0'): + make_key(code=39, names=('0', 'N0')) + + # More ASCII standard keys + elif key in ('ENTER', 'ENT', '\n'): + make_key(code=40, names=('ENTER', 'ENT', '\n')) + elif key in ('ESCAPE', 'ESC'): + make_key(code=41, names=('ESCAPE', 'ESC')) + elif key in ('BACKSPACE', 'BSPC', 'BKSP'): + make_key(code=42, names=('BACKSPACE', 'BSPC', 'BKSP')) + elif key in ('TAB', '\t'): + make_key(code=43, names=('TAB', '\t')) + elif key in ('SPACE', 'SPC', ' '): + make_key(code=44, names=('SPACE', 'SPC', ' ')) + elif key in ('MINUS', 'MINS', '-'): + make_key(code=45, names=('MINUS', 'MINS', '-')) + elif key in ('EQUAL', 'EQL', '='): + make_key(code=46, names=('EQUAL', 'EQL', '=')) + elif key in ('LBRACKET', 'LBRC', '['): + make_key(code=47, names=('LBRACKET', 'LBRC', '[')) + elif key in ('RBRACKET', 'RBRC', ']'): + make_key(code=48, names=('RBRACKET', 'RBRC', ']')) + elif key in ('BACKSLASH', 'BSLASH', 'BSLS', '\\'): + make_key(code=49, names=('BACKSLASH', 'BSLASH', 'BSLS', '\\')) + elif key in ('SEMICOLON', 'SCOLON', 'SCLN', ';'): + make_key(code=51, names=('SEMICOLON', 'SCOLON', 'SCLN', ';')) + elif key in ('QUOTE', 'QUOT', "'"): + make_key(code=52, names=('QUOTE', 'QUOT', "'")) + elif key in ('GRAVE', 'GRV', 'ZKHK', '`'): + make_key(code=53, names=('GRAVE', 'GRV', 'ZKHK', '`')) + elif key in ('COMMA', 'COMM', ','): + make_key(code=54, names=('COMMA', 'COMM', ',')) + elif key in ('DOT', '.'): + make_key(code=55, names=('DOT', '.')) + elif key in ('SLASH', 'SLSH'): + make_key(code=56, names=('SLASH', 'SLSH')) + + # Function Keys + elif key in ('F1',): + make_key(code=58, names=('F1',)) + elif key in ('F2',): + make_key(code=59, names=('F2',)) + elif key in ('F3',): + make_key(code=60, names=('F3',)) + elif key in ('F4',): + make_key(code=61, names=('F4',)) + elif key in ('F5',): + make_key(code=62, names=('F5',)) + elif key in ('F6',): + make_key(code=63, names=('F6',)) + elif key in ('F7',): + make_key(code=64, names=('F7',)) + elif key in ('F8',): + make_key(code=65, names=('F8',)) + elif key in ('F9',): + make_key(code=66, names=('F9',)) + elif key in ('F10',): + make_key(code=67, names=('F10',)) + elif key in ('F11',): + make_key(code=68, names=('F11',)) + elif key in ('F12',): + make_key(code=69, names=('F12',)) + elif key in ('F13',): + make_key(code=104, names=('F13',)) + elif key in ('F14',): + make_key(code=105, names=('F14',)) + elif key in ('F15',): + make_key(code=106, names=('F15',)) + elif key in ('F16',): + make_key(code=107, names=('F16',)) + elif key in ('F17',): + make_key(code=108, names=('F17',)) + elif key in ('F18',): + make_key(code=109, names=('F18',)) + elif key in ('F19',): + make_key(code=110, names=('F19',)) + elif key in ('F20',): + make_key(code=111, names=('F20',)) + elif key in ('F21',): + make_key(code=112, names=('F21',)) + elif key in ('F22',): + make_key(code=113, names=('F22',)) + elif key in ('F23',): + make_key(code=114, names=('F23',)) + elif key in ('F24',): + make_key(code=115, names=('F24',)) + + # Lock Keys, Navigation, etc. + elif key in ('CAPS_LOCK', 'CAPSLOCK', 'CLCK', 'CAPS'): + make_key(code=57, names=('CAPS_LOCK', 'CAPSLOCK', 'CLCK', 'CAPS')) + # FIXME: Investigate whether this key actually works, and + # uncomment when/if it does. + # elif key in ('LOCKING_CAPS', 'LCAP'): + # # make_key(code=130, names=('LOCKING_CAPS', 'LCAP')) + elif key in ('PRINT_SCREEN', 'PSCREEN', 'PSCR'): + make_key(code=70, names=('PRINT_SCREEN', 'PSCREEN', 'PSCR')) + elif key in ('SCROLL_LOCK', 'SCROLLLOCK', 'SLCK'): + make_key(code=71, names=('SCROLL_LOCK', 'SCROLLLOCK', 'SLCK')) + # FIXME: Investigate whether this key actually works, and + # uncomment when/if it does. + # elif key in ('LOCKING_SCROLL', 'LSCRL'): + # make_key(code=132, names=('LOCKING_SCROLL', 'LSCRL')) + elif key in ('PAUSE', 'PAUS', 'BRK'): + make_key(code=72, names=('PAUSE', 'PAUS', 'BRK')) + elif key in ('INSERT', 'INS'): + make_key(code=73, names=('INSERT', 'INS')) + elif key in ('HOME',): + make_key(code=74, names=('HOME',)) + elif key in ('PGUP',): + make_key(code=75, names=('PGUP',)) + elif key in ('DELETE', 'DEL'): + make_key(code=76, names=('DELETE', 'DEL')) + elif key in ('END',): + make_key(code=77, names=('END',)) + elif key in ('PGDOWN', 'PGDN'): + make_key(code=78, names=('PGDOWN', 'PGDN')) + elif key in ('RIGHT', 'RGHT'): + make_key(code=79, names=('RIGHT', 'RGHT')) + elif key in ('LEFT',): + make_key(code=80, names=('LEFT',)) + elif key in ('DOWN',): + make_key(code=81, names=('DOWN',)) + elif key in ('UP',): + make_key(code=82, names=('UP',)) + + # Numpad + elif key in ('NUM_LOCK', 'NUMLOCK', 'NLCK'): + make_key(code=83, names=('NUM_LOCK', 'NUMLOCK', 'NLCK')) + # FIXME: Investigate whether this key actually works, and + # uncomment when/if it does. + # elif key in ('LOCKING_NUM', 'LNUM'): + # make_key(code=131, names=('LOCKING_NUM', 'LNUM')) + elif key in ('KP_SLASH', 'NUMPAD_SLASH', 'PSLS'): + make_key(code=84, names=('KP_SLASH', 'NUMPAD_SLASH', 'PSLS')) + elif key in ('KP_ASTERISK', 'NUMPAD_ASTERISK', 'PAST'): + make_key(code=85, names=('KP_ASTERISK', 'NUMPAD_ASTERISK', 'PAST')) + elif key in ('KP_MINUS', 'NUMPAD_MINUS', 'PMNS'): + make_key(code=86, names=('KP_MINUS', 'NUMPAD_MINUS', 'PMNS')) + elif key in ('KP_PLUS', 'NUMPAD_PLUS', 'PPLS'): + make_key(code=87, names=('KP_PLUS', 'NUMPAD_PLUS', 'PPLS')) + elif key in ('KP_ENTER', 'NUMPAD_ENTER', 'PENT'): + make_key(code=88, names=('KP_ENTER', 'NUMPAD_ENTER', 'PENT')) + elif key in ('KP_1', 'P1', 'NUMPAD_1'): + make_key(code=89, names=('KP_1', 'P1', 'NUMPAD_1')) + elif key in ('KP_2', 'P2', 'NUMPAD_2'): + make_key(code=90, names=('KP_2', 'P2', 'NUMPAD_2')) + elif key in ('KP_3', 'P3', 'NUMPAD_3'): + make_key(code=91, names=('KP_3', 'P3', 'NUMPAD_3')) + elif key in ('KP_4', 'P4', 'NUMPAD_4'): + make_key(code=92, names=('KP_4', 'P4', 'NUMPAD_4')) + elif key in ('KP_5', 'P5', 'NUMPAD_5'): + make_key(code=93, names=('KP_5', 'P5', 'NUMPAD_5')) + elif key in ('KP_6', 'P6', 'NUMPAD_6'): + make_key(code=94, names=('KP_6', 'P6', 'NUMPAD_6')) + elif key in ('KP_7', 'P7', 'NUMPAD_7'): + make_key(code=95, names=('KP_7', 'P7', 'NUMPAD_7')) + elif key in ('KP_8', 'P8', 'NUMPAD_8'): + make_key(code=96, names=('KP_8', 'P8', 'NUMPAD_8')) + elif key in ('KP_9', 'P9', 'NUMPAD_9'): + make_key(code=97, names=('KP_9', 'P9', 'NUMPAD_9')) + elif key in ('KP_0', 'P0', 'NUMPAD_0'): + make_key(code=98, names=('KP_0', 'P0', 'NUMPAD_0')) + elif key in ('KP_DOT', 'PDOT', 'NUMPAD_DOT'): + make_key(code=99, names=('KP_DOT', 'PDOT', 'NUMPAD_DOT')) + elif key in ('KP_EQUAL', 'PEQL', 'NUMPAD_EQUAL'): + make_key(code=103, names=('KP_EQUAL', 'PEQL', 'NUMPAD_EQUAL')) + elif key in ('KP_COMMA', 'PCMM', 'NUMPAD_COMMA'): + make_key(code=133, names=('KP_COMMA', 'PCMM', 'NUMPAD_COMMA')) + elif key in ('KP_EQUAL_AS400', 'NUMPAD_EQUAL_AS400'): + make_key(code=134, names=('KP_EQUAL_AS400', 'NUMPAD_EQUAL_AS400')) + + # Making life better for folks on tiny keyboards especially: exposes + # the 'shifted' keys as raw keys. Under the hood we're still + # sending Shift+(whatever key is normally pressed) to get these, so + # for example `KC_AT` will hold shift and press 2. + elif key in ('TILDE', 'TILD', '~'): + make_shifted_key('GRAVE', names=('TILDE', 'TILD', '~')) + elif key in ('EXCLAIM', 'EXLM', '!'): + make_shifted_key('1', names=('EXCLAIM', 'EXLM', '!')) + elif key in ('AT', '@'): + make_shifted_key('2', names=('AT', '@')) + elif key in ('HASH', 'POUND', '#'): + make_shifted_key('3', names=('HASH', 'POUND', '#')) + elif key in ('DOLLAR', 'DLR', '$'): + make_shifted_key('4', names=('DOLLAR', 'DLR', '$')) + elif key in ('PERCENT', 'PERC', '%'): + make_shifted_key('5', names=('PERCENT', 'PERC', '%')) + elif key in ('CIRCUMFLEX', 'CIRC', '^'): + make_shifted_key('6', names=('CIRCUMFLEX', 'CIRC', '^')) + elif key in ('AMPERSAND', 'AMPR', '&'): + make_shifted_key('7', names=('AMPERSAND', 'AMPR', '&')) + elif key in ('ASTERISK', 'ASTR', '*'): + make_shifted_key('8', names=('ASTERISK', 'ASTR', '*')) + elif key in ('LEFT_PAREN', 'LPRN', '('): + make_shifted_key('9', names=('LEFT_PAREN', 'LPRN', '(')) + elif key in ('RIGHT_PAREN', 'RPRN', ')'): + make_shifted_key('0', names=('RIGHT_PAREN', 'RPRN', ')')) + elif key in ('UNDERSCORE', 'UNDS', '_'): + make_shifted_key('MINUS', names=('UNDERSCORE', 'UNDS', '_')) + elif key in ('PLUS', '+'): + make_shifted_key('EQUAL', names=('PLUS', '+')) + elif key in ('LEFT_CURLY_BRACE', 'LCBR', '{'): + make_shifted_key('LBRACKET', names=('LEFT_CURLY_BRACE', 'LCBR', '{')) + elif key in ('RIGHT_CURLY_BRACE', 'RCBR', '}'): + make_shifted_key('RBRACKET', names=('RIGHT_CURLY_BRACE', 'RCBR', '}')) + elif key in ('PIPE', '|'): + make_shifted_key('BACKSLASH', names=('PIPE', '|')) + elif key in ('COLON', 'COLN', ':'): + make_shifted_key('SEMICOLON', names=('COLON', 'COLN', ':')) + elif key in ('DOUBLE_QUOTE', 'DQUO', 'DQT', '"'): + make_shifted_key('QUOTE', names=('DOUBLE_QUOTE', 'DQUO', 'DQT', '"')) + elif key in ('LEFT_ANGLE_BRACKET', 'LABK', '<'): + make_shifted_key('COMMA', names=('LEFT_ANGLE_BRACKET', 'LABK', '<')) + elif key in ('RIGHT_ANGLE_BRACKET', 'RABK', '>'): + make_shifted_key('DOT', names=('RIGHT_ANGLE_BRACKET', 'RABK', '>')) + elif key in ('QUESTION', 'QUES', '?'): + make_shifted_key('SLSH', names=('QUESTION', 'QUES', '?')) + + # International + elif key in ('NONUS_HASH', 'NUHS'): + make_key(code=50, names=('NONUS_HASH', 'NUHS')) + elif key in ('NONUS_BSLASH', 'NUBS'): + make_key(code=100, names=('NONUS_BSLASH', 'NUBS')) + elif key in ('APP', 'APPLICATION', 'SEL', 'WINMENU'): + make_key(code=101, names=('APP', 'APPLICATION', 'SEL', 'WINMENU')) + + elif key in ('INT1', 'RO'): + make_key(code=135, names=('INT1', 'RO')) + elif key in ('INT2', 'KANA'): + make_key(code=136, names=('INT2', 'KANA')) + elif key in ('INT3', 'JYEN'): + make_key(code=137, names=('INT3', 'JYEN')) + elif key in ('INT4', 'HENK'): + make_key(code=138, names=('INT4', 'HENK')) + elif key in ('INT5', 'MHEN'): + make_key(code=139, names=('INT5', 'MHEN')) + elif key in ('INT6',): + make_key(code=140, names=('INT6',)) + elif key in ('INT7',): + make_key(code=141, names=('INT7',)) + elif key in ('INT8',): + make_key(code=142, names=('INT8',)) + elif key in ('INT9',): + make_key(code=143, names=('INT9',)) + elif key in ('LANG1', 'HAEN'): + make_key(code=144, names=('LANG1', 'HAEN')) + elif key in ('LANG2', 'HAEJ'): + make_key(code=145, names=('LANG2', 'HAEJ')) + elif key in ('LANG3',): + make_key(code=146, names=('LANG3',)) + elif key in ('LANG4',): + make_key(code=147, names=('LANG4',)) + elif key in ('LANG5',): + make_key(code=148, names=('LANG5',)) + elif key in ('LANG6',): + make_key(code=149, names=('LANG6',)) + elif key in ('LANG7',): + make_key(code=150, names=('LANG7',)) + elif key in ('LANG8',): + make_key(code=151, names=('LANG8',)) + elif key in ('LANG9',): + make_key(code=152, names=('LANG9',)) + + # Consumer ("media") keys. Most known keys aren't supported here. A much + # longer list used to exist in this file, but the codes were almost certainly + # incorrect, conflicting with each other, or otherwise 'weird'. We'll add them + # back in piecemeal as needed. PRs welcome. + # + # A super useful reference for these is http://www.freebsddiary.org/APC/usb_hid_usages.php + # Note that currently we only have the PC codes. Recent MacOS versions seem to + # support PC media keys, so I don't know how much value we would get out of + # adding the old Apple-specific consumer codes, but again, PRs welcome if the + # lack of them impacts you. + elif key in ('AUDIO_MUTE', 'MUTE'): + make_consumer_key(code=226, names=('AUDIO_MUTE', 'MUTE')) # 0xE2 + elif key in ('AUDIO_VOL_UP', 'VOLU'): + make_consumer_key(code=233, names=('AUDIO_VOL_UP', 'VOLU')) # 0xE9 + elif key in ('AUDIO_VOL_DOWN', 'VOLD'): + make_consumer_key(code=234, names=('AUDIO_VOL_DOWN', 'VOLD')) # 0xEA + elif key in ('MEDIA_NEXT_TRACK', 'MNXT'): + make_consumer_key(code=181, names=('MEDIA_NEXT_TRACK', 'MNXT')) # 0xB5 + elif key in ('MEDIA_PREV_TRACK', 'MPRV'): + make_consumer_key(code=182, names=('MEDIA_PREV_TRACK', 'MPRV')) # 0xB6 + elif key in ('MEDIA_STOP', 'MSTP'): + make_consumer_key(code=183, names=('MEDIA_STOP', 'MSTP')) # 0xB7 + elif key in ('MEDIA_PLAY_PAUSE', 'MPLY'): + make_consumer_key( + code=205, names=('MEDIA_PLAY_PAUSE', 'MPLY') + ) # 0xCD (this may not be right) + elif key in ('MEDIA_EJECT', 'EJCT'): + make_consumer_key(code=184, names=('MEDIA_EJECT', 'EJCT')) # 0xB8 + elif key in ('MEDIA_FAST_FORWARD', 'MFFD'): + make_consumer_key(code=179, names=('MEDIA_FAST_FORWARD', 'MFFD')) # 0xB3 + elif key in ('MEDIA_REWIND', 'MRWD'): + make_consumer_key(code=180, names=('MEDIA_REWIND', 'MRWD')) # 0xB4 + + # Internal, diagnostic, or auxiliary/enhanced keys + + # NO and TRNS are functionally identical in how they (don't) mutate + # the state, but are tracked semantically separately, so create + # two keys with the exact same functionality + elif key in ('NO',): + make_key( + names=('NO',), + on_press=handlers.passthrough, + on_release=handlers.passthrough, + ) + elif key in ('TRANSPARENT', 'TRNS'): + make_key( + names=('TRANSPARENT', 'TRNS'), + on_press=handlers.passthrough, + on_release=handlers.passthrough, + ) + + elif key in ('RESET',): + make_key(names=('RESET',), on_press=handlers.reset) + elif key in ('BOOTLOADER',): + make_key(names=('BOOTLOADER',), on_press=handlers.bootloader) + elif key in ('DEBUG', 'DBG'): + make_key( + names=('DEBUG', 'DBG'), + on_press=handlers.debug_pressed, + on_release=handlers.passthrough, + ) + elif key in ('GESC',): + make_key( + names=('GESC',), + on_press=handlers.gesc_pressed, + on_release=handlers.gesc_released, + ) + elif key in ('BKDL',): + make_key( + names=('BKDL',), + on_press=handlers.bkdl_pressed, + on_release=handlers.bkdl_released, + ) + elif key in ('GESC', 'GRAVE_ESC'): + make_key( + names=('GESC', 'GRAVE_ESC'), + on_press=handlers.gesc_pressed, + on_release=handlers.gesc_released, + ) + + # A dummy key to trigger a sleep_ms call in a sequence of other keys in a + # simple sequence macro. + elif key in ('MACRO_SLEEP_MS', 'SLEEP_IN_SEQ'): + make_argumented_key( + validator=key_seq_sleep_validator, + names=('MACRO_SLEEP_MS', 'SLEEP_IN_SEQ'), + on_press=handlers.sleep_pressed, + ) + elif key in ('UC_MODE_NOOP', 'UC_DISABLE'): + make_key( + names=('UC_MODE_NOOP', 'UC_DISABLE'), + meta=UnicodeModeKeyMeta(UnicodeMode.NOOP), + on_press=handlers.uc_mode_pressed, + ) + elif key in ('UC_MODE_LINUX', 'UC_MODE_IBUS'): + make_key( + names=('UC_MODE_LINUX', 'UC_MODE_IBUS'), + meta=UnicodeModeKeyMeta(UnicodeMode.IBUS), + on_press=handlers.uc_mode_pressed, + ) + elif key in ('UC_MODE_MACOS', 'UC_MODE_OSX', 'US_MODE_RALT'): + make_key( + names=('UC_MODE_MACOS', 'UC_MODE_OSX', 'US_MODE_RALT'), + meta=UnicodeModeKeyMeta(UnicodeMode.RALT), + on_press=handlers.uc_mode_pressed, + ) + elif key in ('UC_MODE_WINC',): + make_key( + names=('UC_MODE_WINC',), + meta=UnicodeModeKeyMeta(UnicodeMode.WINC), + on_press=handlers.uc_mode_pressed, + ) + elif key in ('UC_MODE',): + make_argumented_key( + validator=unicode_mode_key_validator, + names=('UC_MODE',), + on_press=handlers.uc_mode_pressed, + ) + elif key in ('TAP_DANCE', 'TD'): + make_argumented_key( + validator=tap_dance_key_validator, + names=('TAP_DANCE', 'TD'), + on_press=handlers.td_pressed, + on_release=handlers.td_released, + ) + elif key in ('HID_SWITCH', 'HID'): + make_key(names=('HID_SWITCH', 'HID'), on_press=handlers.hid_switch) + else: + raise ValueError("Invalid key") + return self.__getattr__(key) + + # Global state, will be filled in througout this file, and # anywhere the user creates custom keys -KC = AttrDict() +KC = KeyAttrDict() class Key: @@ -357,296 +858,3 @@ def make_argumented_key( KC[name] = _argumented_key return _argumented_key - - -# Modifiers -make_mod_key(code=0x01, names=('LEFT_CONTROL', 'LCTRL', 'LCTL')) -make_mod_key(code=0x02, names=('LEFT_SHIFT', 'LSHIFT', 'LSFT')) -make_mod_key(code=0x04, names=('LEFT_ALT', 'LALT')) -make_mod_key(code=0x08, names=('LEFT_SUPER', 'LGUI', 'LCMD', 'LWIN')) -make_mod_key(code=0x10, names=('RIGHT_CONTROL', 'RCTRL', 'RCTL')) -make_mod_key(code=0x20, names=('RIGHT_SHIFT', 'RSHIFT', 'RSFT')) -make_mod_key(code=0x40, names=('RIGHT_ALT', 'RALT')) -make_mod_key(code=0x80, names=('RIGHT_SUPER', 'RGUI', 'RCMD', 'RWIN')) -# MEH = LCTL | LALT | LSFT -make_mod_key(code=0x07, names=('MEH',)) -# HYPR = LCTL | LALT | LSFT | LGUI -make_mod_key(code=0x0F, names=('HYPER', 'HYPR')) - -# Basic ASCII letters -make_key(code=4, names=('A',)) -make_key(code=5, names=('B',)) -make_key(code=6, names=('C',)) -make_key(code=7, names=('D',)) -make_key(code=8, names=('E',)) -make_key(code=9, names=('F',)) -make_key(code=10, names=('G',)) -make_key(code=11, names=('H',)) -make_key(code=12, names=('I',)) -make_key(code=13, names=('J',)) -make_key(code=14, names=('K',)) -make_key(code=15, names=('L',)) -make_key(code=16, names=('M',)) -make_key(code=17, names=('N',)) -make_key(code=18, names=('O',)) -make_key(code=19, names=('P',)) -make_key(code=20, names=('Q',)) -make_key(code=21, names=('R',)) -make_key(code=22, names=('S',)) -make_key(code=23, names=('T',)) -make_key(code=24, names=('U',)) -make_key(code=25, names=('V',)) -make_key(code=26, names=('W',)) -make_key(code=27, names=('X',)) -make_key(code=28, names=('Y',)) -make_key(code=29, names=('Z',)) - -# Numbers -# Aliases to play nicely with AttrDict, since KC.1 isn't a valid -# attribute key in Python, but KC.N1 is -make_key(code=30, names=('1', 'N1')) -make_key(code=31, names=('2', 'N2')) -make_key(code=32, names=('3', 'N3')) -make_key(code=33, names=('4', 'N4')) -make_key(code=34, names=('5', 'N5')) -make_key(code=35, names=('6', 'N6')) -make_key(code=36, names=('7', 'N7')) -make_key(code=37, names=('8', 'N8')) -make_key(code=38, names=('9', 'N9')) -make_key(code=39, names=('0', 'N0')) - -# More ASCII standard keys -make_key(code=40, names=('ENTER', 'ENT', '\n')) -make_key(code=41, names=('ESCAPE', 'ESC')) -make_key(code=42, names=('BACKSPACE', 'BSPC', 'BKSP')) -make_key(code=43, names=('TAB', '\t')) -make_key(code=44, names=('SPACE', 'SPC', ' ')) -make_key(code=45, names=('MINUS', 'MINS', '-')) -make_key(code=46, names=('EQUAL', 'EQL', '=')) -make_key(code=47, names=('LBRACKET', 'LBRC', '[')) -make_key(code=48, names=('RBRACKET', 'RBRC', ']')) -make_key(code=49, names=('BACKSLASH', 'BSLASH', 'BSLS', '\\')) -make_key(code=51, names=('SEMICOLON', 'SCOLON', 'SCLN', ';')) -make_key(code=52, names=('QUOTE', 'QUOT', "'")) -make_key(code=53, names=('GRAVE', 'GRV', 'ZKHK', '`')) -make_key(code=54, names=('COMMA', 'COMM', ',')) -make_key(code=55, names=('DOT', '.')) -make_key(code=56, names=('SLASH', 'SLSH')) - -# Function Keys -make_key(code=58, names=('F1',)) -make_key(code=59, names=('F2',)) -make_key(code=60, names=('F3',)) -make_key(code=61, names=('F4',)) -make_key(code=62, names=('F5',)) -make_key(code=63, names=('F6',)) -make_key(code=64, names=('F7',)) -make_key(code=65, names=('F8',)) -make_key(code=66, names=('F9',)) -make_key(code=67, names=('F10',)) -make_key(code=68, names=('F11',)) -make_key(code=69, names=('F12',)) -make_key(code=104, names=('F13',)) -make_key(code=105, names=('F14',)) -make_key(code=106, names=('F15',)) -make_key(code=107, names=('F16',)) -make_key(code=108, names=('F17',)) -make_key(code=109, names=('F18',)) -make_key(code=110, names=('F19',)) -make_key(code=111, names=('F20',)) -make_key(code=112, names=('F21',)) -make_key(code=113, names=('F22',)) -make_key(code=114, names=('F23',)) -make_key(code=115, names=('F24',)) - -# Lock Keys, Navigation, etc. -make_key(code=57, names=('CAPS_LOCK', 'CAPSLOCK', 'CLCK', 'CAPS')) -# FIXME: Investigate whether this key actually works, and -# uncomment when/if it does. -# make_key(code=130, names=('LOCKING_CAPS', 'LCAP')) -make_key(code=70, names=('PRINT_SCREEN', 'PSCREEN', 'PSCR')) -make_key(code=71, names=('SCROLL_LOCK', 'SCROLLLOCK', 'SLCK')) -# FIXME: Investigate whether this key actually works, and -# uncomment when/if it does. -# make_key(code=132, names=('LOCKING_SCROLL', 'LSCRL')) -make_key(code=72, names=('PAUSE', 'PAUS', 'BRK')) -make_key(code=73, names=('INSERT', 'INS')) -make_key(code=74, names=('HOME',)) -make_key(code=75, names=('PGUP',)) -make_key(code=76, names=('DELETE', 'DEL')) -make_key(code=77, names=('END',)) -make_key(code=78, names=('PGDOWN', 'PGDN')) -make_key(code=79, names=('RIGHT', 'RGHT')) -make_key(code=80, names=('LEFT',)) -make_key(code=81, names=('DOWN',)) -make_key(code=82, names=('UP',)) - -# Numpad -make_key(code=83, names=('NUM_LOCK', 'NUMLOCK', 'NLCK')) -# FIXME: Investigate whether this key actually works, and -# uncomment when/if it does. -# make_key(code=131, names=('LOCKING_NUM', 'LNUM')) -make_key(code=84, names=('KP_SLASH', 'NUMPAD_SLASH', 'PSLS')) -make_key(code=85, names=('KP_ASTERISK', 'NUMPAD_ASTERISK', 'PAST')) -make_key(code=86, names=('KP_MINUS', 'NUMPAD_MINUS', 'PMNS')) -make_key(code=87, names=('KP_PLUS', 'NUMPAD_PLUS', 'PPLS')) -make_key(code=88, names=('KP_ENTER', 'NUMPAD_ENTER', 'PENT')) -make_key(code=89, names=('KP_1', 'P1', 'NUMPAD_1')) -make_key(code=90, names=('KP_2', 'P2', 'NUMPAD_2')) -make_key(code=91, names=('KP_3', 'P3', 'NUMPAD_3')) -make_key(code=92, names=('KP_4', 'P4', 'NUMPAD_4')) -make_key(code=93, names=('KP_5', 'P5', 'NUMPAD_5')) -make_key(code=94, names=('KP_6', 'P6', 'NUMPAD_6')) -make_key(code=95, names=('KP_7', 'P7', 'NUMPAD_7')) -make_key(code=96, names=('KP_8', 'P8', 'NUMPAD_8')) -make_key(code=97, names=('KP_9', 'P9', 'NUMPAD_9')) -make_key(code=98, names=('KP_0', 'P0', 'NUMPAD_0')) -make_key(code=99, names=('KP_DOT', 'PDOT', 'NUMPAD_DOT')) -make_key(code=103, names=('KP_EQUAL', 'PEQL', 'NUMPAD_EQUAL')) -make_key(code=133, names=('KP_COMMA', 'PCMM', 'NUMPAD_COMMA')) -make_key(code=134, names=('KP_EQUAL_AS400', 'NUMPAD_EQUAL_AS400')) - -# Making life better for folks on tiny keyboards especially: exposes -# the 'shifted' keys as raw keys. Under the hood we're still -# sending Shift+(whatever key is normally pressed) to get these, so -# for example `KC_AT` will hold shift and press 2. -make_shifted_key('GRAVE', names=('TILDE', 'TILD', '~')) -make_shifted_key('1', names=('EXCLAIM', 'EXLM', '!')) -make_shifted_key('2', names=('AT', '@')) -make_shifted_key('3', names=('HASH', 'POUND', '#')) -make_shifted_key('4', names=('DOLLAR', 'DLR', '$')) -make_shifted_key('5', names=('PERCENT', 'PERC', '%')) -make_shifted_key('6', names=('CIRCUMFLEX', 'CIRC', '^')) -make_shifted_key('7', names=('AMPERSAND', 'AMPR', '&')) -make_shifted_key('8', names=('ASTERISK', 'ASTR', '*')) -make_shifted_key('9', names=('LEFT_PAREN', 'LPRN', '(')) -make_shifted_key('0', names=('RIGHT_PAREN', 'RPRN', ')')) -make_shifted_key('MINUS', names=('UNDERSCORE', 'UNDS', '_')) -make_shifted_key('EQUAL', names=('PLUS', '+')) -make_shifted_key('LBRACKET', names=('LEFT_CURLY_BRACE', 'LCBR', '{')) -make_shifted_key('RBRACKET', names=('RIGHT_CURLY_BRACE', 'RCBR', '}')) -make_shifted_key('BACKSLASH', names=('PIPE', '|')) -make_shifted_key('SEMICOLON', names=('COLON', 'COLN', ':')) -make_shifted_key('QUOTE', names=('DOUBLE_QUOTE', 'DQUO', 'DQT', '"')) -make_shifted_key('COMMA', names=('LEFT_ANGLE_BRACKET', 'LABK', '<')) -make_shifted_key('DOT', names=('RIGHT_ANGLE_BRACKET', 'RABK', '>')) -make_shifted_key('SLSH', names=('QUESTION', 'QUES', '?')) - -# International -make_key(code=50, names=('NONUS_HASH', 'NUHS')) -make_key(code=100, names=('NONUS_BSLASH', 'NUBS')) -make_key(code=101, names=('APP', 'APPLICATION', 'SEL', 'WINMENU')) - -make_key(code=135, names=('INT1', 'RO')) -make_key(code=136, names=('INT2', 'KANA')) -make_key(code=137, names=('INT3', 'JYEN')) -make_key(code=138, names=('INT4', 'HENK')) -make_key(code=139, names=('INT5', 'MHEN')) -make_key(code=140, names=('INT6',)) -make_key(code=141, names=('INT7',)) -make_key(code=142, names=('INT8',)) -make_key(code=143, names=('INT9',)) -make_key(code=144, names=('LANG1', 'HAEN')) -make_key(code=145, names=('LANG2', 'HAEJ')) -make_key(code=146, names=('LANG3',)) -make_key(code=147, names=('LANG4',)) -make_key(code=148, names=('LANG5',)) -make_key(code=149, names=('LANG6',)) -make_key(code=150, names=('LANG7',)) -make_key(code=151, names=('LANG8',)) -make_key(code=152, names=('LANG9',)) - -# Consumer ("media") keys. Most known keys aren't supported here. A much -# longer list used to exist in this file, but the codes were almost certainly -# incorrect, conflicting with each other, or otherwise 'weird'. We'll add them -# back in piecemeal as needed. PRs welcome. -# -# A super useful reference for these is http://www.freebsddiary.org/APC/usb_hid_usages.php -# Note that currently we only have the PC codes. Recent MacOS versions seem to -# support PC media keys, so I don't know how much value we would get out of -# adding the old Apple-specific consumer codes, but again, PRs welcome if the -# lack of them impacts you. -make_consumer_key(code=226, names=('AUDIO_MUTE', 'MUTE')) # 0xE2 -make_consumer_key(code=233, names=('AUDIO_VOL_UP', 'VOLU')) # 0xE9 -make_consumer_key(code=234, names=('AUDIO_VOL_DOWN', 'VOLD')) # 0xEA -make_consumer_key(code=181, names=('MEDIA_NEXT_TRACK', 'MNXT')) # 0xB5 -make_consumer_key(code=182, names=('MEDIA_PREV_TRACK', 'MPRV')) # 0xB6 -make_consumer_key(code=183, names=('MEDIA_STOP', 'MSTP')) # 0xB7 -make_consumer_key( - code=205, names=('MEDIA_PLAY_PAUSE', 'MPLY') -) # 0xCD (this may not be right) -make_consumer_key(code=184, names=('MEDIA_EJECT', 'EJCT')) # 0xB8 -make_consumer_key(code=179, names=('MEDIA_FAST_FORWARD', 'MFFD')) # 0xB3 -make_consumer_key(code=180, names=('MEDIA_REWIND', 'MRWD')) # 0xB4 - -# Internal, diagnostic, or auxiliary/enhanced keys - -# NO and TRNS are functionally identical in how they (don't) mutate -# the state, but are tracked semantically separately, so create -# two keys with the exact same functionality -for names in (('NO',), ('TRANSPARENT', 'TRNS')): - make_key( - names=names, on_press=handlers.passthrough, on_release=handlers.passthrough - ) - -make_key(names=('RESET',), on_press=handlers.reset) -make_key(names=('BOOTLOADER',), on_press=handlers.bootloader) -make_key( - names=('DEBUG', 'DBG'), - on_press=handlers.debug_pressed, - on_release=handlers.passthrough, -) - -make_key( - names=('GESC',), on_press=handlers.gesc_pressed, on_release=handlers.gesc_released -) -make_key( - names=('BKDL',), on_press=handlers.bkdl_pressed, on_release=handlers.bkdl_released -) -make_key( - names=('GESC', 'GRAVE_ESC'), - on_press=handlers.gesc_pressed, - on_release=handlers.gesc_released, -) - -# A dummy key to trigger a sleep_ms call in a sequence of other keys in a -# simple sequence macro. -make_argumented_key( - validator=key_seq_sleep_validator, - names=('MACRO_SLEEP_MS', 'SLEEP_IN_SEQ'), - on_press=handlers.sleep_pressed, -) - -make_key( - names=('UC_MODE_NOOP', 'UC_DISABLE'), - meta=UnicodeModeKeyMeta(UnicodeMode.NOOP), - on_press=handlers.uc_mode_pressed, -) -make_key( - names=('UC_MODE_LINUX', 'UC_MODE_IBUS'), - meta=UnicodeModeKeyMeta(UnicodeMode.IBUS), - on_press=handlers.uc_mode_pressed, -) -make_key( - names=('UC_MODE_MACOS', 'UC_MODE_OSX', 'US_MODE_RALT'), - meta=UnicodeModeKeyMeta(UnicodeMode.RALT), - on_press=handlers.uc_mode_pressed, -) -make_key( - names=('UC_MODE_WINC',), - meta=UnicodeModeKeyMeta(UnicodeMode.WINC), - on_press=handlers.uc_mode_pressed, -) -make_argumented_key( - validator=unicode_mode_key_validator, - names=('UC_MODE',), - on_press=handlers.uc_mode_pressed, -) - -make_argumented_key( - validator=tap_dance_key_validator, - names=('TAP_DANCE', 'TD'), - on_press=handlers.td_pressed, - on_release=handlers.td_released, -) -make_key(names=('HID_SWITCH', 'HID'), on_press=handlers.hid_switch)