Implement autoshift module

This commit is contained in:
xs5871
2023-04-08 10:01:17 +00:00
parent 62984d34f7
commit d7eb293af8
3 changed files with 183 additions and 0 deletions

View File

@@ -229,6 +229,15 @@ class AbstractHID:
for idx in range(2, len(self._pd_report)):
self._pd_report[idx] = 0x00
def has_key(self, key):
if isinstance(key, ModifierKey):
return bool(self.report_mods[0] & key.code)
else:
for code in self.report_non_mods:
if code == key.code:
return True
return False
class USBHID(AbstractHID):
REPORT_BYTES = 9

83
kmk/modules/autoshift.py Normal file
View File

@@ -0,0 +1,83 @@
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)