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
|
||||
# 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 gc # isort:skip
|
||||
import supervisor # isort:skip
|
||||
|
||||
# Now "light" KMK stuff with few/no external deps
|
||||
import kmk.consts # isort:skip
|
||||
import kmk.kmktime # isort:skip
|
||||
import kmk.types # 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.hid import USB_HID # 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
|
||||
|
||||
from kmk.kmktime import sleep_ms
|
||||
from kmk.util import intify_coordinate as ic
|
||||
|
||||
|
||||
@ -100,6 +103,76 @@ class Firmware:
|
||||
|
||||
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):
|
||||
self._hid_helper_inst.create_report(self._state.keys_pressed).send()
|
||||
self._state.resolve_hid()
|
||||
@ -155,21 +228,8 @@ class Firmware:
|
||||
self.uart.write('DEB')
|
||||
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):
|
||||
if self._master_half():
|
||||
if self.is_master:
|
||||
return busio.UART(tx=None, rx=pin, timeout=timeout)
|
||||
else:
|
||||
return busio.UART(tx=pin, rx=None, timeout=timeout)
|
||||
@ -183,13 +243,27 @@ class Firmware:
|
||||
self._hid_helper_inst = self.hid_helper()
|
||||
|
||||
# Split keyboard Init
|
||||
if self.split_flip and not self._master_half():
|
||||
self.col_pins = list(reversed(self.col_pins))
|
||||
if self.split_type is not None:
|
||||
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":
|
||||
self.split_master_left = self._master_half()
|
||||
elif self.split_side == "Right":
|
||||
self.split_master_left = not self._master_half()
|
||||
# Sleep 2s so master portion doesn't "appear" to boot quicker than
|
||||
# dependent portions (which will take ~2s to time out on the HID send)
|
||||
sleep_ms(2000)
|
||||
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:
|
||||
self.uart = self.init_uart(self.uart_pin)
|
||||
@ -211,13 +285,13 @@ class Firmware:
|
||||
if not isinstance(k, tuple):
|
||||
del self.leader_dictionary[k]
|
||||
|
||||
if self.debug_enabled:
|
||||
print("Firin' lazers. Keyboard is booted.")
|
||||
gc.collect()
|
||||
self._print_debug_cycle(init=True)
|
||||
|
||||
while True:
|
||||
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()
|
||||
if update is not None:
|
||||
self._handle_matrix_report(update)
|
||||
@ -226,7 +300,7 @@ class Firmware:
|
||||
update = self.matrix.scan_for_changes()
|
||||
|
||||
if update is not None:
|
||||
if self._master_half():
|
||||
if self.is_master:
|
||||
self._handle_matrix_report(update)
|
||||
state_changed = True
|
||||
else:
|
||||
@ -246,5 +320,5 @@ class Firmware:
|
||||
if self._state.hid_pending:
|
||||
self._send_hid()
|
||||
|
||||
if self.debug_enabled and state_changed:
|
||||
print('New State: {}'.format(self._state._to_dict()))
|
||||
if state_changed:
|
||||
self._print_debug_cycle()
|
||||
|
@ -3,24 +3,31 @@ from kmk.kmktime import ticks_diff, ticks_ms
|
||||
|
||||
def df_pressed(key, state, *args, **kwargs):
|
||||
"""Switches the default layer"""
|
||||
state.active_layers[0] = key.meta.layer
|
||||
state.reversed_active_layers = list(reversed(state.active_layers))
|
||||
state.active_layers[-1] = key.meta.layer
|
||||
return state
|
||||
|
||||
|
||||
def mo_pressed(key, state, *args, **kwargs):
|
||||
"""Momentarily activates layer, switches off when you let go"""
|
||||
state.active_layers.append(key.meta.layer)
|
||||
state.reversed_active_layers = list(reversed(state.active_layers))
|
||||
state.active_layers.insert(0, key.meta.layer)
|
||||
return state
|
||||
|
||||
|
||||
def mo_released(key, state, KC, *args, **kwargs):
|
||||
state.active_layers = [
|
||||
layer for layer in state.active_layers
|
||||
if layer != key.meta.layer
|
||||
]
|
||||
state.reversed_active_layers = list(reversed(state.active_layers))
|
||||
# remove the first instance of the target layer
|
||||
# from the active list
|
||||
# under almost all normal use cases, this will
|
||||
# disable the layer (but preserve it if it was triggered
|
||||
# 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
|
||||
|
||||
|
||||
@ -62,23 +69,21 @@ def lt_released(key, state, *args, **kwargs):
|
||||
|
||||
def tg_pressed(key, state, *args, **kwargs):
|
||||
"""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
|
||||
|
||||
|
||||
def to_pressed(key, state, *args, **kwargs):
|
||||
"""Activates layer and deactivates all other layers"""
|
||||
state.active_layers = [key.meta.layer]
|
||||
state.reversed_active_layers = list(reversed(state.active_layers))
|
||||
state.active_layers.clear()
|
||||
state.active_layers.insert(0, key.meta.layer)
|
||||
|
||||
return state
|
||||
|
||||
|
@ -38,9 +38,9 @@ def bootloader(*args, **kwargs):
|
||||
|
||||
def debug_pressed(key, state, KC, *args, **kwargs):
|
||||
if state.config.debug_enabled:
|
||||
print('Disabling debug mode, bye!')
|
||||
print('DebugDisable()')
|
||||
else:
|
||||
print('Enabling debug mode. Welcome to the jungle.')
|
||||
print('DebugEnable()')
|
||||
|
||||
state.config.debug_enabled = not state.config.debug_enabled
|
||||
|
||||
|
@ -21,6 +21,12 @@ class USB_HID:
|
||||
|
||||
self.post_init()
|
||||
|
||||
def __repr__(self):
|
||||
return '{}(REPORT_BYTES={})'.format(
|
||||
self.__class__.__name__,
|
||||
self.REPORT_BYTES,
|
||||
)
|
||||
|
||||
def post_init(self):
|
||||
pass
|
||||
|
||||
|
@ -12,8 +12,12 @@ class InternalState:
|
||||
leader_last_len = 0
|
||||
hid_pending = False
|
||||
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]
|
||||
reversed_active_layers = list(reversed(active_layers))
|
||||
|
||||
start_time = {
|
||||
'lt': None,
|
||||
'tg': None,
|
||||
@ -30,21 +34,35 @@ class InternalState:
|
||||
self.config = config
|
||||
|
||||
def __repr__(self):
|
||||
return 'InternalState({})'.format(self._to_dict())
|
||||
|
||||
def _to_dict(self):
|
||||
ret = {
|
||||
'keys_pressed': self.keys_pressed,
|
||||
'active_layers': self.active_layers,
|
||||
'leader_mode_history': self.leader_mode_history,
|
||||
'leader_mode': self.config.leader_mode,
|
||||
'start_time': self.start_time,
|
||||
'tapping': self.tapping,
|
||||
'tap_dance_counts': self.tap_dance_counts,
|
||||
'timeouts': self.timeouts,
|
||||
}
|
||||
|
||||
return ret
|
||||
return (
|
||||
'InternalState('
|
||||
'keys_pressed={} '
|
||||
'coord_keys_pressed={} '
|
||||
'leader_pending={} '
|
||||
'leader_last_len={} '
|
||||
'hid_pending={} '
|
||||
'leader_mode_history={} '
|
||||
'active_layers={} '
|
||||
'start_time={} '
|
||||
'timeouts={} '
|
||||
'tapping={} '
|
||||
'tap_dance_counts={} '
|
||||
'tap_side_effects={}'
|
||||
')'
|
||||
).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):
|
||||
ic = intify_coordinate(row, col)
|
||||
@ -54,7 +72,7 @@ class InternalState:
|
||||
except ValueError:
|
||||
if self.config.debug_enabled:
|
||||
print(
|
||||
'No coord_mapping index for value {}, row={} col={}'.format(
|
||||
'CoordMappingNotFound(ic={}, row={}, col={})'.format(
|
||||
ic,
|
||||
row,
|
||||
col,
|
||||
@ -63,16 +81,14 @@ class InternalState:
|
||||
|
||||
return None
|
||||
|
||||
# Later-added layers have priority. Sift through the layers
|
||||
# in reverse order until we find a valid keycode object
|
||||
for layer in self.reversed_active_layers:
|
||||
for layer in self.active_layers:
|
||||
layer_key = self.config.keymap[layer][idx]
|
||||
|
||||
if not layer_key or layer_key == KC.TRNS:
|
||||
continue
|
||||
|
||||
if self.config.debug_enabled:
|
||||
print('Resolved key: {}'.format(layer_key))
|
||||
print('KeyResolution(key={})'.format(layer_key))
|
||||
|
||||
return layer_key
|
||||
|
||||
@ -112,15 +128,17 @@ class InternalState:
|
||||
|
||||
def matrix_changed(self, row, col, is_pressed):
|
||||
if self.config.debug_enabled:
|
||||
print('Matrix changed (col, row, pressed?): {}, {}, {}'.format(
|
||||
col, row, is_pressed,
|
||||
print('MatrixChange(col={} row={} pressed={})'.format(
|
||||
col,
|
||||
row,
|
||||
is_pressed,
|
||||
))
|
||||
|
||||
int_coord = intify_coordinate(row, col)
|
||||
kc_changed = self._find_key_in_map(row, col)
|
||||
|
||||
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.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.modtap as modtap
|
||||
import kmk.handlers.stock as handlers
|
||||
from kmk.consts import UnicodeMode
|
||||
from kmk.types import (AttrDict, KeySeqSleepMeta, LayerKeyMeta, ModTapKeyMeta,
|
||||
TapDanceKeyMeta, UnicodeModeKeyMeta)
|
||||
from kmk.key_validators import (key_seq_sleep_validator, layer_key_validator,
|
||||
mod_tap_validator, tap_dance_key_validator,
|
||||
unicode_mode_key_validator)
|
||||
from kmk.types import AttrDict, UnicodeModeKeyMeta
|
||||
|
||||
FIRST_KMK_INTERNAL_KEY = 1000
|
||||
NEXT_AVAILABLE_KEY = 1000
|
||||
@ -367,8 +367,6 @@ def make_argumented_key(
|
||||
return _argumented_key
|
||||
|
||||
|
||||
gc.collect()
|
||||
|
||||
# Modifiers
|
||||
make_mod_key(code=0x01, names=('LEFT_CONTROL', 'LCTRL', 'LCTL'))
|
||||
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
|
||||
make_mod_key(code=0x0F, names=('HYPER', 'HYPR'))
|
||||
|
||||
gc.collect()
|
||||
|
||||
# Basic ASCII letters
|
||||
make_key(code=4, names=('A',))
|
||||
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=29, names=('Z',))
|
||||
|
||||
gc.collect()
|
||||
|
||||
# Numbers
|
||||
# Aliases to play nicely with AttrDict, since KC.1 isn't a valid
|
||||
# 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=39, names=('0', 'N0'))
|
||||
|
||||
gc.collect()
|
||||
|
||||
# More ASCII standard keys
|
||||
make_key(code=40, names=('ENTER', 'ENT', "\n"))
|
||||
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=56, names=('SLASH', 'SLSH'))
|
||||
|
||||
gc.collect()
|
||||
|
||||
# Function Keys
|
||||
make_key(code=58, names=('F1',))
|
||||
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=115, names=('F24',))
|
||||
|
||||
gc.collect()
|
||||
|
||||
# Lock Keys, Navigation, etc.
|
||||
make_key(code=57, names=('CAPS_LOCK', 'CAPSLOCK', 'CLCK', 'CAPS'))
|
||||
# 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=82, names=('UP',))
|
||||
|
||||
gc.collect()
|
||||
|
||||
# Numpad
|
||||
make_key(code=83, names=('NUM_LOCK', 'NUMLOCK', 'NLCK'))
|
||||
# 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=134, names=('KP_EQUAL_AS400', 'NUMPAD_EQUAL_AS400'))
|
||||
|
||||
gc.collect()
|
||||
|
||||
# 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
|
||||
@ -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('SLSH', names=('QUESTION', 'QUES', '?'))
|
||||
|
||||
gc.collect()
|
||||
|
||||
# International
|
||||
make_key(code=50, names=('NONUS_HASH', 'NUHS'))
|
||||
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=152, names=('LANG9',))
|
||||
|
||||
gc.collect()
|
||||
|
||||
# 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
|
||||
@ -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=180, names=('MEDIA_REWIND', 'MRWD')) # 0xB4
|
||||
|
||||
gc.collect()
|
||||
|
||||
# Internal, diagnostic, or auxiliary/enhanced keys
|
||||
|
||||
# NO and TRNS are functionally identical in how they (don't) mutate
|
||||
@ -631,18 +609,6 @@ make_key(
|
||||
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
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
@ -684,15 +650,6 @@ make_argumented_key(
|
||||
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(
|
||||
validator=mod_tap_validator,
|
||||
names=('MT',),
|
||||
@ -700,14 +657,6 @@ make_argumented_key(
|
||||
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
|
||||
# simple sequence macro.
|
||||
make_argumented_key(
|
||||
@ -716,8 +665,6 @@ make_argumented_key(
|
||||
on_press=handlers.sleep_pressed,
|
||||
)
|
||||
|
||||
|
||||
# Switch unicode modes at runtime
|
||||
make_key(
|
||||
names=('UC_MODE_NOOP', 'UC_DISABLE'),
|
||||
meta=UnicodeModeKeyMeta(UnicodeMode.NOOP),
|
||||
@ -738,22 +685,14 @@ make_key(
|
||||
meta=UnicodeModeKeyMeta(UnicodeMode.WINC),
|
||||
on_press=handlers.uc_mode_pressed,
|
||||
)
|
||||
|
||||
|
||||
def unicode_mode_key_validator(mode):
|
||||
return UnicodeModeKeyMeta(mode)
|
||||
|
||||
|
||||
make_argumented_key(
|
||||
validator=unicode_mode_key_validator,
|
||||
names=('UC_MODE',),
|
||||
on_press=handlers.uc_mode_pressed,
|
||||
)
|
||||
|
||||
|
||||
# Tap Dance
|
||||
make_argumented_key(
|
||||
validator=lambda *codes: TapDanceKeyMeta(codes),
|
||||
validator=tap_dance_key_validator,
|
||||
names=('TAP_DANCE', 'TD'),
|
||||
on_press=handlers.td_pressed,
|
||||
on_release=handlers.td_released,
|
||||
|
@ -6,7 +6,7 @@ from kmk.keys import KC
|
||||
|
||||
keyboard = Firmware()
|
||||
|
||||
keyboard.debug_enabled = True
|
||||
keyboard.debug_enabled = False
|
||||
keyboard.unicode_mode = UnicodeMode.LINUX
|
||||
keyboard.tap_time = 750
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user