From 9c5843782c1d75ea83c1ee94b6590f9ca3aa9979 Mon Sep 17 00:00:00 2001 From: "vincent.tran" Date: Mon, 2 Jan 2023 03:28:23 +0800 Subject: [PATCH 1/5] fix bug for Mac OS Ventura where value of event.name is None --- keyboard/__init__.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/keyboard/__init__.py b/keyboard/__init__.py index 4b8c6ed7..ac04396b 100644 --- a/keyboard/__init__.py +++ b/keyboard/__init__.py @@ -193,7 +193,7 @@ def on_space(): """ from __future__ import print_function as _print_function -version = '0.13.5' +version = '0.13.6' import re as _re import itertools as _itertools @@ -258,7 +258,7 @@ def is_modifier(key): return key in all_modifiers else: if not _modifier_scan_codes: - scan_codes = (key_to_scan_codes(name, False) for name in all_modifiers) + scan_codes = (key_to_scan_codes(name, False) for name in all_modifiers) _modifier_scan_codes.update(*scan_codes) return key in _modifier_scan_codes @@ -536,7 +536,7 @@ def is_pressed(hotkey): if len(steps) > 1: raise ValueError("Impossible to check if multi-step hotkeys are pressed (`a+b` is ok, `a, b` isn't).") - # Convert _pressed_events into a set + # Convert _pressed_events into a set with _pressed_events_lock: pressed_scan_codes = set(_pressed_events) for scan_codes in steps[0]: @@ -558,7 +558,7 @@ def hook(callback, suppress=False, on_remove=lambda: None): """ Installs a global listener on all available keyboards, invoking `callback` each time a key is pressed or released. - + The event passed to the callback is of type `keyboard.KeyboardEvent`, with the following attributes: @@ -697,7 +697,7 @@ def _add_hotkey_step(handler, combinations, suppress): container = _listener.blocking_hotkeys if suppress else _listener.nonblocking_hotkeys # Register the scan codes of every possible combination of - # modfiier + main key. Modifiers have to be registered in + # modfiier + main key. Modifiers have to be registered in # filtered_modifiers too, so suppression and replaying can work. for scan_codes in combinations: for scan_code in scan_codes: @@ -781,7 +781,7 @@ def remove_(): state.remove_last_step = None state.suppressed_events = [] state.last_update = float('-inf') - + def catch_misses(event, force_fail=False): if ( event.event_type == event_type @@ -823,7 +823,7 @@ def handler(event): if event.event_type == KEY_UP: remove() set_index(0) - accept = event.event_type == event_type and callback() + accept = event.event_type == event_type and callback() if accept: return catch_misses(event, force_fail=True) else: @@ -957,7 +957,7 @@ def write(text, delay=0, restore_state_after=True, exact=None): exact = _platform.system() == 'Windows' state = stash_state() - + # Window's typing of unicode characters is quite efficient and should be preferred. if exact: for letter in text: @@ -974,7 +974,7 @@ def write(text, delay=0, restore_state_after=True, exact=None): except (KeyError, ValueError, StopIteration): _os_keyboard.type_unicode(letter) continue - + for modifier in modifiers: press(modifier) @@ -1099,7 +1099,7 @@ def get_typed_strings(events, allow_backspace=True): capslock_pressed = False string = '' for event in events: - name = event.name + name = event.name if event.name is not None else '' # Space is the only key that we _parse_hotkey to the spelled out name # because of legibility. Now we have to undo that. @@ -1266,7 +1266,7 @@ def add_abbreviation(source_text, replacement_text, match_suffix=False, timeout= listener for 'pet'. Defaults to false, only whole words are checked. - `timeout` is the maximum number of seconds between typed characters before the current word is discarded. Defaults to 2 seconds. - + For more details see `add_word_listener`. """ replacement = '\b'*(len(source_text)+1) + replacement_text From 3d88d7b6e7934083381c3578e7dcc7fe1dc5db79 Mon Sep 17 00:00:00 2001 From: "vincent.tran" Date: Mon, 2 Jan 2023 03:31:05 +0800 Subject: [PATCH 2/5] fix bug for Mac OS Ventura where value of event.name is None --- keyboard/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keyboard/__init__.py b/keyboard/__init__.py index ac04396b..65173655 100644 --- a/keyboard/__init__.py +++ b/keyboard/__init__.py @@ -1215,7 +1215,7 @@ def add_word_listener(word, callback, triggers=['space'], match_suffix=False, ti state.time = -1 def handler(event): - name = event.name + name = event.name if event.name is not None else '' if event.event_type == KEY_UP or name in all_modifiers: return if timeout and event.time - state.time > timeout: From 0eb36928c4e396b436255863a6e28069f083e19a Mon Sep 17 00:00:00 2001 From: "vincent.tran" Date: Mon, 2 Jan 2023 05:33:25 +0800 Subject: [PATCH 3/5] test fix --- keyboard/_darwinkeyboard.py | 78 ++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/keyboard/_darwinkeyboard.py b/keyboard/_darwinkeyboard.py index e43c2100..f204878f 100644 --- a/keyboard/_darwinkeyboard.py +++ b/keyboard/_darwinkeyboard.py @@ -68,7 +68,73 @@ class KeyMap(object): 0x7d: 'down', 0x7e: 'up', }.items()) - layout_specific_keys = {} + layout_specific_keys = { + 0x00: ('a', 'A'), + 0x01: ('s', 'S'), + 0x02: ('d', 'D'), + 0x03: ('f', 'F'), + 0x04: ('h', 'H'), + # kVK_ANSI_G = 0x05, + # kVK_ANSI_Z = 0x06, + # kVK_ANSI_X = 0x07, + # kVK_ANSI_C = 0x08, + # kVK_ANSI_V = 0x09, + 0x0B: ('b', 'B'), + # kVK_ANSI_Q = 0x0C, + # kVK_ANSI_W = 0x0D, + # kVK_ANSI_E = 0x0E, + # kVK_ANSI_R = 0x0F, + # kVK_ANSI_Y = 0x10, + # kVK_ANSI_T = 0x11, + 0x12: ('1', '1'), + 0x13: ('2', '2'), + 0x14: ('3', '3'), + 0x15: ('4', '4'), + 0x16: ('6', '6'), + 0x17: ('5', '5'), + # kVK_ANSI_Equal = 0x18, + # kVK_ANSI_9 = 0x19, + # kVK_ANSI_7 = 0x1A, + # kVK_ANSI_Minus = 0x1B, + # kVK_ANSI_8 = 0x1C, + # kVK_ANSI_0 = 0x1D, + # kVK_ANSI_RightBracket = 0x1E, + # kVK_ANSI_O = 0x1F, + # kVK_ANSI_U = 0x20, + # kVK_ANSI_LeftBracket = 0x21, + # kVK_ANSI_I = 0x22, + # kVK_ANSI_P = 0x23, + # kVK_ANSI_L = 0x25, + # kVK_ANSI_J = 0x26, + # kVK_ANSI_Quote = 0x27, + # kVK_ANSI_K = 0x28, + # kVK_ANSI_Semicolon = 0x29, + # kVK_ANSI_Backslash = 0x2A, + # kVK_ANSI_Comma = 0x2B, + # kVK_ANSI_Slash = 0x2C, + # kVK_ANSI_N = 0x2D, + # kVK_ANSI_M = 0x2E, + # kVK_ANSI_Period = 0x2F, + # kVK_ANSI_Grave = 0x32, + # kVK_ANSI_KeypadDecimal = 0x41, + # kVK_ANSI_KeypadMultiply = 0x43, + # kVK_ANSI_KeypadPlus = 0x45, + # kVK_ANSI_KeypadClear = 0x47, + # kVK_ANSI_KeypadDivide = 0x4B, + # kVK_ANSI_KeypadEnter = 0x4C, + # kVK_ANSI_KeypadMinus = 0x4E, + # kVK_ANSI_KeypadEquals = 0x51, + # kVK_ANSI_Keypad0 = 0x52, + # kVK_ANSI_Keypad1 = 0x53, + # kVK_ANSI_Keypad2 = 0x54, + # kVK_ANSI_Keypad3 = 0x55, + # kVK_ANSI_Keypad4 = 0x56, + # kVK_ANSI_Keypad5 = 0x57, + # kVK_ANSI_Keypad6 = 0x58, + # kVK_ANSI_Keypad7 = 0x59, + # kVK_ANSI_Keypad8 = 0x5B, + # kVK_ANSI_Keypad9 = 0x5C + } def __init__(self): # Virtual key codes are usually the same for any given key, unless you have a different # keyboard layout. The only way I've found to determine the layout relies on (supposedly @@ -167,8 +233,8 @@ class CFRange(ctypes.Structure): shifted_char) shifted_key = u''.join(unichr(shifted_char[i]) for i in range(char_count.value)) - - self.layout_specific_keys[key_code] = (non_shifted_key, shifted_key) + if non_shifted_key: + self.layout_specific_keys[key_code] = (non_shifted_key, shifted_key) # Cleanup Carbon.CFRelease(klis) @@ -236,7 +302,7 @@ def __init__(self): 'KEYTYPE_ILLUMINATION_DOWN': 22, 'KEYTYPE_ILLUMINATION_TOGGLE': 23 } - + def press(self, key_code): """ Sends a 'down' event for the specified scan code """ if key_code >= 128: @@ -444,7 +510,7 @@ def release(scan_code): key_controller.release(scan_code) def map_name(name): - """ Returns a tuple of (scan_code, modifiers) where ``scan_code`` is a numeric scan code + """ Returns a tuple of (scan_code, modifiers) where ``scan_code`` is a numeric scan code and ``modifiers`` is an array of string modifier names (like 'shift') """ yield key_controller.map_char(name) @@ -464,4 +530,4 @@ def type_unicode(character): # Key up event = Quartz.CGEventCreateKeyboardEvent(OUTPUT_SOURCE, 0, False) Quartz.CGEventKeyboardSetUnicodeString(event, len(character.encode('utf-16-le')) // 2, character) - Quartz.CGEventPost(Quartz.kCGSessionEventTap, event) \ No newline at end of file + Quartz.CGEventPost(Quartz.kCGSessionEventTap, event) From 80447b436991e61d6f36c0b6e23d76c9cc2b6073 Mon Sep 17 00:00:00 2001 From: "vincent.tran" Date: Mon, 2 Jan 2023 14:45:58 +0800 Subject: [PATCH 4/5] test fix 2 --- keyboard/_darwinkeyboard.py | 82 ++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/keyboard/_darwinkeyboard.py b/keyboard/_darwinkeyboard.py index f204878f..69fb5da6 100644 --- a/keyboard/_darwinkeyboard.py +++ b/keyboard/_darwinkeyboard.py @@ -74,48 +74,48 @@ class KeyMap(object): 0x02: ('d', 'D'), 0x03: ('f', 'F'), 0x04: ('h', 'H'), - # kVK_ANSI_G = 0x05, - # kVK_ANSI_Z = 0x06, - # kVK_ANSI_X = 0x07, - # kVK_ANSI_C = 0x08, - # kVK_ANSI_V = 0x09, + 0x05: ('g', 'G'), + 0x06: ('z', 'Z'), + 0x07: ('x', 'X'), + 0x08: ('c', 'C'), + 0x09: ('v', 'V'), 0x0B: ('b', 'B'), - # kVK_ANSI_Q = 0x0C, - # kVK_ANSI_W = 0x0D, - # kVK_ANSI_E = 0x0E, - # kVK_ANSI_R = 0x0F, - # kVK_ANSI_Y = 0x10, - # kVK_ANSI_T = 0x11, - 0x12: ('1', '1'), - 0x13: ('2', '2'), - 0x14: ('3', '3'), - 0x15: ('4', '4'), - 0x16: ('6', '6'), - 0x17: ('5', '5'), - # kVK_ANSI_Equal = 0x18, - # kVK_ANSI_9 = 0x19, - # kVK_ANSI_7 = 0x1A, - # kVK_ANSI_Minus = 0x1B, - # kVK_ANSI_8 = 0x1C, - # kVK_ANSI_0 = 0x1D, - # kVK_ANSI_RightBracket = 0x1E, - # kVK_ANSI_O = 0x1F, - # kVK_ANSI_U = 0x20, - # kVK_ANSI_LeftBracket = 0x21, - # kVK_ANSI_I = 0x22, - # kVK_ANSI_P = 0x23, - # kVK_ANSI_L = 0x25, - # kVK_ANSI_J = 0x26, - # kVK_ANSI_Quote = 0x27, - # kVK_ANSI_K = 0x28, - # kVK_ANSI_Semicolon = 0x29, - # kVK_ANSI_Backslash = 0x2A, - # kVK_ANSI_Comma = 0x2B, - # kVK_ANSI_Slash = 0x2C, - # kVK_ANSI_N = 0x2D, - # kVK_ANSI_M = 0x2E, - # kVK_ANSI_Period = 0x2F, - # kVK_ANSI_Grave = 0x32, + 0x0C: ('q', 'Q'), + 0x0D: ('w', 'W'), + 0x0E: ('e', 'E'), + 0x0F: ('r', 'R'), + 0x10: ('y', 'Y'), + 0x11: ('t', 'T'), + 0x12: ('1', '!'), + 0x13: ('2', '@'), + 0x14: ('3', '#'), + 0x15: ('4', '$'), + 0x16: ('6', '^'), + 0x17: ('5', '%'), + 0x18: ('=', '+'), + 0x19: ('9', '('), + 0x1A: ('7', '&'), + 0x1B: ('-', '_'), + 0x1C: ('8', '*'), + 0x1D: ('0', ')'), + 0x1E: (']', '}'), + 0x1F: ('o', 'O'), + 0x20: ('u', 'U'), + 0x21: ('[', '{'), + 0x22: ('i', 'I'), + 0x23: ('p', 'P'), + 0x25: ('l', 'L'), + 0x26: ('j', 'J'), + 0x27: ("'", '"'), + 0x28: ('k', 'K'), + 0x29: (';', ':'), + 0x2A: (r"\\", r"|"), + 0x2B: (',', '<'), + 0x2C: ('/', '?'), + 0x2D: ('n', 'N'), + 0x2E: ('m', 'M'), + 0x2F: ('.', '>'), + 0x32: ('`', '~'), # kVK_ANSI_KeypadDecimal = 0x41, # kVK_ANSI_KeypadMultiply = 0x43, # kVK_ANSI_KeypadPlus = 0x45, From 18ffa6d2c92d9a7280c5b6b91b19f46ab0434c1d Mon Sep 17 00:00:00 2001 From: "vincent.tran" Date: Mon, 2 Jan 2023 15:01:43 +0800 Subject: [PATCH 5/5] test fix 3 --- keyboard/_darwinkeyboard.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/keyboard/_darwinkeyboard.py b/keyboard/_darwinkeyboard.py index 69fb5da6..7a3f4b39 100644 --- a/keyboard/_darwinkeyboard.py +++ b/keyboard/_darwinkeyboard.py @@ -25,6 +25,7 @@ class KeyMap(object): 0x31: 'space', 0x33: 'delete', 0x35: 'escape', + 0x36: 'right command', 0x37: 'command', 0x38: 'shift', 0x39: 'capslock', @@ -109,7 +110,7 @@ class KeyMap(object): 0x27: ("'", '"'), 0x28: ('k', 'K'), 0x29: (';', ':'), - 0x2A: (r"\\", r"|"), + 0x2A: ("\\", r"|"), 0x2B: (',', '<'), 0x2C: ('/', '?'), 0x2D: ('n', 'N'),