kmk_firmware/kmk/modules/autoshift.py
2023-04-09 22:36:25 +00:00

84 lines
2.3 KiB
Python

from kmk.keys import KC, Key
from kmk.modules import Module
from kmk.scheduler import cancel_task, create_task
from kmk.utils import Debug
debug = Debug(__name__)
class Autoshift(Module):
def __init__(self, tap_time=300):
self.tap_time = tap_time
self._active = False
self._task = None
self._key = None
def during_bootup(self, keyboard):
self._task = create_task(lambda: self._shift(keyboard), after_ms=-1)
def before_matrix_scan(self, keyboard):
pass
def after_matrix_scan(self, keyboard):
pass
def process_key(self, keyboard, key, is_pressed, int_coord):
# Unshift on any key event
if self._active:
self._unshift(keyboard)
return key
# Only shift from an unshifted state
if keyboard._hid_helper.has_key(KC.LSHIFT):
return key
# Ignore rolls from tapped to hold
if not is_pressed and key is not self._key:
return key
# Only shift alpha keys, iff there's no pending potential shift
if (
is_pressed
and not self._key
and isinstance(key, Key)
and key.code
and KC.A.code <= key.code <= KC.Z.code
):
create_task(self._task, after_ms=self.tap_time)
self._key = key
else:
cancel_task(self._task)
keyboard.resume_process_key(self, self._key, True)
if key is self._key:
keyboard.resume_process_key(self, self._key, False)
else:
keyboard.resume_process_key(self, key, True)
self._key = None
def before_hid_send(self, keyboard):
pass
def after_hid_send(self, keyboard):
pass
def on_powersave_enable(self, keyboard):
pass
def on_powersave_disable(self, keyboard):
pass
def _shift(self, keyboard):
if debug.enabled:
debug('activate')
self._active = True
keyboard.keys_pressed.add(KC.LSFT)
keyboard.resume_process_key(self, self._key, True)
def _unshift(self, keyboard):
if debug.enabled:
debug('deactivate')
self._active = False
self._key = None
keyboard.keys_pressed.remove(KC.LSFT)