massive cleanup
This commit is contained in:
@@ -18,28 +18,28 @@ class Extension:
|
||||
# The below methods should be implemented by subclasses
|
||||
|
||||
def on_runtime_enable(self, keyboard):
|
||||
pass
|
||||
raise NotImplementedError
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
pass
|
||||
raise NotImplementedError
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
pass
|
||||
raise NotImplementedError
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
'''
|
||||
Return value will be injected as an extra matrix update
|
||||
'''
|
||||
pass
|
||||
raise NotImplementedError
|
||||
|
||||
def after_matrix_scan(self, keyboard, matrix_update):
|
||||
'''
|
||||
Return value will be replace matrix update if supplied
|
||||
'''
|
||||
pass
|
||||
raise NotImplementedError
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
pass
|
||||
raise NotImplementedError
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
pass
|
||||
raise NotImplementedError
|
||||
|
@@ -1,8 +1,11 @@
|
||||
'''Adds international keys'''
|
||||
from kmk.extensions import Extension
|
||||
from kmk.keys import make_key
|
||||
|
||||
|
||||
class International(Extension):
|
||||
'''Adds international keys'''
|
||||
|
||||
def __init__(self):
|
||||
# International
|
||||
make_key(code=50, names=('NONUS_HASH', 'NUHS'))
|
||||
@@ -27,3 +30,24 @@ class International(Extension):
|
||||
make_key(code=150, names=('LANG7',))
|
||||
make_key(code=151, names=('LANG8',))
|
||||
make_key(code=152, names=('LANG9',))
|
||||
|
||||
def on_runtime_enable(self, keyboard):
|
||||
return
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
return
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
return
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard, matrix_update):
|
||||
return
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
return
|
||||
|
@@ -1,14 +1,15 @@
|
||||
'''One layer isn't enough. Adds keys to get to more of them'''
|
||||
from micropython import const
|
||||
|
||||
import kmk.handlers.modtap as modtap
|
||||
from kmk.extensions import Extension
|
||||
from kmk.key_validators import layer_key_validator, mod_tap_validator
|
||||
from kmk.key_validators import layer_key_validator
|
||||
from kmk.keys import make_argumented_key
|
||||
from kmk.kmktime import accurate_ticks, accurate_ticks_diff
|
||||
|
||||
|
||||
class LayerType:
|
||||
# These number must be reserved for layer timers.
|
||||
'''Defines layer type values for readability'''
|
||||
|
||||
MO = const(0)
|
||||
DF = const(1)
|
||||
LM = const(2)
|
||||
@@ -18,47 +19,42 @@ class LayerType:
|
||||
|
||||
|
||||
class Layers(Extension):
|
||||
'''Gives access to the keys used to enable the layer system'''
|
||||
|
||||
def __init__(self):
|
||||
# Layers
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
names=('MO',),
|
||||
on_press=self.mo_pressed,
|
||||
on_release=self.mo_released,
|
||||
on_press=self._mo_pressed,
|
||||
on_release=self._mo_released,
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator, names=('DF',), on_press=self.df_pressed
|
||||
validator=layer_key_validator, names=('DF',), on_press=self._df_pressed
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
names=('LM',),
|
||||
on_press=self.lm_pressed,
|
||||
on_release=self.lm_released,
|
||||
on_press=self._lm_pressed,
|
||||
on_release=self._lm_released,
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
names=('LT',),
|
||||
on_press=self.lt_pressed,
|
||||
on_release=self.lt_released,
|
||||
on_press=self._lt_pressed,
|
||||
on_release=self._lt_released,
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator, names=('TG',), on_press=self.tg_pressed
|
||||
validator=layer_key_validator, names=('TG',), on_press=self._tg_pressed
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator, names=('TO',), on_press=self.to_pressed
|
||||
validator=layer_key_validator, names=('TO',), on_press=self._to_pressed
|
||||
)
|
||||
make_argumented_key(
|
||||
validator=layer_key_validator,
|
||||
names=('TT',),
|
||||
on_press=self.tt_pressed,
|
||||
on_release=self.tt_released,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
validator=mod_tap_validator,
|
||||
names=('MT',),
|
||||
on_press=modtap.mt_pressed,
|
||||
on_release=modtap.mt_released,
|
||||
on_press=self._tt_pressed,
|
||||
on_release=self._tt_released,
|
||||
)
|
||||
|
||||
start_time = {
|
||||
@@ -68,21 +64,45 @@ class Layers(Extension):
|
||||
LayerType.LM: None,
|
||||
}
|
||||
|
||||
def df_pressed(self, key, state, *args, **kwargs):
|
||||
def on_runtime_enable(self, keyboard):
|
||||
return
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
return
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
return
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard, matrix_update):
|
||||
return
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def _after_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
@staticmethod
|
||||
def _df_pressed(key, state, *args, **kwargs):
|
||||
'''
|
||||
Switches the default layer
|
||||
'''
|
||||
state._active_layers[-1] = key.meta.layer
|
||||
state.active_layers[-1] = key.meta.layer
|
||||
return state
|
||||
|
||||
def mo_pressed(self, key, state, *args, **kwargs):
|
||||
@staticmethod
|
||||
def _mo_pressed(key, state, *args, **kwargs):
|
||||
'''
|
||||
Momentarily activates layer, switches off when you let go
|
||||
'''
|
||||
state._active_layers.insert(0, key.meta.layer)
|
||||
state.active_layers.insert(0, key.meta.layer)
|
||||
return state
|
||||
|
||||
def mo_released(self, key, state, KC, *args, **kwargs):
|
||||
@staticmethod
|
||||
def _mo_released(key, state, KC, *args, **kwargs):
|
||||
# remove the first instance of the target layer
|
||||
# from the active list
|
||||
# under almost all normal use cases, this will
|
||||
@@ -92,93 +112,95 @@ class Layers(Extension):
|
||||
# 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]
|
||||
del_idx = state.active_layers.index(key.meta.layer)
|
||||
del state.active_layers[del_idx]
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return state
|
||||
|
||||
def lm_pressed(self, key, state, *args, **kwargs):
|
||||
def _lm_pressed(self, key, state, *args, **kwargs):
|
||||
'''
|
||||
As MO(layer) but with mod active
|
||||
'''
|
||||
state._hid_pending = True
|
||||
state.hid_pending = True
|
||||
# Sets the timer start and acts like MO otherwise
|
||||
state._keys_pressed.add(key.meta.kc)
|
||||
return self.mo_pressed(key, state, *args, **kwargs)
|
||||
state.keys_pressed.add(key.meta.kc)
|
||||
return self._mo_pressed(key, state, *args, **kwargs)
|
||||
|
||||
def lm_released(self, key, state, *args, **kwargs):
|
||||
def _lm_released(self, key, state, *args, **kwargs):
|
||||
'''
|
||||
As MO(layer) but with mod active
|
||||
'''
|
||||
state._hid_pending = True
|
||||
state._keys_pressed.discard(key.meta.kc)
|
||||
return self.mo_released(key, state, *args, **kwargs)
|
||||
state.hid_pending = True
|
||||
state.keys_pressed.discard(key.meta.kc)
|
||||
return self._mo_released(key, state, *args, **kwargs)
|
||||
|
||||
def lt_pressed(self, key, state, *args, **kwargs):
|
||||
def _lt_pressed(self, key, state, *args, **kwargs):
|
||||
# Sets the timer start and acts like MO otherwise
|
||||
self.start_time[LayerType.LT] = accurate_ticks()
|
||||
return self.mo_pressed(key, state, *args, **kwargs)
|
||||
return self._mo_pressed(key, state, *args, **kwargs)
|
||||
|
||||
def lt_released(self, key, state, *args, **kwargs):
|
||||
def _lt_released(self, key, state, *args, **kwargs):
|
||||
# On keyup, check timer, and press key if needed.
|
||||
if self.start_time[LayerType.LT] and (
|
||||
accurate_ticks_diff(
|
||||
accurate_ticks(), self.start_time[LayerType.LT], state.tap_time
|
||||
)
|
||||
):
|
||||
state._hid_pending = True
|
||||
state._tap_key(key.meta.kc)
|
||||
state.hid_pending = True
|
||||
state.tap_key(key.meta.kc)
|
||||
|
||||
self.mo_released(key, state, *args, **kwargs)
|
||||
self._mo_released(key, state, *args, **kwargs)
|
||||
self.start_time[LayerType.LT] = None
|
||||
return state
|
||||
|
||||
def tg_pressed(self, key, state, *args, **kwargs):
|
||||
@staticmethod
|
||||
def _tg_pressed(key, state, *args, **kwargs):
|
||||
'''
|
||||
Toggles the layer (enables it if not active, and vise versa)
|
||||
'''
|
||||
# See mo_released for implementation details around this
|
||||
try:
|
||||
del_idx = state._active_layers.index(key.meta.layer)
|
||||
del state._active_layers[del_idx]
|
||||
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)
|
||||
state.active_layers.insert(0, key.meta.layer)
|
||||
|
||||
return state
|
||||
|
||||
def to_pressed(self, key, state, *args, **kwargs):
|
||||
@staticmethod
|
||||
def _to_pressed(key, state, *args, **kwargs):
|
||||
'''
|
||||
Activates layer and deactivates all other layers
|
||||
'''
|
||||
state._active_layers.clear()
|
||||
state._active_layers.insert(0, key.meta.layer)
|
||||
state.active_layers.clear()
|
||||
state.active_layers.insert(0, key.meta.layer)
|
||||
|
||||
return state
|
||||
|
||||
def tt_pressed(self, key, state, *args, **kwargs):
|
||||
def _tt_pressed(self, key, state, *args, **kwargs):
|
||||
'''
|
||||
Momentarily activates layer if held, toggles it if tapped repeatedly
|
||||
'''
|
||||
# TODO Make this work with tap dance to function more correctly, but technically works.
|
||||
if self.start_time[LayerType.TT] is None:
|
||||
# Sets the timer start and acts like MO otherwise
|
||||
self.start_time[LayerType.TT] = accurate_ticks()
|
||||
return self.mo_pressed(key, state, *args, **kwargs)
|
||||
return self._mo_pressed(key, state, *args, **kwargs)
|
||||
elif accurate_ticks_diff(
|
||||
accurate_ticks(), self.start_time[LayerType.TT], state.tap_time
|
||||
):
|
||||
self.start_time[LayerType.TT] = None
|
||||
return self.tg_pressed(key, state, *args, **kwargs)
|
||||
return self._tg_pressed(key, state, *args, **kwargs)
|
||||
return None
|
||||
|
||||
def tt_released(self, key, state, *args, **kwargs):
|
||||
def _tt_released(self, key, state, *args, **kwargs):
|
||||
if self.start_time[LayerType.TT] is None or not accurate_ticks_diff(
|
||||
accurate_ticks(), self.start_time[LayerType.TT], state.tap_time
|
||||
):
|
||||
# On first press, works like MO. On second press, does nothing unless let up within
|
||||
# time window, then acts like TG.
|
||||
self.start_time[LayerType.TT] = None
|
||||
return self.mo_released(key, state, *args, **kwargs)
|
||||
return self._mo_released(key, state, *args, **kwargs)
|
||||
|
||||
return state
|
||||
|
@@ -31,24 +31,35 @@ class Leader(Extension):
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
|
||||
def after_matrix_scan(self, keyboard_state, *args):
|
||||
def on_runtime_enable(self, keyboard):
|
||||
return
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
return
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
return
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard, matrix_update):
|
||||
if self._mode % 2 == 1:
|
||||
keys_pressed = keyboard_state._keys_pressed
|
||||
keys_pressed = keyboard.keys_pressed
|
||||
|
||||
if self._assembly_last_len and self._sequence_assembly:
|
||||
history_set = set(self._sequence_assembly)
|
||||
|
||||
keys_pressed = keys_pressed - history_set
|
||||
|
||||
self._assembly_last_len = len(keyboard_state._keys_pressed)
|
||||
self._assembly_last_len = len(keyboard.keys_pressed)
|
||||
|
||||
for key in keys_pressed:
|
||||
if self._mode == LeaderMode.ENTER_ACTIVE and key == KC.ENT:
|
||||
self._handle_leader_sequence(keyboard_state)
|
||||
break
|
||||
elif key == KC.ESC or key == KC.GESC:
|
||||
self._handle_leader_sequence(keyboard)
|
||||
elif key in (KC.ESC, KC.GESC):
|
||||
# Clean self and turn leader mode off.
|
||||
self._exit_leader_mode(keyboard_state)
|
||||
self._exit_leader_mode(keyboard)
|
||||
break
|
||||
elif key == KC.LEAD:
|
||||
break
|
||||
@@ -57,9 +68,16 @@ class Leader(Extension):
|
||||
# This needs replaced later with a proper debounce
|
||||
self._sequence_assembly.append(key)
|
||||
|
||||
keyboard_state._hid_pending = False
|
||||
keyboard.hid_pending = False
|
||||
|
||||
def _compile_sequences(self, sequences):
|
||||
def before_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
@staticmethod
|
||||
def _compile_sequences(sequences):
|
||||
|
||||
for k, v in sequences.items():
|
||||
if not isinstance(k, tuple):
|
||||
@@ -72,33 +90,33 @@ class Leader(Extension):
|
||||
|
||||
return sequences
|
||||
|
||||
def _handle_leader_sequence(self, keyboard_state):
|
||||
def _handle_leader_sequence(self, keyboard):
|
||||
lmh = tuple(self._sequence_assembly)
|
||||
# Will get caught in infinite processing loops if we don't
|
||||
# exit leader mode before processing the target key
|
||||
self._exit_leader_mode(keyboard_state)
|
||||
self._exit_leader_mode(keyboard)
|
||||
|
||||
if lmh in self._sequences:
|
||||
# Stack depth exceeded if try to use add_key here with a unicode sequence
|
||||
keyboard_state._process_key(self._sequences[lmh], True)
|
||||
keyboard.process_key(self._sequences[lmh], True)
|
||||
|
||||
keyboard_state._set_timeout(
|
||||
False, lambda: keyboard_state._remove_key(self._sequences[lmh])
|
||||
keyboard.set_timeout(
|
||||
False, lambda: keyboard.remove_key(self._sequences[lmh])
|
||||
)
|
||||
|
||||
def _exit_leader_mode(self, keyboard_state):
|
||||
def _exit_leader_mode(self, keyboard):
|
||||
self._sequence_assembly.clear()
|
||||
self._mode -= 1
|
||||
self._assembly_last_len = 0
|
||||
keyboard_state._keys_pressed.clear()
|
||||
keyboard.keys_pressed.clear()
|
||||
|
||||
def _key_leader_pressed(self, key, keyboard_state, *args, **kwargs):
|
||||
def _key_leader_pressed(self, key, keyboard):
|
||||
if self._mode % 2 == 0:
|
||||
keyboard_state._keys_pressed.discard(key)
|
||||
keyboard.keys_pressed.discard(key)
|
||||
# All leader modes are one number higher when activating
|
||||
self._mode += 1
|
||||
|
||||
if self._mode == LeaderMode.TIMEOUT_ACTIVE:
|
||||
keyboard_state._set_timeout(
|
||||
self._timeout, lambda: self._handle_leader_sequence(keyboard_state)
|
||||
keyboard.set_timeout(
|
||||
self._timeout, lambda: self._handle_leader_sequence(keyboard)
|
||||
)
|
||||
|
@@ -66,10 +66,23 @@ class LED(Extension):
|
||||
def _to_dict(self):
|
||||
return f'LED(_brightness={self._brightness} _pos={self._pos} brightness_step={self.brightness_step} brightness_limit={self.brightness_limit} animation_mode={self.animation_mode} animation_speed={self.animation_speed} breathe_center={self.breathe_center} val={self.val} )'
|
||||
|
||||
def _init_effect(self):
|
||||
self._pos = 0
|
||||
self._effect_init = False
|
||||
return self
|
||||
def on_runtime_enable(self, keyboard):
|
||||
return
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
return
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
return
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard, matrix_update):
|
||||
return
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
if self._enabled and self.animation_mode:
|
||||
@@ -77,6 +90,11 @@ class LED(Extension):
|
||||
|
||||
return keyboard
|
||||
|
||||
def _init_effect(self):
|
||||
self._pos = 0
|
||||
self._effect_init = False
|
||||
return self
|
||||
|
||||
def set_brightness(self, percent):
|
||||
self._led.duty_cycle = int(percent / 100 * 65535)
|
||||
|
||||
@@ -161,8 +179,6 @@ class LED(Extension):
|
||||
else:
|
||||
self.off()
|
||||
|
||||
return self
|
||||
|
||||
def _key_led_tog(self, key, state, *args, **kwargs):
|
||||
if self.animation_mode == AnimationModes.STATIC_STANDBY:
|
||||
self.animation_mode = AnimationModes.STATIC
|
||||
|
@@ -26,3 +26,24 @@ class MediaKeys(Extension):
|
||||
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
|
||||
|
||||
def on_runtime_enable(self, keyboard):
|
||||
return
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
return
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
return
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard, matrix_update):
|
||||
return
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
return
|
||||
|
55
kmk/extensions/modtap.py
Normal file
55
kmk/extensions/modtap.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from kmk.extensions import Extension
|
||||
from kmk.key_validators import mod_tap_validator
|
||||
from kmk.keys import make_argumented_key
|
||||
from kmk.kmktime import accurate_ticks, accurate_ticks_diff
|
||||
|
||||
|
||||
class ModTap(Extension):
|
||||
def __init__(self):
|
||||
self._mod_tap_timer = None
|
||||
make_argumented_key(
|
||||
validator=mod_tap_validator,
|
||||
names=('MT',),
|
||||
on_press=self.mt_pressed,
|
||||
on_release=self.mt_released,
|
||||
)
|
||||
|
||||
def on_runtime_enable(self, keyboard):
|
||||
return
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
return
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
return
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard, matrix_update):
|
||||
return
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def mt_pressed(self, key, state, *args, **kwargs):
|
||||
'''Sets the timer start and acts like a modifier otherwise'''
|
||||
state.keys_pressed.add(key.meta.mods)
|
||||
|
||||
self._mod_tap_timer = accurate_ticks()
|
||||
return state
|
||||
|
||||
def mt_released(self, key, state, *args, **kwargs):
|
||||
''' On keyup, check timer, and press key if needed.'''
|
||||
state.keys_pressed.discard(key.meta.mods)
|
||||
if self._mod_tap_timer and (
|
||||
accurate_ticks_diff(accurate_ticks(), self._mod_tap_timer, state.tap_time)
|
||||
):
|
||||
state.hid_pending = True
|
||||
state.tap_key(key.meta.kc)
|
||||
|
||||
self._mod_tap_timer = None
|
||||
return state
|
@@ -1,93 +1,144 @@
|
||||
import board
|
||||
import digitalio
|
||||
|
||||
from kmk.extensions import Extension
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import make_key
|
||||
from kmk.kmktime import sleep_ms, ticks_diff, ticks_ms
|
||||
|
||||
|
||||
class Power(Extension):
|
||||
def __init__(self, powersave_pin=None, enable=False, is_target=True):
|
||||
self.enable = enable
|
||||
self.powersave_pin = powersave_pin
|
||||
self.powersave_pin = powersave_pin # Powersave pin board object
|
||||
self.is_target = is_target
|
||||
self._powersave_start = ticks_ms()
|
||||
self._usb_last_scan = ticks_ms() - 5000
|
||||
self._psp = None
|
||||
self._psp = None # Powersave pin object
|
||||
self._i2c = None
|
||||
|
||||
make_key(
|
||||
names=('PS_TOG',), on_press=self._ps_tog, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('PS_ENB',), on_press=self._ps_enable, on_release=handler_passthrough
|
||||
)
|
||||
make_key(
|
||||
names=('PS_DIS',), on_press=self._ps_disable, on_release=handler_passthrough
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return f'Power({self._to_dict()})'
|
||||
|
||||
def _to_dict(self):
|
||||
return f'Power( enable={self.enable} powersave_pin={self.powersave_pin} is_target={self.is_target} _powersave_start={self._powersave_start} _usb_last_scan={self._usb_last_scan} _psp={self._psp} )'
|
||||
return f'''Power(
|
||||
enable={self.enable}
|
||||
powersave_pin={self.powersave_pin}
|
||||
is_target={self.is_target}
|
||||
_powersave_start={self._powersave_start}
|
||||
_usb_last_scan={self._usb_last_scan}
|
||||
_psp={self._psp} )
|
||||
'''
|
||||
|
||||
def on_runtime_enable(self, keyboard):
|
||||
return
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
self.disable_powersave
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
self._detect_i2c()
|
||||
self.enable = not bool(self.usb_scan)
|
||||
|
||||
def before_matrix_scan(self, keyboard_state):
|
||||
def before_matrix_scan(self, keyboard):
|
||||
if self.usb_rescan_timer():
|
||||
self.enable = not bool(self.usb_scan)
|
||||
|
||||
def after_matrix_scan(self, keyboard_state, matrix_update):
|
||||
def after_matrix_scan(self, keyboard, matrix_update):
|
||||
if matrix_update:
|
||||
self.psave_time_reset()
|
||||
else:
|
||||
self.psleep()
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def enable_powersave(self):
|
||||
'''Enables power saving features'''
|
||||
print('Psave True')
|
||||
if self.powersave_pin:
|
||||
import digitalio
|
||||
|
||||
# Allows power save to prevent RGB drain.
|
||||
# Example here https://docs.nicekeyboards.com/#/nice!nano/pinout_schematic
|
||||
|
||||
if not self._psp:
|
||||
self._psp = digitalio.DigitalInOut(self.powersave_pin)
|
||||
self._psp.direction = digitalio.Direction.OUTPUT
|
||||
self._psp.value = True
|
||||
# TODO Allow a hook to stop RGB/OLED to deinit or this causes a lockup
|
||||
|
||||
self.enable = True
|
||||
|
||||
return self
|
||||
|
||||
def disable_powersave(self):
|
||||
'''Disables power saving features'''
|
||||
print('Psave False')
|
||||
if self.powersave_pin:
|
||||
import digitalio
|
||||
|
||||
# Allows power save to prevent RGB drain.
|
||||
# Example here https://docs.nicekeyboards.com/#/nice!nano/pinout_schematic
|
||||
|
||||
if not self._psp:
|
||||
self._psp = digitalio.DigitalInOut(self.powersave_pin)
|
||||
self._psp.direction = digitalio.Direction.OUTPUT
|
||||
self._psp.value = False
|
||||
# TODO Allow a hook to stop RGB/OLED to reinit
|
||||
|
||||
self.enable = False
|
||||
|
||||
return self
|
||||
|
||||
def psleep(self):
|
||||
'''
|
||||
Sleeps longer and longer to save power the more time in between updates.
|
||||
'''
|
||||
if ticks_diff(ticks_ms(), self.powersave_start) <= 20000 and self.is_target:
|
||||
if ticks_diff(ticks_ms(), self._powersave_start) <= 20000 and self.is_target:
|
||||
sleep_ms(1)
|
||||
elif ticks_diff(ticks_ms(), self.powersave_start) <= 40000 and self.is_target:
|
||||
elif ticks_diff(ticks_ms(), self._powersave_start) <= 40000 and self.is_target:
|
||||
sleep_ms(4)
|
||||
elif ticks_diff(ticks_ms(), self.powersave_start) <= 60000 and self.is_target:
|
||||
elif ticks_diff(ticks_ms(), self._powersave_start) <= 60000 and self.is_target:
|
||||
sleep_ms(8)
|
||||
elif ticks_diff(ticks_ms(), self.powersave_start) >= 240000:
|
||||
elif ticks_diff(ticks_ms(), self._powersave_start) >= 240000:
|
||||
sleep_ms(250)
|
||||
|
||||
def psave_time_reset(self):
|
||||
self.powersave_start = ticks_ms()
|
||||
return self
|
||||
self._powersave_start = ticks_ms()
|
||||
|
||||
def usb_rescan_timer(self):
|
||||
return bool(ticks_diff(ticks_ms(), self.usb_last_scan) > 5000)
|
||||
return bool(ticks_diff(ticks_ms(), self._usb_last_scan) > 5000)
|
||||
|
||||
def usb_time_reset(self):
|
||||
self.usb_last_scan = ticks_ms()
|
||||
return self
|
||||
self._usb_last_scan = ticks_ms()
|
||||
|
||||
def usb_scan(self):
|
||||
# TODO Add USB detection here. Currently lies that it's connected
|
||||
# https://github.com/adafruit/circuitpython/pull/3513
|
||||
return True
|
||||
|
||||
def _detect_i2c(self):
|
||||
'''Detects i2c devices and disables cutting power to them'''
|
||||
# TODO Figure out how this could deinit/reinit instead.
|
||||
self._i2c = board.I2C()
|
||||
devices = self._i2c.scan()
|
||||
if devices != []:
|
||||
self.powersave_pin = None
|
||||
|
||||
def _ps_tog(self):
|
||||
if self.enable:
|
||||
self.enable_powersave()
|
||||
else:
|
||||
self.disable_powersave()
|
||||
|
||||
def _ps_enable(self):
|
||||
if not self.enable:
|
||||
self.enable_powersave()
|
||||
|
||||
def _ps_disable(self):
|
||||
if self.enable:
|
||||
self.disable_powersave()
|
||||
|
@@ -141,6 +141,24 @@ class RGB(Extension):
|
||||
on_release=handler_passthrough,
|
||||
)
|
||||
|
||||
def on_runtime_enable(self, keyboard):
|
||||
return
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
return
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
return
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard, matrix_update):
|
||||
return
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
if self.animation_mode:
|
||||
self.loopcounter += 1
|
||||
@@ -150,7 +168,8 @@ class RGB(Extension):
|
||||
|
||||
return keyboard
|
||||
|
||||
def time_ms(self):
|
||||
@staticmethod
|
||||
def time_ms():
|
||||
return int(time.monotonic() * 1000)
|
||||
|
||||
def hsv_to_rgb(self, hue, sat, val):
|
||||
@@ -230,8 +249,6 @@ class RGB(Extension):
|
||||
else:
|
||||
self.set_rgb(self.hsv_to_rgb(hue, sat, val), index)
|
||||
|
||||
return self
|
||||
|
||||
def set_hsv_fill(self, hue, sat, val):
|
||||
'''
|
||||
Takes HSV values and displays it on all LEDs/Neopixels
|
||||
@@ -244,7 +261,6 @@ class RGB(Extension):
|
||||
self.set_rgb_fill(self.hsv_to_rgbw(hue, sat, val))
|
||||
else:
|
||||
self.set_rgb_fill(self.hsv_to_rgb(hue, sat, val))
|
||||
return self
|
||||
|
||||
def set_rgb(self, rgb, index):
|
||||
'''
|
||||
@@ -257,8 +273,6 @@ class RGB(Extension):
|
||||
if not self.disable_auto_write:
|
||||
self.neopixel.show()
|
||||
|
||||
return self
|
||||
|
||||
def set_rgb_fill(self, rgb):
|
||||
'''
|
||||
Takes an RGB or RGBW and displays it on all LEDs/Neopixels
|
||||
@@ -269,8 +283,6 @@ class RGB(Extension):
|
||||
if not self.disable_auto_write:
|
||||
self.neopixel.show()
|
||||
|
||||
return self
|
||||
|
||||
def increase_hue(self, step=None):
|
||||
'''
|
||||
Increases hue by step amount rolling at 360 and returning to 0
|
||||
@@ -284,8 +296,6 @@ class RGB(Extension):
|
||||
if self._check_update():
|
||||
self._do_update()
|
||||
|
||||
return self
|
||||
|
||||
def decrease_hue(self, step=None):
|
||||
'''
|
||||
Decreases hue by step amount rolling at 0 and returning to 360
|
||||
@@ -302,8 +312,6 @@ class RGB(Extension):
|
||||
if self._check_update():
|
||||
self._do_update()
|
||||
|
||||
return self
|
||||
|
||||
def increase_sat(self, step=None):
|
||||
'''
|
||||
Increases saturation by step amount stopping at 100
|
||||
@@ -320,8 +328,6 @@ class RGB(Extension):
|
||||
if self._check_update():
|
||||
self._do_update()
|
||||
|
||||
return self
|
||||
|
||||
def decrease_sat(self, step=None):
|
||||
'''
|
||||
Decreases saturation by step amount stopping at 0
|
||||
@@ -338,8 +344,6 @@ class RGB(Extension):
|
||||
if self._check_update():
|
||||
self._do_update()
|
||||
|
||||
return self
|
||||
|
||||
def increase_val(self, step=None):
|
||||
'''
|
||||
Increases value by step amount stopping at 100
|
||||
@@ -355,8 +359,6 @@ class RGB(Extension):
|
||||
if self._check_update():
|
||||
self._do_update()
|
||||
|
||||
return self
|
||||
|
||||
def decrease_val(self, step=None):
|
||||
'''
|
||||
Decreases value by step amount stopping at 0
|
||||
@@ -372,8 +374,6 @@ class RGB(Extension):
|
||||
if self._check_update():
|
||||
self._do_update()
|
||||
|
||||
return self
|
||||
|
||||
def increase_ani(self):
|
||||
'''
|
||||
Increases animation speed by 1 amount stopping at 10
|
||||
@@ -386,8 +386,6 @@ class RGB(Extension):
|
||||
if self._check_update():
|
||||
self._do_update()
|
||||
|
||||
return self
|
||||
|
||||
def decrease_ani(self):
|
||||
'''
|
||||
Decreases animation speed by 1 amount stopping at 0
|
||||
@@ -400,8 +398,6 @@ class RGB(Extension):
|
||||
if self._check_update():
|
||||
self._do_update()
|
||||
|
||||
return self
|
||||
|
||||
def off(self):
|
||||
'''
|
||||
Turns off all LEDs/Neopixels without changing stored values
|
||||
@@ -409,8 +405,6 @@ class RGB(Extension):
|
||||
if self.neopixel:
|
||||
self.set_hsv_fill(0, 0, 0)
|
||||
|
||||
return self
|
||||
|
||||
def show(self):
|
||||
'''
|
||||
Turns on all LEDs/Neopixels without changing stored values
|
||||
@@ -418,8 +412,6 @@ class RGB(Extension):
|
||||
if self.neopixel:
|
||||
self.neopixel.show()
|
||||
|
||||
return self
|
||||
|
||||
def animate(self):
|
||||
'''
|
||||
Activates a "step" in the animation based on the active mode
|
||||
@@ -448,8 +440,6 @@ class RGB(Extension):
|
||||
else:
|
||||
self.off()
|
||||
|
||||
return self
|
||||
|
||||
def _animation_step(self):
|
||||
interval = self.time_ms() - self.time
|
||||
if interval >= max(self.intervals):
|
||||
@@ -471,7 +461,6 @@ class RGB(Extension):
|
||||
self.pos = 0
|
||||
self.reverse_animation = False
|
||||
self.effect_init = False
|
||||
return self
|
||||
|
||||
def _check_update(self):
|
||||
return bool(self.animation_mode == AnimationModes.STATIC_STANDBY)
|
||||
@@ -483,7 +472,6 @@ class RGB(Extension):
|
||||
def effect_static(self):
|
||||
self.set_hsv_fill(self.hue, self.sat, self.val)
|
||||
self.animation_mode = AnimationModes.STATIC_STANDBY
|
||||
return self
|
||||
|
||||
def effect_breathing(self):
|
||||
# http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
|
||||
@@ -496,20 +484,14 @@ class RGB(Extension):
|
||||
self.pos = (self.pos + self.animation_speed) % 256
|
||||
self.set_hsv_fill(self.hue, self.sat, self.val)
|
||||
|
||||
return self
|
||||
|
||||
def effect_breathing_rainbow(self):
|
||||
self.increase_hue(self.animation_speed)
|
||||
self.effect_breathing()
|
||||
|
||||
return self
|
||||
|
||||
def effect_rainbow(self):
|
||||
self.increase_hue(self.animation_speed)
|
||||
self.set_hsv_fill(self.hue, self.sat, self.val)
|
||||
|
||||
return self
|
||||
|
||||
def effect_swirl(self):
|
||||
self.increase_hue(self.animation_speed)
|
||||
self.disable_auto_write = True # Turn off instantly showing
|
||||
@@ -521,7 +503,6 @@ class RGB(Extension):
|
||||
# Show final results
|
||||
self.disable_auto_write = False # Resume showing changes
|
||||
self.show()
|
||||
return self
|
||||
|
||||
def effect_knight(self):
|
||||
# Determine which LEDs should be lit up
|
||||
@@ -546,8 +527,6 @@ class RGB(Extension):
|
||||
self.disable_auto_write = False # Resume showing changes
|
||||
self.show()
|
||||
|
||||
return self
|
||||
|
||||
def _rgb_tog(self, key, state, *args, **kwargs):
|
||||
if self.animation_mode == AnimationModes.STATIC:
|
||||
self.animation_mode = AnimationModes.STATIC_STANDBY
|
||||
@@ -556,69 +535,54 @@ class RGB(Extension):
|
||||
self.animation_mode = AnimationModes.STATIC
|
||||
self._do_update()
|
||||
self.enable = not self.enable
|
||||
return state
|
||||
|
||||
def _rgb_hui(self, key, state, *args, **kwargs):
|
||||
self.increase_hue()
|
||||
return state
|
||||
|
||||
def _rgb_hud(self, key, state, *args, **kwargs):
|
||||
self.decrease_hue()
|
||||
return state
|
||||
|
||||
def _rgb_sai(self, key, state, *args, **kwargs):
|
||||
self.increase_sat()
|
||||
return state
|
||||
|
||||
def _rgb_sad(self, key, state, *args, **kwargs):
|
||||
self.decrease_sat()
|
||||
return state
|
||||
|
||||
def _rgb_vai(self, key, state, *args, **kwargs):
|
||||
self.increase_val()
|
||||
return state
|
||||
|
||||
def _rgb_vad(self, key, state, *args, **kwargs):
|
||||
self.decrease_val()
|
||||
return state
|
||||
|
||||
def _rgb_ani(self, key, state, *args, **kwargs):
|
||||
self.increase_ani()
|
||||
return state
|
||||
|
||||
def _rgb_and(self, key, state, *args, **kwargs):
|
||||
self.decrease_ani()
|
||||
return state
|
||||
|
||||
def _rgb_mode_static(self, key, state, *args, **kwargs):
|
||||
self.effect_init = True
|
||||
self.animation_mode = AnimationModes.STATIC
|
||||
return state
|
||||
|
||||
def _rgb_mode_breathe(self, key, state, *args, **kwargs):
|
||||
self.effect_init = True
|
||||
self.animation_mode = AnimationModes.BREATHING
|
||||
return state
|
||||
|
||||
def _rgb_mode_breathe_rainbow(self, key, state, *args, **kwargs):
|
||||
self.effect_init = True
|
||||
self.animation_mode = AnimationModes.BREATHING_RAINBOW
|
||||
return state
|
||||
|
||||
def _rgb_mode_rainbow(self, key, state, *args, **kwargs):
|
||||
self.effect_init = True
|
||||
self.animation_mode = AnimationModes.RAINBOW
|
||||
return state
|
||||
|
||||
def _rgb_mode_swirl(self, key, state, *args, **kwargs):
|
||||
self.effect_init = True
|
||||
self.animation_mode = AnimationModes.SWIRL
|
||||
return state
|
||||
|
||||
def _rgb_mode_knight(self, key, state, *args, **kwargs):
|
||||
self.effect_init = True
|
||||
self.animation_mode = AnimationModes.KNIGHT
|
||||
return state
|
||||
|
||||
def _rgb_reset(self, key, state, *args, **kwargs):
|
||||
self.hue = self.hue_default
|
||||
@@ -627,4 +591,3 @@ class RGB(Extension):
|
||||
if self.animation_mode == AnimationModes.STATIC_STANDBY:
|
||||
self.animation_mode = AnimationModes.STATIC
|
||||
self._do_update()
|
||||
return state
|
||||
|
@@ -37,6 +37,12 @@ class Split(Extension):
|
||||
self.uart_pin = uart_pin
|
||||
self.uart_timeout = uart_timeout
|
||||
|
||||
def on_runtime_enable(self, keyboard):
|
||||
return
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
return
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
try:
|
||||
# Working around https://github.com/adafruit/circuitpython/issues/1769
|
||||
@@ -75,14 +81,21 @@ class Split(Extension):
|
||||
for cidx in range(cols_to_calc):
|
||||
keyboard.coord_mapping.append(intify_coordinate(ridx, cidx))
|
||||
|
||||
def before_matrix_scan(self, keyboard_state):
|
||||
def before_matrix_scan(self, keyboard):
|
||||
if self._is_target:
|
||||
return self._receive()
|
||||
return None
|
||||
|
||||
def after_matrix_scan(self, keyboard_state, matrix_update):
|
||||
def after_matrix_scan(self, keyboard, matrix_update):
|
||||
if matrix_update is not None and not self._is_target:
|
||||
self._send(matrix_update)
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
return
|
||||
|
||||
def _send(self, update):
|
||||
if self.split_target_left:
|
||||
update[1] += self.split_offset
|
||||
|
@@ -1,23 +0,0 @@
|
||||
from kmk.kmktime import ticks_diff, ticks_ms
|
||||
|
||||
|
||||
def mt_pressed(key, state, *args, **kwargs):
|
||||
# Sets the timer start and acts like a modifier otherwise
|
||||
state._keys_pressed.add(key.meta.mods)
|
||||
|
||||
state._start_time['mod_tap'] = ticks_ms()
|
||||
return state
|
||||
|
||||
|
||||
def mt_released(key, state, *args, **kwargs):
|
||||
# On keyup, check timer, and press key if needed.
|
||||
state._keys_pressed.discard(key.meta.mods)
|
||||
timer_name = 'mod_tap'
|
||||
if state._start_time[timer_name] and (
|
||||
ticks_diff(ticks_ms(), state._start_time[timer_name]) < state.tap_time
|
||||
):
|
||||
state._hid_pending = True
|
||||
state._tap_key(key.meta.kc)
|
||||
|
||||
state._start_time[timer_name] = None
|
||||
return state
|
@@ -12,18 +12,18 @@ def get_wide_ordinal(char):
|
||||
|
||||
|
||||
def sequence_press_handler(key, state, KC, *args, **kwargs):
|
||||
old_keys_pressed = state._keys_pressed
|
||||
state._keys_pressed = set()
|
||||
oldkeys_pressed = state.keys_pressed
|
||||
state.keys_pressed = set()
|
||||
|
||||
for ikey in key.meta.seq:
|
||||
if not getattr(ikey, 'no_press', None):
|
||||
state._process_key(ikey, True)
|
||||
state.process_key(ikey, True)
|
||||
state._send_hid()
|
||||
if not getattr(ikey, 'no_release', None):
|
||||
state._process_key(ikey, False)
|
||||
state.process_key(ikey, False)
|
||||
state._send_hid()
|
||||
|
||||
state._keys_pressed = old_keys_pressed
|
||||
state.keys_pressed = oldkeys_pressed
|
||||
|
||||
return state
|
||||
|
||||
@@ -104,15 +104,15 @@ def unicode_codepoint_sequence(codepoints):
|
||||
|
||||
def _unicode_sequence(key, state, *args, **kwargs):
|
||||
if state.unicode_mode == UnicodeMode.IBUS:
|
||||
state._process_key(
|
||||
state.process_key(
|
||||
simple_key_sequence(_ibus_unicode_sequence(kc_macros, state)), True
|
||||
)
|
||||
elif state.unicode_mode == UnicodeMode.RALT:
|
||||
state._process_key(
|
||||
state.process_key(
|
||||
simple_key_sequence(_ralt_unicode_sequence(kc_macros, state)), True
|
||||
)
|
||||
elif state.unicode_mode == UnicodeMode.WINC:
|
||||
state._process_key(
|
||||
state.process_key(
|
||||
simple_key_sequence(_winc_unicode_sequence(kc_macros, state)), True
|
||||
)
|
||||
|
||||
|
@@ -6,50 +6,38 @@ def passthrough(key, state, *args, **kwargs):
|
||||
|
||||
|
||||
def default_pressed(key, state, KC, coord_int=None, coord_raw=None):
|
||||
state._hid_pending = True
|
||||
state.hid_pending = True
|
||||
|
||||
if coord_int is not None:
|
||||
state._coord_keys_pressed[coord_int] = key
|
||||
state._coordkeys_pressed[coord_int] = key
|
||||
|
||||
state._keys_pressed.add(key)
|
||||
state.keys_pressed.add(key)
|
||||
|
||||
return state
|
||||
|
||||
|
||||
def default_released(key, state, KC, coord_int=None, coord_raw=None):
|
||||
state._hid_pending = True
|
||||
state._keys_pressed.discard(key)
|
||||
state.hid_pending = True
|
||||
state.keys_pressed.discard(key)
|
||||
|
||||
if coord_int is not None:
|
||||
state._keys_pressed.discard(state._coord_keys_pressed.get(coord_int, None))
|
||||
state._coord_keys_pressed[coord_int] = None
|
||||
state.keys_pressed.discard(state._coordkeys_pressed.get(coord_int, None))
|
||||
state._coordkeys_pressed[coord_int] = None
|
||||
|
||||
return state
|
||||
|
||||
|
||||
def reset(*args, **kwargs):
|
||||
try:
|
||||
import machine
|
||||
import microcontroller
|
||||
|
||||
machine.reset()
|
||||
|
||||
except ImportError:
|
||||
import microcontroller
|
||||
|
||||
microcontroller.reset()
|
||||
microcontroller.reset()
|
||||
|
||||
|
||||
def bootloader(*args, **kwargs):
|
||||
try:
|
||||
import machine
|
||||
import microcontroller
|
||||
|
||||
machine.bootloader()
|
||||
|
||||
except ImportError:
|
||||
import microcontroller
|
||||
|
||||
microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
|
||||
microcontroller.reset()
|
||||
microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
|
||||
microcontroller.reset()
|
||||
|
||||
|
||||
def debug_pressed(key, state, KC, *args, **kwargs):
|
||||
@@ -66,48 +54,48 @@ def debug_pressed(key, state, KC, *args, **kwargs):
|
||||
def gesc_pressed(key, state, KC, *args, **kwargs):
|
||||
GESC_TRIGGERS = {KC.LSHIFT, KC.RSHIFT, KC.LGUI, KC.RGUI}
|
||||
|
||||
if GESC_TRIGGERS.intersection(state._keys_pressed):
|
||||
if GESC_TRIGGERS.intersection(state.keys_pressed):
|
||||
# First, release GUI if already pressed
|
||||
state._send_hid()
|
||||
# if Shift is held, KC_GRAVE will become KC_TILDE on OS level
|
||||
state._keys_pressed.add(KC.GRAVE)
|
||||
state._hid_pending = True
|
||||
state.keys_pressed.add(KC.GRAVE)
|
||||
state.hid_pending = True
|
||||
return state
|
||||
|
||||
# else return KC_ESC
|
||||
state._keys_pressed.add(KC.ESCAPE)
|
||||
state._hid_pending = True
|
||||
state.keys_pressed.add(KC.ESCAPE)
|
||||
state.hid_pending = True
|
||||
|
||||
return state
|
||||
|
||||
|
||||
def gesc_released(key, state, KC, *args, **kwargs):
|
||||
state._keys_pressed.discard(KC.ESCAPE)
|
||||
state._keys_pressed.discard(KC.GRAVE)
|
||||
state._hid_pending = True
|
||||
state.keys_pressed.discard(KC.ESCAPE)
|
||||
state.keys_pressed.discard(KC.GRAVE)
|
||||
state.hid_pending = True
|
||||
return state
|
||||
|
||||
|
||||
def bkdl_pressed(key, state, KC, *args, **kwargs):
|
||||
BKDL_TRIGGERS = {KC.LGUI, KC.RGUI}
|
||||
|
||||
if BKDL_TRIGGERS.intersection(state._keys_pressed):
|
||||
if BKDL_TRIGGERS.intersection(state.keys_pressed):
|
||||
state._send_hid()
|
||||
state._keys_pressed.add(KC.DEL)
|
||||
state._hid_pending = True
|
||||
state.keys_pressed.add(KC.DEL)
|
||||
state.hid_pending = True
|
||||
return state
|
||||
|
||||
# else return KC_ESC
|
||||
state._keys_pressed.add(KC.BKSP)
|
||||
state._hid_pending = True
|
||||
state.keys_pressed.add(KC.BKSP)
|
||||
state.hid_pending = True
|
||||
|
||||
return state
|
||||
|
||||
|
||||
def bkdl_released(key, state, KC, *args, **kwargs):
|
||||
state._keys_pressed.discard(KC.BKSP)
|
||||
state._keys_pressed.discard(KC.DEL)
|
||||
state._hid_pending = True
|
||||
state.keys_pressed.discard(KC.BKSP)
|
||||
state.keys_pressed.discard(KC.DEL)
|
||||
state.hid_pending = True
|
||||
return state
|
||||
|
||||
|
||||
|
@@ -60,7 +60,7 @@ class Key:
|
||||
def __repr__(self):
|
||||
return 'Key(code={}, has_modifiers={})'.format(self.code, self.has_modifiers)
|
||||
|
||||
def _on_press(self, state, coord_int, coord_raw):
|
||||
def on_press(self, state, coord_int, coord_raw):
|
||||
for fn in self._pre_press_handlers:
|
||||
if not fn(self, state, KC, coord_int, coord_raw):
|
||||
return None
|
||||
@@ -72,7 +72,7 @@ class Key:
|
||||
|
||||
return ret
|
||||
|
||||
def _on_release(self, state, coord_int, coord_raw):
|
||||
def on_release(self, state, coord_int, coord_raw):
|
||||
for fn in self._pre_release_handlers:
|
||||
if not fn(self, state, KC, coord_int, coord_raw):
|
||||
return None
|
||||
|
@@ -28,22 +28,22 @@ class KMKKeyboard:
|
||||
|
||||
#####
|
||||
# Internal State
|
||||
_keys_pressed = set()
|
||||
_coord_keys_pressed = {}
|
||||
keys_pressed = set()
|
||||
_coordkeys_pressed = {}
|
||||
hid_type = HIDModes.USB
|
||||
_hid_helper = None
|
||||
_hid_pending = False
|
||||
_state_layer_key = None
|
||||
_matrix_update = None
|
||||
hid_pending = False
|
||||
state_layer_key = None
|
||||
matrix_update = None
|
||||
_matrix_modify = None
|
||||
_state_changed = False
|
||||
state_changed = False
|
||||
_old_timeouts_len = None
|
||||
_new_timeouts_len = None
|
||||
|
||||
# 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]
|
||||
|
||||
_timeouts = {}
|
||||
_tapping = False
|
||||
@@ -64,7 +64,7 @@ class KMKKeyboard:
|
||||
'tap_time={} '
|
||||
'_hid_helper={} '
|
||||
'keys_pressed={} '
|
||||
'coord_keys_pressed={} '
|
||||
'coordkeys_pressed={} '
|
||||
'hid_pending={} '
|
||||
'active_layers={} '
|
||||
'timeouts={} '
|
||||
@@ -82,12 +82,12 @@ class KMKKeyboard:
|
||||
self.matrix_scanner,
|
||||
self.unicode_mode,
|
||||
self.tap_time,
|
||||
self._hid_helper.__name__,
|
||||
self._hid_helper,
|
||||
# internal state
|
||||
self._keys_pressed,
|
||||
self._coord_keys_pressed,
|
||||
self._hid_pending,
|
||||
self._active_layers,
|
||||
self.keys_pressed,
|
||||
self._coordkeys_pressed,
|
||||
self.hid_pending,
|
||||
self.active_layers,
|
||||
self._timeouts,
|
||||
self._tapping,
|
||||
self._tap_dance_counts,
|
||||
@@ -102,13 +102,13 @@ class KMKKeyboard:
|
||||
print(self)
|
||||
|
||||
def _send_hid(self):
|
||||
self._hid_helper.create_report(self._keys_pressed).send()
|
||||
self._hid_pending = False
|
||||
self._hid_helper.create_report(self.keys_pressed).send()
|
||||
self.hid_pending = False
|
||||
|
||||
def _handle_matrix_report(self, update=None):
|
||||
if update is not None:
|
||||
self._on_matrix_changed(update[0], update[1], update[2])
|
||||
self._state_changed = True
|
||||
self.state_changed = True
|
||||
|
||||
#####
|
||||
# SPLICE: INTERNAL STATE
|
||||
@@ -116,7 +116,7 @@ class KMKKeyboard:
|
||||
#####
|
||||
|
||||
def _find_key_in_map(self, int_coord, row, col):
|
||||
self._state_layer_key = None
|
||||
self.state_layer_key = None
|
||||
try:
|
||||
idx = self.coord_mapping.index(int_coord)
|
||||
except ValueError:
|
||||
@@ -129,16 +129,16 @@ class KMKKeyboard:
|
||||
|
||||
return None
|
||||
|
||||
for layer in self._active_layers:
|
||||
self._state_layer_key = self.keymap[layer][idx]
|
||||
for layer in self.active_layers:
|
||||
self.state_layer_key = self.keymap[layer][idx]
|
||||
|
||||
if not self._state_layer_key or self._state_layer_key == KC.TRNS:
|
||||
if not self.state_layer_key or self.state_layer_key == KC.TRNS:
|
||||
continue
|
||||
|
||||
if self.debug_enabled:
|
||||
print('KeyResolution(key={})'.format(self._state_layer_key))
|
||||
print('KeyResolution(key={})'.format(self.state_layer_key))
|
||||
|
||||
return self._state_layer_key
|
||||
return self.state_layer_key
|
||||
|
||||
def _on_matrix_changed(self, row, col, is_pressed):
|
||||
if self.debug_enabled:
|
||||
@@ -151,31 +151,31 @@ class KMKKeyboard:
|
||||
print('MatrixUndefinedCoordinate(col={} row={})'.format(col, row))
|
||||
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))
|
||||
|
||||
def _process_key(self, key, is_pressed, coord_int=None, coord_raw=None):
|
||||
def process_key(self, key, is_pressed, coord_int=None, coord_raw=None):
|
||||
if self._tapping and not isinstance(key.meta, TapDanceKeyMeta):
|
||||
self._process_tap_dance(key, is_pressed)
|
||||
else:
|
||||
if is_pressed:
|
||||
key._on_press(self, coord_int, coord_raw)
|
||||
key.on_press(self, coord_int, coord_raw)
|
||||
else:
|
||||
key._on_release(self, coord_int, coord_raw)
|
||||
key.on_release(self, coord_int, coord_raw)
|
||||
|
||||
return self
|
||||
|
||||
def _remove_key(self, keycode):
|
||||
self._keys_pressed.discard(keycode)
|
||||
return self._process_key(keycode, False)
|
||||
def remove_key(self, keycode):
|
||||
self.keys_pressed.discard(keycode)
|
||||
return self.process_key(keycode, False)
|
||||
|
||||
def _add_key(self, keycode):
|
||||
self._keys_pressed.add(keycode)
|
||||
return self._process_key(keycode, True)
|
||||
def add_key(self, keycode):
|
||||
self.keys_pressed.add(keycode)
|
||||
return self.process_key(keycode, True)
|
||||
|
||||
def _tap_key(self, keycode):
|
||||
self._add_key(keycode)
|
||||
def tap_key(self, keycode):
|
||||
self.add_key(keycode)
|
||||
# On the next cycle, we'll remove the key.
|
||||
self._set_timeout(False, lambda: self._remove_key(keycode))
|
||||
self.set_timeout(False, lambda: self.remove_key(keycode))
|
||||
|
||||
return self
|
||||
|
||||
@@ -196,7 +196,7 @@ class KMKKeyboard:
|
||||
or not self._tap_dance_counts[changed_key]
|
||||
):
|
||||
self._tap_dance_counts[changed_key] = 1
|
||||
self._set_timeout(
|
||||
self.set_timeout(
|
||||
self.tap_time, lambda: self._end_tap_dance(changed_key)
|
||||
)
|
||||
self._tapping = True
|
||||
@@ -220,19 +220,19 @@ class KMKKeyboard:
|
||||
v = self._tap_dance_counts[td_key] - 1
|
||||
|
||||
if v >= 0:
|
||||
if td_key in self._keys_pressed:
|
||||
if td_key in self.keys_pressed:
|
||||
key_to_press = td_key.codes[v]
|
||||
self._add_key(key_to_press)
|
||||
self.add_key(key_to_press)
|
||||
self._tap_side_effects[td_key] = key_to_press
|
||||
self._hid_pending = True
|
||||
self.hid_pending = True
|
||||
else:
|
||||
if self._tap_side_effects[td_key]:
|
||||
self._remove_key(self._tap_side_effects[td_key])
|
||||
self.remove_key(self._tap_side_effects[td_key])
|
||||
self._tap_side_effects[td_key] = None
|
||||
self._hid_pending = True
|
||||
self.hid_pending = True
|
||||
self._cleanup_tap_dance(td_key)
|
||||
else:
|
||||
self._tap_key(td_key.codes[v])
|
||||
self.tap_key(td_key.codes[v])
|
||||
self._cleanup_tap_dance(td_key)
|
||||
|
||||
return self
|
||||
@@ -242,7 +242,7 @@ class KMKKeyboard:
|
||||
self._tapping = any(count > 0 for count in self._tap_dance_counts.values())
|
||||
return self
|
||||
|
||||
def _set_timeout(self, after_ticks, callback):
|
||||
def set_timeout(self, after_ticks, callback):
|
||||
if after_ticks is False:
|
||||
# We allow passing False as an implicit "run this on the next process timeouts cycle"
|
||||
timeout_key = ticks_ms()
|
||||
@@ -366,7 +366,7 @@ class KMKKeyboard:
|
||||
self._print_debug_cycle(init=True)
|
||||
|
||||
while True:
|
||||
self._state_changed = False
|
||||
self.state_changed = False
|
||||
|
||||
for ext in self.extensions:
|
||||
try:
|
||||
@@ -374,20 +374,20 @@ class KMKKeyboard:
|
||||
except Exception as err:
|
||||
print('Failed to run pre matrix function: ', err)
|
||||
|
||||
self._matrix_update = self.matrix.scan_for_changes()
|
||||
self.matrix_update = self.matrix.scan_for_changes()
|
||||
|
||||
for ext in self.extensions:
|
||||
try:
|
||||
self._matrix_modify = ext.after_matrix_scan(
|
||||
self, self._matrix_update
|
||||
self, self.matrix_update
|
||||
)
|
||||
if self._matrix_modify is not None:
|
||||
self._matrix_update = self._matrix_modify
|
||||
self.matrix_update = self._matrix_modify
|
||||
except Exception as err:
|
||||
print('Failed to run post matrix function: ', err)
|
||||
|
||||
self._handle_matrix_report(self._matrix_update)
|
||||
self._matrix_update = None
|
||||
self._handle_matrix_report(self.matrix_update)
|
||||
self.matrix_update = None
|
||||
|
||||
for ext in self.extensions:
|
||||
try:
|
||||
@@ -395,7 +395,7 @@ class KMKKeyboard:
|
||||
except Exception as err:
|
||||
print('Failed to run pre hid function: ', err)
|
||||
|
||||
if self._hid_pending:
|
||||
if self.hid_pending:
|
||||
self._send_hid()
|
||||
|
||||
self._old_timeouts_len = len(self._timeouts)
|
||||
@@ -403,8 +403,8 @@ class KMKKeyboard:
|
||||
self._new_timeouts_len = len(self._timeouts)
|
||||
|
||||
if self._old_timeouts_len != self._new_timeouts_len:
|
||||
self._state_changed = True
|
||||
if self._hid_pending:
|
||||
self.state_changed = True
|
||||
if self.hid_pending:
|
||||
self._send_hid()
|
||||
|
||||
for ext in self.extensions:
|
||||
@@ -413,5 +413,5 @@ class KMKKeyboard:
|
||||
except Exception as err:
|
||||
print('Failed to run post hid function: ', err)
|
||||
|
||||
if self._state_changed:
|
||||
if self.state_changed:
|
||||
self._print_debug_cycle()
|
||||
|
Reference in New Issue
Block a user