Fix layer tap interrupted

This commit is contained in:
xs5871 2023-03-13 22:14:49 +00:00 committed by xs5871
parent 878fe0deca
commit 26bf630608
6 changed files with 38 additions and 9 deletions

View File

@ -197,7 +197,7 @@ class KMKKeyboard:
key = ksf.key key = ksf.key
# Handle any unaccounted-for layer shifts by looking up the key resolution again. # Handle any unaccounted-for layer shifts by looking up the key resolution again.
if ksf.int_coord in self._coordkeys_pressed.keys(): if ksf.int_coord is not None:
key = self._find_key_in_map(ksf.int_coord) key = self._find_key_in_map(ksf.int_coord)
# Resume the processing of the key event and update the HID report # Resume the processing of the key event and update the HID report

View File

@ -83,6 +83,11 @@ class HoldTap(Module):
if state.activated != ActivationType.PRESSED: if state.activated != ActivationType.PRESSED:
continue continue
# holdtap isn't interruptable, resolves on ht_release or timeout.
if not key.meta.tap_interrupted and not key.meta.prefer_hold:
append_buffer = True
continue
# holdtap is interrupted by another key event. # holdtap is interrupted by another key event.
if (is_pressed and not key.meta.tap_interrupted) or ( if (is_pressed and not key.meta.tap_interrupted) or (
not is_pressed and key.meta.tap_interrupted and self.key_buffer not is_pressed and key.meta.tap_interrupted and self.key_buffer

View File

@ -53,7 +53,7 @@ class OneShot(HoldTap):
elif state.activated == ActivationType.INTERRUPTED: elif state.activated == ActivationType.INTERRUPTED:
if is_pressed: if is_pressed:
send_buffer = True send_buffer = True
self.key_buffer.insert(0, (0, key, False)) self.key_buffer.insert(0, (None, key, False))
if send_buffer: if send_buffer:
self.key_buffer.append((int_coord, current_key, is_pressed)) self.key_buffer.append((int_coord, current_key, is_pressed))

View File

@ -17,7 +17,7 @@ class TapDanceKeyMeta:
ht_key = KC.HT( ht_key = KC.HT(
tap=key, tap=key,
hold=key, hold=key,
prefer_hold=False, prefer_hold=True,
tap_interrupted=False, tap_interrupted=False,
tap_time=self.tap_time, tap_time=self.tap_time,
) )

View File

@ -11,8 +11,8 @@ class TestHoldTap(unittest.TestCase):
KC.clear() KC.clear()
self.t_within = 2 * KeyboardTest.loop_delay_ms self.t_within = 2 * KeyboardTest.loop_delay_ms
self.t_after = 5 * KeyboardTest.loop_delay_ms self.t_after = 6 * KeyboardTest.loop_delay_ms
tap_time = (self.t_after + self.t_within) // 2 tap_time = 5 * KeyboardTest.loop_delay_ms
# overide default timeouts # overide default timeouts
HoldTap.tap_time = tap_time HoldTap.tap_time = tap_time
@ -91,13 +91,13 @@ class TestHoldTap(unittest.TestCase):
keyboard.test( keyboard.test(
'LT within tap time rolling -> tap behavior', 'LT within tap time rolling -> tap behavior',
[(1, True), t_within, (3, True), t_after, (1, False), (3, False)], [(1, True), t_within, (3, True), (1, False), (3, False)],
[{KC.B}, {KC.B, KC.D}, {KC.D}, {}], [{KC.B}, {KC.B, KC.D}, {KC.D}, {}],
) )
keyboard.test( keyboard.test(
'LT within tap time nested -> tap behavior', 'LT within tap time nested -> tap behavior',
[(1, True), t_within, (3, True), (3, False), t_after, (1, False)], [(1, True), t_within, (3, True), (3, False), (1, False)],
[{KC.B}, {KC.B, KC.D}, {KC.B}, {}], [{KC.B}, {KC.B, KC.D}, {KC.B}, {}],
) )

View File

@ -10,8 +10,13 @@ class TestLayers(unittest.TestCase):
self.kb = KeyboardTest( self.kb = KeyboardTest(
[Layers()], [Layers()],
[ [
[KC.N0, KC.LM(1, KC.LCTL)], [
[KC.A, KC.B], KC.N0,
KC.LM(1, KC.LCTL),
KC.LT(1, KC.N2, tap_interrupted=True, prefer_hold=True),
KC.LT(1, KC.N3, tap_interrupted=False, prefer_hold=True),
],
[KC.A, KC.B, KC.C, KC.D],
], ],
debug_enabled=False, debug_enabled=False,
) )
@ -23,6 +28,25 @@ class TestLayers(unittest.TestCase):
[{KC.LCTL}, {KC.LCTL, KC.A}, {KC.A}, {}], [{KC.LCTL}, {KC.LCTL, KC.A}, {KC.A}, {}],
) )
def test_layertap(self):
self.kb.test(
'Layertap roll',
[(2, True), (0, True), (2, False), (0, False)],
[{KC.N2}, {KC.N0, KC.N2}, {KC.N0}, {}],
)
self.kb.test(
'Layertap tap interrupted',
[(2, True), (0, True), 200, (0, False), (2, False)],
[{KC.A}, {}],
)
self.kb.test(
'Layertap tap interrupted by holdtap',
[(3, True), (2, True), (2, False), (3, False)],
[{KC.C}, {}],
)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()