Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #585 Mac OS Ventura compatibility issue! #587

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions keyboard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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]:
Expand All @@ -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:

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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)

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
79 changes: 73 additions & 6 deletions keyboard/_darwinkeyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class KeyMap(object):
0x31: 'space',
0x33: 'delete',
0x35: 'escape',
0x36: 'right command',
0x37: 'command',
0x38: 'shift',
0x39: 'capslock',
Expand Down Expand Up @@ -68,7 +69,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'),
0x05: ('g', 'G'),
0x06: ('z', 'Z'),
0x07: ('x', 'X'),
0x08: ('c', 'C'),
0x09: ('v', 'V'),
0x0B: ('b', 'B'),
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"|"),
0x2B: (',', '<'),
0x2C: ('/', '?'),
0x2D: ('n', 'N'),
0x2E: ('m', 'M'),
0x2F: ('.', '>'),
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
Expand Down Expand Up @@ -167,8 +234,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)

Expand Down Expand Up @@ -236,7 +303,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:
Expand Down Expand Up @@ -444,7 +511,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)

Expand All @@ -464,4 +531,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)
Quartz.CGEventPost(Quartz.kCGSessionEventTap, event)