Merge pull request #133 from KMKfw/topic-misc-perf
Slight perf improvements, heavily improved logging/debugging output
This commit is contained in:
commit
f6a39acd26
134
kmk/firmware.py
134
kmk/firmware.py
@ -15,16 +15,18 @@
|
|||||||
# chain to import _every single thing_ KMK eventually uses in a normal
|
# chain to import _every single thing_ KMK eventually uses in a normal
|
||||||
# workflow, in order from fewest to least nested dependencies.
|
# workflow, in order from fewest to least nested dependencies.
|
||||||
|
|
||||||
# First, stuff that has no dependencies, or only C/MPY deps
|
# First, system-provided deps
|
||||||
|
import busio # isort:skip
|
||||||
import collections # isort:skip
|
import collections # isort:skip
|
||||||
|
import gc # isort:skip
|
||||||
|
import supervisor # isort:skip
|
||||||
|
|
||||||
|
# Now "light" KMK stuff with few/no external deps
|
||||||
import kmk.consts # isort:skip
|
import kmk.consts # isort:skip
|
||||||
import kmk.kmktime # isort:skip
|
import kmk.kmktime # isort:skip
|
||||||
import kmk.types # isort:skip
|
import kmk.types # isort:skip
|
||||||
import kmk.util # isort:skip
|
import kmk.util # isort:skip
|
||||||
|
|
||||||
import busio # isort:skip
|
|
||||||
|
|
||||||
import supervisor # isort:skip
|
|
||||||
from kmk.consts import LeaderMode, UnicodeMode # isort:skip
|
from kmk.consts import LeaderMode, UnicodeMode # isort:skip
|
||||||
from kmk.hid import USB_HID # isort:skip
|
from kmk.hid import USB_HID # isort:skip
|
||||||
from kmk.internal_state import InternalState # isort:skip
|
from kmk.internal_state import InternalState # isort:skip
|
||||||
@ -48,6 +50,7 @@ import kmk.internal_state # isort:skip
|
|||||||
|
|
||||||
# Thanks for sticking around. Now let's do real work, starting below
|
# Thanks for sticking around. Now let's do real work, starting below
|
||||||
|
|
||||||
|
from kmk.kmktime import sleep_ms
|
||||||
from kmk.util import intify_coordinate as ic
|
from kmk.util import intify_coordinate as ic
|
||||||
|
|
||||||
|
|
||||||
@ -100,6 +103,76 @@ class Firmware:
|
|||||||
|
|
||||||
self._state = InternalState(self)
|
self._state = InternalState(self)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return (
|
||||||
|
'Firmware('
|
||||||
|
'debug_enabled={} '
|
||||||
|
'keymap=truncated '
|
||||||
|
'coord_mapping=truncated '
|
||||||
|
'row_pins=truncated '
|
||||||
|
'col_pins=truncated '
|
||||||
|
'diode_orientation={} '
|
||||||
|
'matrix_scanner={} '
|
||||||
|
'unicode_mode={} '
|
||||||
|
'tap_time={} '
|
||||||
|
'leader_mode={} '
|
||||||
|
'leader_dictionary=truncated '
|
||||||
|
'leader_timeout={} '
|
||||||
|
'hid_helper={} '
|
||||||
|
'extra_data_pin={} '
|
||||||
|
'split_offsets={} '
|
||||||
|
'split_flip={} '
|
||||||
|
'split_side={} '
|
||||||
|
'split_type={} '
|
||||||
|
'split_master_left={} '
|
||||||
|
'is_master={} '
|
||||||
|
'uart={} '
|
||||||
|
'uart_flip={} '
|
||||||
|
'uart_pin={}'
|
||||||
|
')'
|
||||||
|
).format(
|
||||||
|
self.debug_enabled,
|
||||||
|
# self.keymap,
|
||||||
|
# self.coord_mapping,
|
||||||
|
# self.row_pins,
|
||||||
|
# self.col_pins,
|
||||||
|
self.diode_orientation,
|
||||||
|
self.matrix_scanner,
|
||||||
|
self.unicode_mode,
|
||||||
|
self.tap_time,
|
||||||
|
self.leader_mode,
|
||||||
|
# self.leader_dictionary,
|
||||||
|
self.leader_timeout,
|
||||||
|
self.hid_helper.__name__,
|
||||||
|
self.extra_data_pin,
|
||||||
|
self.split_offsets,
|
||||||
|
self.split_flip,
|
||||||
|
self.split_side,
|
||||||
|
self.split_type,
|
||||||
|
self.split_master_left,
|
||||||
|
self.is_master,
|
||||||
|
self.uart,
|
||||||
|
self.uart_flip,
|
||||||
|
self.uart_pin,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _print_debug_cycle(self, init=False):
|
||||||
|
pre_alloc = gc.mem_alloc()
|
||||||
|
pre_free = gc.mem_free()
|
||||||
|
|
||||||
|
if self.debug_enabled:
|
||||||
|
if init:
|
||||||
|
print('KMKInit()')
|
||||||
|
|
||||||
|
print(self)
|
||||||
|
print(self._state)
|
||||||
|
print('GCStats(pre_alloc={} pre_free={} alloc={} free={})'.format(
|
||||||
|
pre_alloc,
|
||||||
|
pre_free,
|
||||||
|
gc.mem_alloc(),
|
||||||
|
gc.mem_free(),
|
||||||
|
))
|
||||||
|
|
||||||
def _send_hid(self):
|
def _send_hid(self):
|
||||||
self._hid_helper_inst.create_report(self._state.keys_pressed).send()
|
self._hid_helper_inst.create_report(self._state.keys_pressed).send()
|
||||||
self._state.resolve_hid()
|
self._state.resolve_hid()
|
||||||
@ -155,21 +228,8 @@ class Firmware:
|
|||||||
self.uart.write('DEB')
|
self.uart.write('DEB')
|
||||||
self.uart.write(message, '\n')
|
self.uart.write(message, '\n')
|
||||||
|
|
||||||
def _master_half(self):
|
|
||||||
if self.is_master is not None:
|
|
||||||
return self.is_master
|
|
||||||
|
|
||||||
# Working around https://github.com/adafruit/circuitpython/issues/1769
|
|
||||||
try:
|
|
||||||
self._hid_helper_inst.create_report([]).send()
|
|
||||||
self.is_master = True
|
|
||||||
except OSError:
|
|
||||||
self.is_master = False
|
|
||||||
|
|
||||||
return self.is_master
|
|
||||||
|
|
||||||
def init_uart(self, pin, timeout=20):
|
def init_uart(self, pin, timeout=20):
|
||||||
if self._master_half():
|
if self.is_master:
|
||||||
return busio.UART(tx=None, rx=pin, timeout=timeout)
|
return busio.UART(tx=None, rx=pin, timeout=timeout)
|
||||||
else:
|
else:
|
||||||
return busio.UART(tx=pin, rx=None, timeout=timeout)
|
return busio.UART(tx=pin, rx=None, timeout=timeout)
|
||||||
@ -183,13 +243,27 @@ class Firmware:
|
|||||||
self._hid_helper_inst = self.hid_helper()
|
self._hid_helper_inst = self.hid_helper()
|
||||||
|
|
||||||
# Split keyboard Init
|
# Split keyboard Init
|
||||||
if self.split_flip and not self._master_half():
|
if self.split_type is not None:
|
||||||
self.col_pins = list(reversed(self.col_pins))
|
try:
|
||||||
|
# Working around https://github.com/adafruit/circuitpython/issues/1769
|
||||||
|
self._hid_helper_inst.create_report([]).send()
|
||||||
|
self.is_master = True
|
||||||
|
|
||||||
if self.split_side == "Left":
|
# Sleep 2s so master portion doesn't "appear" to boot quicker than
|
||||||
self.split_master_left = self._master_half()
|
# dependent portions (which will take ~2s to time out on the HID send)
|
||||||
elif self.split_side == "Right":
|
sleep_ms(2000)
|
||||||
self.split_master_left = not self._master_half()
|
except OSError:
|
||||||
|
self.is_master = False
|
||||||
|
|
||||||
|
if self.split_flip and not self.is_master:
|
||||||
|
self.col_pins = list(reversed(self.col_pins))
|
||||||
|
|
||||||
|
if self.split_side == "Left":
|
||||||
|
self.split_master_left = self.is_master
|
||||||
|
elif self.split_side == "Right":
|
||||||
|
self.split_master_left = not self.is_master
|
||||||
|
else:
|
||||||
|
self.is_master = True
|
||||||
|
|
||||||
if self.uart_pin is not None:
|
if self.uart_pin is not None:
|
||||||
self.uart = self.init_uart(self.uart_pin)
|
self.uart = self.init_uart(self.uart_pin)
|
||||||
@ -211,13 +285,13 @@ class Firmware:
|
|||||||
if not isinstance(k, tuple):
|
if not isinstance(k, tuple):
|
||||||
del self.leader_dictionary[k]
|
del self.leader_dictionary[k]
|
||||||
|
|
||||||
if self.debug_enabled:
|
gc.collect()
|
||||||
print("Firin' lazers. Keyboard is booted.")
|
self._print_debug_cycle(init=True)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
state_changed = False
|
state_changed = False
|
||||||
|
|
||||||
if self.split_type is not None and self._master_half:
|
if self.split_type is not None and self.is_master:
|
||||||
update = self._receive_from_slave()
|
update = self._receive_from_slave()
|
||||||
if update is not None:
|
if update is not None:
|
||||||
self._handle_matrix_report(update)
|
self._handle_matrix_report(update)
|
||||||
@ -226,7 +300,7 @@ class Firmware:
|
|||||||
update = self.matrix.scan_for_changes()
|
update = self.matrix.scan_for_changes()
|
||||||
|
|
||||||
if update is not None:
|
if update is not None:
|
||||||
if self._master_half():
|
if self.is_master:
|
||||||
self._handle_matrix_report(update)
|
self._handle_matrix_report(update)
|
||||||
state_changed = True
|
state_changed = True
|
||||||
else:
|
else:
|
||||||
@ -246,5 +320,5 @@ class Firmware:
|
|||||||
if self._state.hid_pending:
|
if self._state.hid_pending:
|
||||||
self._send_hid()
|
self._send_hid()
|
||||||
|
|
||||||
if self.debug_enabled and state_changed:
|
if state_changed:
|
||||||
print('New State: {}'.format(self._state._to_dict()))
|
self._print_debug_cycle()
|
||||||
|
@ -3,24 +3,31 @@ from kmk.kmktime import ticks_diff, ticks_ms
|
|||||||
|
|
||||||
def df_pressed(key, state, *args, **kwargs):
|
def df_pressed(key, state, *args, **kwargs):
|
||||||
"""Switches the default layer"""
|
"""Switches the default layer"""
|
||||||
state.active_layers[0] = key.meta.layer
|
state.active_layers[-1] = key.meta.layer
|
||||||
state.reversed_active_layers = list(reversed(state.active_layers))
|
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
||||||
def mo_pressed(key, state, *args, **kwargs):
|
def mo_pressed(key, state, *args, **kwargs):
|
||||||
"""Momentarily activates layer, switches off when you let go"""
|
"""Momentarily activates layer, switches off when you let go"""
|
||||||
state.active_layers.append(key.meta.layer)
|
state.active_layers.insert(0, key.meta.layer)
|
||||||
state.reversed_active_layers = list(reversed(state.active_layers))
|
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
||||||
def mo_released(key, state, KC, *args, **kwargs):
|
def mo_released(key, state, KC, *args, **kwargs):
|
||||||
state.active_layers = [
|
# remove the first instance of the target layer
|
||||||
layer for layer in state.active_layers
|
# from the active list
|
||||||
if layer != key.meta.layer
|
# under almost all normal use cases, this will
|
||||||
]
|
# disable the layer (but preserve it if it was triggered
|
||||||
state.reversed_active_layers = list(reversed(state.active_layers))
|
# as a default layer, etc.)
|
||||||
|
# this also resolves an issue where using DF() on a layer
|
||||||
|
# triggered by MO() and then defaulting to the MO()'s layer
|
||||||
|
# would result in no layers active
|
||||||
|
try:
|
||||||
|
del_idx = state.active_layers.index(key.meta.layer)
|
||||||
|
del state.active_layers[del_idx]
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
||||||
@ -62,23 +69,21 @@ def lt_released(key, state, *args, **kwargs):
|
|||||||
|
|
||||||
def tg_pressed(key, state, *args, **kwargs):
|
def tg_pressed(key, state, *args, **kwargs):
|
||||||
"""Toggles the layer (enables it if not active, and vise versa)"""
|
"""Toggles the layer (enables it if not active, and vise versa)"""
|
||||||
if key.meta.layer in state.active_layers:
|
|
||||||
state.active_layers = [
|
|
||||||
layer for layer in state.active_layers
|
|
||||||
if layer != key.meta.layer
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
state.active_layers.append(key.meta.layer)
|
|
||||||
|
|
||||||
state.reversed_active_layers = list(reversed(state.active_layers))
|
# See mo_released for implementation details around this
|
||||||
|
try:
|
||||||
|
del_idx = state.active_layers.index(key.meta.layer)
|
||||||
|
del state.active_layers[del_idx]
|
||||||
|
except ValueError:
|
||||||
|
state.active_layers.insert(0, key.meta.layer)
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
||||||
def to_pressed(key, state, *args, **kwargs):
|
def to_pressed(key, state, *args, **kwargs):
|
||||||
"""Activates layer and deactivates all other layers"""
|
"""Activates layer and deactivates all other layers"""
|
||||||
state.active_layers = [key.meta.layer]
|
state.active_layers.clear()
|
||||||
state.reversed_active_layers = list(reversed(state.active_layers))
|
state.active_layers.insert(0, key.meta.layer)
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
@ -38,9 +38,9 @@ def bootloader(*args, **kwargs):
|
|||||||
|
|
||||||
def debug_pressed(key, state, KC, *args, **kwargs):
|
def debug_pressed(key, state, KC, *args, **kwargs):
|
||||||
if state.config.debug_enabled:
|
if state.config.debug_enabled:
|
||||||
print('Disabling debug mode, bye!')
|
print('DebugDisable()')
|
||||||
else:
|
else:
|
||||||
print('Enabling debug mode. Welcome to the jungle.')
|
print('DebugEnable()')
|
||||||
|
|
||||||
state.config.debug_enabled = not state.config.debug_enabled
|
state.config.debug_enabled = not state.config.debug_enabled
|
||||||
|
|
||||||
|
@ -21,6 +21,12 @@ class USB_HID:
|
|||||||
|
|
||||||
self.post_init()
|
self.post_init()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '{}(REPORT_BYTES={})'.format(
|
||||||
|
self.__class__.__name__,
|
||||||
|
self.REPORT_BYTES,
|
||||||
|
)
|
||||||
|
|
||||||
def post_init(self):
|
def post_init(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -12,8 +12,12 @@ class InternalState:
|
|||||||
leader_last_len = 0
|
leader_last_len = 0
|
||||||
hid_pending = False
|
hid_pending = False
|
||||||
leader_mode_history = []
|
leader_mode_history = []
|
||||||
|
|
||||||
|
# this should almost always be PREpended to, replaces
|
||||||
|
# former use of reversed_active_layers which had pointless
|
||||||
|
# overhead (the underlying list was never used anyway)
|
||||||
active_layers = [0]
|
active_layers = [0]
|
||||||
reversed_active_layers = list(reversed(active_layers))
|
|
||||||
start_time = {
|
start_time = {
|
||||||
'lt': None,
|
'lt': None,
|
||||||
'tg': None,
|
'tg': None,
|
||||||
@ -30,21 +34,35 @@ class InternalState:
|
|||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'InternalState({})'.format(self._to_dict())
|
return (
|
||||||
|
'InternalState('
|
||||||
def _to_dict(self):
|
'keys_pressed={} '
|
||||||
ret = {
|
'coord_keys_pressed={} '
|
||||||
'keys_pressed': self.keys_pressed,
|
'leader_pending={} '
|
||||||
'active_layers': self.active_layers,
|
'leader_last_len={} '
|
||||||
'leader_mode_history': self.leader_mode_history,
|
'hid_pending={} '
|
||||||
'leader_mode': self.config.leader_mode,
|
'leader_mode_history={} '
|
||||||
'start_time': self.start_time,
|
'active_layers={} '
|
||||||
'tapping': self.tapping,
|
'start_time={} '
|
||||||
'tap_dance_counts': self.tap_dance_counts,
|
'timeouts={} '
|
||||||
'timeouts': self.timeouts,
|
'tapping={} '
|
||||||
}
|
'tap_dance_counts={} '
|
||||||
|
'tap_side_effects={}'
|
||||||
return ret
|
')'
|
||||||
|
).format(
|
||||||
|
self.keys_pressed,
|
||||||
|
self.coord_keys_pressed,
|
||||||
|
self.leader_pending,
|
||||||
|
self.leader_last_len,
|
||||||
|
self.hid_pending,
|
||||||
|
self.leader_mode_history,
|
||||||
|
self.active_layers,
|
||||||
|
self.start_time,
|
||||||
|
self.timeouts,
|
||||||
|
self.tapping,
|
||||||
|
self.tap_dance_counts,
|
||||||
|
self.tap_side_effects,
|
||||||
|
)
|
||||||
|
|
||||||
def _find_key_in_map(self, row, col):
|
def _find_key_in_map(self, row, col):
|
||||||
ic = intify_coordinate(row, col)
|
ic = intify_coordinate(row, col)
|
||||||
@ -54,7 +72,7 @@ class InternalState:
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
if self.config.debug_enabled:
|
if self.config.debug_enabled:
|
||||||
print(
|
print(
|
||||||
'No coord_mapping index for value {}, row={} col={}'.format(
|
'CoordMappingNotFound(ic={}, row={}, col={})'.format(
|
||||||
ic,
|
ic,
|
||||||
row,
|
row,
|
||||||
col,
|
col,
|
||||||
@ -63,16 +81,14 @@ class InternalState:
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Later-added layers have priority. Sift through the layers
|
for layer in self.active_layers:
|
||||||
# in reverse order until we find a valid keycode object
|
|
||||||
for layer in self.reversed_active_layers:
|
|
||||||
layer_key = self.config.keymap[layer][idx]
|
layer_key = self.config.keymap[layer][idx]
|
||||||
|
|
||||||
if not layer_key or layer_key == KC.TRNS:
|
if not layer_key or layer_key == KC.TRNS:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.config.debug_enabled:
|
if self.config.debug_enabled:
|
||||||
print('Resolved key: {}'.format(layer_key))
|
print('KeyResolution(key={})'.format(layer_key))
|
||||||
|
|
||||||
return layer_key
|
return layer_key
|
||||||
|
|
||||||
@ -112,15 +128,17 @@ class InternalState:
|
|||||||
|
|
||||||
def matrix_changed(self, row, col, is_pressed):
|
def matrix_changed(self, row, col, is_pressed):
|
||||||
if self.config.debug_enabled:
|
if self.config.debug_enabled:
|
||||||
print('Matrix changed (col, row, pressed?): {}, {}, {}'.format(
|
print('MatrixChange(col={} row={} pressed={})'.format(
|
||||||
col, row, is_pressed,
|
col,
|
||||||
|
row,
|
||||||
|
is_pressed,
|
||||||
))
|
))
|
||||||
|
|
||||||
int_coord = intify_coordinate(row, col)
|
int_coord = intify_coordinate(row, col)
|
||||||
kc_changed = self._find_key_in_map(row, col)
|
kc_changed = self._find_key_in_map(row, col)
|
||||||
|
|
||||||
if kc_changed is None:
|
if kc_changed is None:
|
||||||
print('No key accessible for col, row: {}, {}'.format(row, col))
|
print('MatrixUndefinedCoordinate(col={} row={})'.format(col, row))
|
||||||
return self
|
return self
|
||||||
|
|
||||||
return self.process_key(kc_changed, is_pressed, int_coord, (row, col))
|
return self.process_key(kc_changed, is_pressed, int_coord, (row, col))
|
||||||
|
32
kmk/key_validators.py
Normal file
32
kmk/key_validators.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from kmk.types import (KeySeqSleepMeta, LayerKeyMeta, ModTapKeyMeta,
|
||||||
|
TapDanceKeyMeta, UnicodeModeKeyMeta)
|
||||||
|
|
||||||
|
|
||||||
|
def key_seq_sleep_validator(ms):
|
||||||
|
return KeySeqSleepMeta(ms)
|
||||||
|
|
||||||
|
|
||||||
|
def layer_key_validator(layer, kc=None):
|
||||||
|
'''
|
||||||
|
Validates the syntax (but not semantics) of a layer key call. We won't
|
||||||
|
have access to the keymap here, so we can't verify much of anything useful
|
||||||
|
here (like whether the target layer actually exists). The spirit of this
|
||||||
|
existing is mostly that Python will catch extraneous args/kwargs and error
|
||||||
|
out.
|
||||||
|
'''
|
||||||
|
return LayerKeyMeta(layer=layer, kc=kc)
|
||||||
|
|
||||||
|
|
||||||
|
def mod_tap_validator(kc, mods=None):
|
||||||
|
'''
|
||||||
|
Validates that mod tap keys are correctly used
|
||||||
|
'''
|
||||||
|
return ModTapKeyMeta(kc=kc, mods=mods)
|
||||||
|
|
||||||
|
|
||||||
|
def tap_dance_key_validator(*codes):
|
||||||
|
return TapDanceKeyMeta(codes)
|
||||||
|
|
||||||
|
|
||||||
|
def unicode_mode_key_validator(mode):
|
||||||
|
return UnicodeModeKeyMeta(mode)
|
71
kmk/keys.py
71
kmk/keys.py
@ -1,11 +1,11 @@
|
|||||||
import gc
|
|
||||||
|
|
||||||
import kmk.handlers.layers as layers
|
import kmk.handlers.layers as layers
|
||||||
import kmk.handlers.modtap as modtap
|
import kmk.handlers.modtap as modtap
|
||||||
import kmk.handlers.stock as handlers
|
import kmk.handlers.stock as handlers
|
||||||
from kmk.consts import UnicodeMode
|
from kmk.consts import UnicodeMode
|
||||||
from kmk.types import (AttrDict, KeySeqSleepMeta, LayerKeyMeta, ModTapKeyMeta,
|
from kmk.key_validators import (key_seq_sleep_validator, layer_key_validator,
|
||||||
TapDanceKeyMeta, UnicodeModeKeyMeta)
|
mod_tap_validator, tap_dance_key_validator,
|
||||||
|
unicode_mode_key_validator)
|
||||||
|
from kmk.types import AttrDict, UnicodeModeKeyMeta
|
||||||
|
|
||||||
FIRST_KMK_INTERNAL_KEY = 1000
|
FIRST_KMK_INTERNAL_KEY = 1000
|
||||||
NEXT_AVAILABLE_KEY = 1000
|
NEXT_AVAILABLE_KEY = 1000
|
||||||
@ -367,8 +367,6 @@ def make_argumented_key(
|
|||||||
return _argumented_key
|
return _argumented_key
|
||||||
|
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
# Modifiers
|
# Modifiers
|
||||||
make_mod_key(code=0x01, names=('LEFT_CONTROL', 'LCTRL', 'LCTL'))
|
make_mod_key(code=0x01, names=('LEFT_CONTROL', 'LCTRL', 'LCTL'))
|
||||||
make_mod_key(code=0x02, names=('LEFT_SHIFT', 'LSHIFT', 'LSFT'))
|
make_mod_key(code=0x02, names=('LEFT_SHIFT', 'LSHIFT', 'LSFT'))
|
||||||
@ -383,8 +381,6 @@ make_mod_key(code=0x07, names=('MEH',))
|
|||||||
# HYPR = LCTL | LALT | LSFT | LGUI
|
# HYPR = LCTL | LALT | LSFT | LGUI
|
||||||
make_mod_key(code=0x0F, names=('HYPER', 'HYPR'))
|
make_mod_key(code=0x0F, names=('HYPER', 'HYPR'))
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
# Basic ASCII letters
|
# Basic ASCII letters
|
||||||
make_key(code=4, names=('A',))
|
make_key(code=4, names=('A',))
|
||||||
make_key(code=5, names=('B',))
|
make_key(code=5, names=('B',))
|
||||||
@ -413,8 +409,6 @@ make_key(code=27, names=('X',))
|
|||||||
make_key(code=28, names=('Y',))
|
make_key(code=28, names=('Y',))
|
||||||
make_key(code=29, names=('Z',))
|
make_key(code=29, names=('Z',))
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
# Numbers
|
# Numbers
|
||||||
# Aliases to play nicely with AttrDict, since KC.1 isn't a valid
|
# Aliases to play nicely with AttrDict, since KC.1 isn't a valid
|
||||||
# attribute key in Python, but KC.N1 is
|
# attribute key in Python, but KC.N1 is
|
||||||
@ -429,8 +423,6 @@ make_key(code=37, names=('8', 'N8'))
|
|||||||
make_key(code=38, names=('9', 'N9'))
|
make_key(code=38, names=('9', 'N9'))
|
||||||
make_key(code=39, names=('0', 'N0'))
|
make_key(code=39, names=('0', 'N0'))
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
# More ASCII standard keys
|
# More ASCII standard keys
|
||||||
make_key(code=40, names=('ENTER', 'ENT', "\n"))
|
make_key(code=40, names=('ENTER', 'ENT', "\n"))
|
||||||
make_key(code=41, names=('ESCAPE', 'ESC'))
|
make_key(code=41, names=('ESCAPE', 'ESC'))
|
||||||
@ -449,8 +441,6 @@ make_key(code=54, names=('COMMA', 'COMM', ','))
|
|||||||
make_key(code=55, names=('DOT', '.'))
|
make_key(code=55, names=('DOT', '.'))
|
||||||
make_key(code=56, names=('SLASH', 'SLSH'))
|
make_key(code=56, names=('SLASH', 'SLSH'))
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
# Function Keys
|
# Function Keys
|
||||||
make_key(code=58, names=('F1',))
|
make_key(code=58, names=('F1',))
|
||||||
make_key(code=59, names=('F2',))
|
make_key(code=59, names=('F2',))
|
||||||
@ -477,8 +467,6 @@ make_key(code=113, names=('F22',))
|
|||||||
make_key(code=114, names=('F23',))
|
make_key(code=114, names=('F23',))
|
||||||
make_key(code=115, names=('F24',))
|
make_key(code=115, names=('F24',))
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
# Lock Keys, Navigation, etc.
|
# Lock Keys, Navigation, etc.
|
||||||
make_key(code=57, names=('CAPS_LOCK', 'CAPSLOCK', 'CLCK', 'CAPS'))
|
make_key(code=57, names=('CAPS_LOCK', 'CAPSLOCK', 'CLCK', 'CAPS'))
|
||||||
# FIXME: Investigate whether this key actually works, and
|
# FIXME: Investigate whether this key actually works, and
|
||||||
@ -501,8 +489,6 @@ make_key(code=80, names=('LEFT',))
|
|||||||
make_key(code=81, names=('DOWN',))
|
make_key(code=81, names=('DOWN',))
|
||||||
make_key(code=82, names=('UP',))
|
make_key(code=82, names=('UP',))
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
# Numpad
|
# Numpad
|
||||||
make_key(code=83, names=('NUM_LOCK', 'NUMLOCK', 'NLCK'))
|
make_key(code=83, names=('NUM_LOCK', 'NUMLOCK', 'NLCK'))
|
||||||
# FIXME: Investigate whether this key actually works, and
|
# FIXME: Investigate whether this key actually works, and
|
||||||
@ -528,8 +514,6 @@ make_key(code=103, names=('KP_EQUAL', 'PEQL', 'NUMPAD_EQUAL'))
|
|||||||
make_key(code=133, names=('KP_COMMA', 'PCMM', 'NUMPAD_COMMA'))
|
make_key(code=133, names=('KP_COMMA', 'PCMM', 'NUMPAD_COMMA'))
|
||||||
make_key(code=134, names=('KP_EQUAL_AS400', 'NUMPAD_EQUAL_AS400'))
|
make_key(code=134, names=('KP_EQUAL_AS400', 'NUMPAD_EQUAL_AS400'))
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
# Making life better for folks on tiny keyboards especially: exposes
|
# Making life better for folks on tiny keyboards especially: exposes
|
||||||
# the "shifted" keys as raw keys. Under the hood we're still
|
# the "shifted" keys as raw keys. Under the hood we're still
|
||||||
# sending Shift+(whatever key is normally pressed) to get these, so
|
# sending Shift+(whatever key is normally pressed) to get these, so
|
||||||
@ -556,8 +540,6 @@ make_shifted_key('COMMA', names=('LEFT_ANGLE_BRACKET', 'LABK', '<'))
|
|||||||
make_shifted_key('DOT', names=('RIGHT_ANGLE_BRACKET', 'RABK', '>'))
|
make_shifted_key('DOT', names=('RIGHT_ANGLE_BRACKET', 'RABK', '>'))
|
||||||
make_shifted_key('SLSH', names=('QUESTION', 'QUES', '?'))
|
make_shifted_key('SLSH', names=('QUESTION', 'QUES', '?'))
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
# International
|
# International
|
||||||
make_key(code=50, names=('NONUS_HASH', 'NUHS'))
|
make_key(code=50, names=('NONUS_HASH', 'NUHS'))
|
||||||
make_key(code=100, names=('NONUS_BSLASH', 'NUBS'))
|
make_key(code=100, names=('NONUS_BSLASH', 'NUBS'))
|
||||||
@ -582,8 +564,6 @@ make_key(code=150, names=('LANG7',))
|
|||||||
make_key(code=151, names=('LANG8',))
|
make_key(code=151, names=('LANG8',))
|
||||||
make_key(code=152, names=('LANG9',))
|
make_key(code=152, names=('LANG9',))
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
# Consumer ("media") keys. Most known keys aren't supported here. A much
|
# 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
|
# 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
|
# incorrect, conflicting with each other, or otherwise "weird". We'll add them
|
||||||
@ -605,8 +585,6 @@ 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=179, names=('MEDIA_FAST_FORWARD', 'MFFD')) # 0xB3
|
||||||
make_consumer_key(code=180, names=('MEDIA_REWIND', 'MRWD')) # 0xB4
|
make_consumer_key(code=180, names=('MEDIA_REWIND', 'MRWD')) # 0xB4
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
# Internal, diagnostic, or auxiliary/enhanced keys
|
# Internal, diagnostic, or auxiliary/enhanced keys
|
||||||
|
|
||||||
# NO and TRNS are functionally identical in how they (don't) mutate
|
# NO and TRNS are functionally identical in how they (don't) mutate
|
||||||
@ -631,18 +609,6 @@ make_key(
|
|||||||
on_release=handlers.passthrough,
|
on_release=handlers.passthrough,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def layer_key_validator(layer, kc=None):
|
|
||||||
'''
|
|
||||||
Validates the syntax (but not semantics) of a layer key call. We won't
|
|
||||||
have access to the keymap here, so we can't verify much of anything useful
|
|
||||||
here (like whether the target layer actually exists). The spirit of this
|
|
||||||
existing is mostly that Python will catch extraneous args/kwargs and error
|
|
||||||
out.
|
|
||||||
'''
|
|
||||||
return LayerKeyMeta(layer=layer, kc=kc)
|
|
||||||
|
|
||||||
|
|
||||||
# Layers
|
# Layers
|
||||||
make_argumented_key(
|
make_argumented_key(
|
||||||
validator=layer_key_validator,
|
validator=layer_key_validator,
|
||||||
@ -684,15 +650,6 @@ make_argumented_key(
|
|||||||
on_release=layers.tt_released,
|
on_release=layers.tt_released,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def mod_tap_validator(kc, mods=None):
|
|
||||||
'''
|
|
||||||
Validates that mod tap keys are correctly used
|
|
||||||
'''
|
|
||||||
return ModTapKeyMeta(kc=kc, mods=mods)
|
|
||||||
|
|
||||||
|
|
||||||
# ModTap
|
|
||||||
make_argumented_key(
|
make_argumented_key(
|
||||||
validator=mod_tap_validator,
|
validator=mod_tap_validator,
|
||||||
names=('MT',),
|
names=('MT',),
|
||||||
@ -700,14 +657,6 @@ make_argumented_key(
|
|||||||
on_release=modtap.mt_released,
|
on_release=modtap.mt_released,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
|
|
||||||
def key_seq_sleep_validator(ms):
|
|
||||||
return KeySeqSleepMeta(ms)
|
|
||||||
|
|
||||||
|
|
||||||
# A dummy key to trigger a sleep_ms call in a sequence of other keys in a
|
# A dummy key to trigger a sleep_ms call in a sequence of other keys in a
|
||||||
# simple sequence macro.
|
# simple sequence macro.
|
||||||
make_argumented_key(
|
make_argumented_key(
|
||||||
@ -716,8 +665,6 @@ make_argumented_key(
|
|||||||
on_press=handlers.sleep_pressed,
|
on_press=handlers.sleep_pressed,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Switch unicode modes at runtime
|
|
||||||
make_key(
|
make_key(
|
||||||
names=('UC_MODE_NOOP', 'UC_DISABLE'),
|
names=('UC_MODE_NOOP', 'UC_DISABLE'),
|
||||||
meta=UnicodeModeKeyMeta(UnicodeMode.NOOP),
|
meta=UnicodeModeKeyMeta(UnicodeMode.NOOP),
|
||||||
@ -738,22 +685,14 @@ make_key(
|
|||||||
meta=UnicodeModeKeyMeta(UnicodeMode.WINC),
|
meta=UnicodeModeKeyMeta(UnicodeMode.WINC),
|
||||||
on_press=handlers.uc_mode_pressed,
|
on_press=handlers.uc_mode_pressed,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def unicode_mode_key_validator(mode):
|
|
||||||
return UnicodeModeKeyMeta(mode)
|
|
||||||
|
|
||||||
|
|
||||||
make_argumented_key(
|
make_argumented_key(
|
||||||
validator=unicode_mode_key_validator,
|
validator=unicode_mode_key_validator,
|
||||||
names=('UC_MODE',),
|
names=('UC_MODE',),
|
||||||
on_press=handlers.uc_mode_pressed,
|
on_press=handlers.uc_mode_pressed,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Tap Dance
|
|
||||||
make_argumented_key(
|
make_argumented_key(
|
||||||
validator=lambda *codes: TapDanceKeyMeta(codes),
|
validator=tap_dance_key_validator,
|
||||||
names=('TAP_DANCE', 'TD'),
|
names=('TAP_DANCE', 'TD'),
|
||||||
on_press=handlers.td_pressed,
|
on_press=handlers.td_pressed,
|
||||||
on_release=handlers.td_released,
|
on_release=handlers.td_released,
|
||||||
|
@ -6,7 +6,7 @@ from kmk.keys import KC
|
|||||||
|
|
||||||
keyboard = Firmware()
|
keyboard = Firmware()
|
||||||
|
|
||||||
keyboard.debug_enabled = True
|
keyboard.debug_enabled = False
|
||||||
keyboard.unicode_mode = UnicodeMode.LINUX
|
keyboard.unicode_mode = UnicodeMode.LINUX
|
||||||
keyboard.tap_time = 750
|
keyboard.tap_time = 750
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user