Add key repeat support for basic alphanumeric tap dance
This commit is contained in:
parent
b0f8c58828
commit
0c13806f1c
@ -95,30 +95,41 @@ class Firmware:
|
|||||||
print("Firin' lazers. Keyboard is booted.")
|
print("Firin' lazers. Keyboard is booted.")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
update = self.matrix.scan_for_changes()
|
matrix_report = self.matrix.scan_for_changes()
|
||||||
if update is not None:
|
state_changed = False
|
||||||
|
|
||||||
|
if matrix_report is not None:
|
||||||
self._state.matrix_changed(
|
self._state.matrix_changed(
|
||||||
update[0],
|
matrix_report[0],
|
||||||
update[1],
|
matrix_report[1],
|
||||||
update[2],
|
matrix_report[2],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._state.hid_pending:
|
state_changed = True
|
||||||
self._send_hid()
|
|
||||||
|
|
||||||
if self.debug_enabled:
|
if self._state.hid_pending:
|
||||||
print('New State: {}'.format(self._state._to_dict()))
|
self._send_hid()
|
||||||
|
|
||||||
|
old_timeouts_len = len(self._state.timeouts)
|
||||||
self._state.process_timeouts()
|
self._state.process_timeouts()
|
||||||
|
new_timeouts_len = len(self._state.timeouts)
|
||||||
|
|
||||||
|
if old_timeouts_len != new_timeouts_len:
|
||||||
|
state_changed = True
|
||||||
|
|
||||||
for key in self._state.pending_keys:
|
for key in self._state.pending_keys:
|
||||||
self._send_key(key)
|
self._send_key(key)
|
||||||
self._state.pending_key_handled()
|
self._state.pending_key_handled()
|
||||||
|
state_changed = True
|
||||||
|
|
||||||
if self._state.macro_pending:
|
if self._state.macro_pending:
|
||||||
for key in self._state.macro_pending(self):
|
for key in self._state.macro_pending(self):
|
||||||
self._send_key(key)
|
self._send_key(key)
|
||||||
|
|
||||||
self._state.resolve_macro()
|
self._state.resolve_macro()
|
||||||
|
state_changed = True
|
||||||
|
|
||||||
|
if self.debug_enabled and state_changed:
|
||||||
|
print('New State: {}'.format(self._state._to_dict()))
|
||||||
|
|
||||||
gc.collect()
|
gc.collect()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from kmk.consts import LeaderMode
|
from kmk.consts import LeaderMode
|
||||||
from kmk.keycodes import FIRST_KMK_INTERNAL_KEYCODE, Keycodes, RawKeycodes
|
from kmk.keycodes import (FIRST_KMK_INTERNAL_KEYCODE, Keycodes, RawKeycodes,
|
||||||
|
TapDanceKeycode)
|
||||||
from kmk.kmktime import sleep_ms, ticks_diff, ticks_ms
|
from kmk.kmktime import sleep_ms, ticks_diff, ticks_ms
|
||||||
from kmk.util import intify_coordinate
|
from kmk.util import intify_coordinate
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ class InternalState:
|
|||||||
timeouts = {}
|
timeouts = {}
|
||||||
tapping = False
|
tapping = False
|
||||||
tap_dance_counts = {}
|
tap_dance_counts = {}
|
||||||
|
tap_side_effects = {}
|
||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.config = config
|
self.config = config
|
||||||
@ -108,7 +110,7 @@ class InternalState:
|
|||||||
print('No key accessible for col, row: {}, {}'.format(row, col))
|
print('No key accessible for col, row: {}, {}'.format(row, col))
|
||||||
return self
|
return self
|
||||||
|
|
||||||
if self.tapping:
|
if self.tapping and not isinstance(kc_changed, TapDanceKeycode):
|
||||||
self._process_tap_dance(kc_changed, is_pressed)
|
self._process_tap_dance(kc_changed, is_pressed)
|
||||||
else:
|
else:
|
||||||
if is_pressed:
|
if is_pressed:
|
||||||
@ -327,18 +329,7 @@ class InternalState:
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
def _kc_tap_dance(self, changed_key, is_pressed):
|
def _kc_tap_dance(self, changed_key, is_pressed):
|
||||||
if is_pressed:
|
return self._process_tap_dance(changed_key, is_pressed)
|
||||||
self._begin_tap_dance(changed_key)
|
|
||||||
else:
|
|
||||||
self._end_tap_dance()
|
|
||||||
|
|
||||||
return self
|
|
||||||
|
|
||||||
def _begin_tap_dance(self, changed_key):
|
|
||||||
self.tap_dance_counts[changed_key] = 1
|
|
||||||
self.set_timeout(500, self._end_tap_dance)
|
|
||||||
self.tapping = changed_key
|
|
||||||
return self
|
|
||||||
|
|
||||||
def _process_tap_dance(self, changed_key, is_pressed):
|
def _process_tap_dance(self, changed_key, is_pressed):
|
||||||
if is_pressed:
|
if is_pressed:
|
||||||
@ -346,28 +337,47 @@ class InternalState:
|
|||||||
changed_key not in self.tap_dance_counts or
|
changed_key not in self.tap_dance_counts or
|
||||||
not self.tap_dance_counts[changed_key]
|
not self.tap_dance_counts[changed_key]
|
||||||
):
|
):
|
||||||
self._end_tap_dance()
|
self.tap_dance_counts[changed_key] = 1
|
||||||
|
self.set_timeout(500, lambda: self._end_tap_dance(changed_key))
|
||||||
|
self.tapping = True
|
||||||
else:
|
else:
|
||||||
self.tap_dance_counts[changed_key] += 1
|
self.tap_dance_counts[changed_key] += 1
|
||||||
|
|
||||||
if self.tap_dance_counts[changed_key] == len(changed_key.codes):
|
if changed_key not in self.tap_side_effects:
|
||||||
self._end_tap_dance()
|
self.tap_side_effects[changed_key] = None
|
||||||
|
else:
|
||||||
|
if (
|
||||||
|
self.tap_side_effects[changed_key] is not None or
|
||||||
|
self.tap_dance_counts[changed_key] == len(changed_key.codes)
|
||||||
|
):
|
||||||
|
self._end_tap_dance(changed_key)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _end_tap_dance(self):
|
def _end_tap_dance(self, td_key):
|
||||||
k = self.tapping
|
v = self.tap_dance_counts[td_key] - 1
|
||||||
|
|
||||||
if not k:
|
if v >= 0:
|
||||||
# already handled elsewhere?
|
if td_key in self.keys_pressed:
|
||||||
return self
|
key_to_press = td_key.codes[v]
|
||||||
|
self.keys_pressed.add(key_to_press)
|
||||||
|
self.tap_side_effects[td_key] = key_to_press
|
||||||
|
self.hid_pending = True
|
||||||
|
else:
|
||||||
|
if self.tap_side_effects[td_key]:
|
||||||
|
self.keys_pressed.discard(self.tap_side_effects[td_key])
|
||||||
|
self.tap_side_effects[td_key] = None
|
||||||
|
self.hid_pending = True
|
||||||
|
self._cleanup_tap_dance(td_key)
|
||||||
|
else:
|
||||||
|
self.pending_keys.append(td_key.codes[v])
|
||||||
|
self._cleanup_tap_dance(td_key)
|
||||||
|
|
||||||
v = self.tap_dance_counts[k] - 1
|
return self
|
||||||
|
|
||||||
self.pending_keys.append(k.codes[min(v, len(k.codes) - 1)])
|
|
||||||
self.tap_dance_counts[k] = 0
|
|
||||||
self.tapping = False
|
|
||||||
|
|
||||||
|
def _cleanup_tap_dance(self, td_key):
|
||||||
|
self.tap_dance_counts[td_key] = 0
|
||||||
|
self.tapping = any(count > 0 for count in self.tap_dance_counts.values())
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _begin_leader_mode(self):
|
def _begin_leader_mode(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user