fix combo buffer replay /w layer-switch
This commit is contained in:
parent
4419f13f1c
commit
62ff7c838d
@ -85,11 +85,11 @@ class Combos(Module):
|
|||||||
|
|
||||||
def process_key(self, keyboard, key, is_pressed, int_coord):
|
def process_key(self, keyboard, key, is_pressed, int_coord):
|
||||||
if is_pressed:
|
if is_pressed:
|
||||||
return self.on_press(keyboard, key)
|
return self.on_press(keyboard, key, int_coord)
|
||||||
else:
|
else:
|
||||||
return self.on_release(keyboard, key)
|
return self.on_release(keyboard, key, int_coord)
|
||||||
|
|
||||||
def on_press(self, keyboard, key):
|
def on_press(self, keyboard, key, int_coord):
|
||||||
# refill potential matches from timed-out matches
|
# refill potential matches from timed-out matches
|
||||||
if not self._matching:
|
if not self._matching:
|
||||||
self._matching = list(self._reset)
|
self._matching = list(self._reset)
|
||||||
@ -108,7 +108,7 @@ class Combos(Module):
|
|||||||
|
|
||||||
if self._matching:
|
if self._matching:
|
||||||
# At least one combo matches current key: append key to buffer.
|
# At least one combo matches current key: append key to buffer.
|
||||||
self._key_buffer.append((key, True))
|
self._key_buffer.append((int_coord, key, True))
|
||||||
key = None
|
key = None
|
||||||
|
|
||||||
# Start or reset individual combo timeouts.
|
# Start or reset individual combo timeouts.
|
||||||
@ -125,10 +125,11 @@ class Combos(Module):
|
|||||||
# There's no matching combo: send and reset key buffer
|
# There's no matching combo: send and reset key buffer
|
||||||
self.send_key_buffer(keyboard)
|
self.send_key_buffer(keyboard)
|
||||||
self._key_buffer = []
|
self._key_buffer = []
|
||||||
|
key = keyboard._find_key_in_map(int_coord)
|
||||||
|
|
||||||
return key
|
return key
|
||||||
|
|
||||||
def on_release(self, keyboard, key):
|
def on_release(self, keyboard, key, int_coord):
|
||||||
for combo in self._active:
|
for combo in self._active:
|
||||||
if key in combo.match:
|
if key in combo.match:
|
||||||
# Deactivate combo if it matches current key.
|
# Deactivate combo if it matches current key.
|
||||||
@ -140,10 +141,10 @@ class Combos(Module):
|
|||||||
# Don't propagate key-release events for keys that have been buffered.
|
# Don't propagate key-release events for keys that have been buffered.
|
||||||
# Append release events only if corresponding press is in buffer.
|
# Append release events only if corresponding press is in buffer.
|
||||||
else:
|
else:
|
||||||
pressed = self._key_buffer.count((key, True))
|
pressed = self._key_buffer.count((int_coord, key, True))
|
||||||
released = self._key_buffer.count((key, False))
|
released = self._key_buffer.count((int_coord, key, False))
|
||||||
if (pressed - released) > 0:
|
if (pressed - released) > 0:
|
||||||
self._key_buffer.append((key, False))
|
self._key_buffer.append((int_coord, key, False))
|
||||||
key = None
|
key = None
|
||||||
|
|
||||||
return key
|
return key
|
||||||
@ -156,7 +157,7 @@ class Combos(Module):
|
|||||||
|
|
||||||
if not combo._remaining:
|
if not combo._remaining:
|
||||||
self.activate(keyboard, combo)
|
self.activate(keyboard, combo)
|
||||||
if any([not pressed for (key, pressed) in self._key_buffer]):
|
if any([not pressed for (int_coord, key, pressed) in self._key_buffer]):
|
||||||
# At least one of the combo keys has already been released:
|
# At least one of the combo keys has already been released:
|
||||||
# "tap" the combo result.
|
# "tap" the combo result.
|
||||||
keyboard._send_hid()
|
keyboard._send_hid()
|
||||||
@ -171,8 +172,17 @@ class Combos(Module):
|
|||||||
self.reset_combo(keyboard, combo)
|
self.reset_combo(keyboard, combo)
|
||||||
|
|
||||||
def send_key_buffer(self, keyboard):
|
def send_key_buffer(self, keyboard):
|
||||||
for (key, is_pressed) in self._key_buffer:
|
for (int_coord, key, is_pressed) in self._key_buffer:
|
||||||
keyboard.process_key(key, is_pressed)
|
try:
|
||||||
|
new_key = keyboard._coordkeys_pressed[int_coord]
|
||||||
|
except KeyError:
|
||||||
|
new_key = None
|
||||||
|
if new_key is None:
|
||||||
|
new_key = keyboard._find_key_in_map(int_coord)
|
||||||
|
|
||||||
|
keyboard._coordkeys_pressed[int_coord] = new_key
|
||||||
|
|
||||||
|
keyboard.process_key(new_key, is_pressed)
|
||||||
keyboard._send_hid()
|
keyboard._send_hid()
|
||||||
|
|
||||||
def activate(self, keyboard, combo):
|
def activate(self, keyboard, combo):
|
||||||
|
@ -2,16 +2,20 @@ import unittest
|
|||||||
|
|
||||||
from kmk.keys import KC
|
from kmk.keys import KC
|
||||||
from kmk.modules.combos import Chord, Combos, Sequence
|
from kmk.modules.combos import Chord, Combos, Sequence
|
||||||
|
from kmk.modules.layers import Layers
|
||||||
from tests.keyboard_test import KeyboardTest
|
from tests.keyboard_test import KeyboardTest
|
||||||
|
|
||||||
|
|
||||||
class TestCombo(unittest.TestCase):
|
class TestCombo(unittest.TestCase):
|
||||||
def test_basic_kmk_keyboard(self):
|
def test_basic_kmk_keyboard(self):
|
||||||
combos = Combos()
|
combos = Combos()
|
||||||
|
layers = Layers()
|
||||||
|
KCMO = KC.MO(1)
|
||||||
combos.combos = [
|
combos.combos = [
|
||||||
Chord((KC.A, KC.B, KC.C), KC.Y),
|
Chord((KC.A, KC.B, KC.C), KC.Y),
|
||||||
Chord((KC.A, KC.B), KC.X),
|
Chord((KC.A, KC.B), KC.X),
|
||||||
Chord((KC.C, KC.D), KC.Z, timeout=80),
|
Chord((KC.C, KC.D), KC.Z, timeout=80),
|
||||||
|
Chord((KC.C, KCMO), KC.Z),
|
||||||
Sequence((KC.N1, KC.N2, KC.N3), KC.Y, timeout=50),
|
Sequence((KC.N1, KC.N2, KC.N3), KC.Y, timeout=50),
|
||||||
Sequence((KC.N1, KC.N2), KC.X, timeout=50),
|
Sequence((KC.N1, KC.N2), KC.X, timeout=50),
|
||||||
Sequence((KC.N3, KC.N4), KC.Z, timeout=100),
|
Sequence((KC.N3, KC.N4), KC.Z, timeout=100),
|
||||||
@ -19,9 +23,9 @@ class TestCombo(unittest.TestCase):
|
|||||||
Sequence((KC.LEADER, KC.N1), KC.V, timeout=50),
|
Sequence((KC.LEADER, KC.N1), KC.V, timeout=50),
|
||||||
]
|
]
|
||||||
keyboard = KeyboardTest(
|
keyboard = KeyboardTest(
|
||||||
[combos],
|
[combos, layers],
|
||||||
[
|
[
|
||||||
[KC.A, KC.B, KC.C, KC.D, KC.E, KC.F],
|
[KC.A, KC.B, KC.C, KC.D, KC.E, KCMO],
|
||||||
[KC.N1, KC.N2, KC.N3, KC.N4, KC.N5, KC.LEADER],
|
[KC.N1, KC.N2, KC.N3, KC.N4, KC.N5, KC.LEADER],
|
||||||
],
|
],
|
||||||
debug_enabled=False,
|
debug_enabled=False,
|
||||||
@ -303,6 +307,32 @@ class TestCombo(unittest.TestCase):
|
|||||||
[{KC.A}, {KC.A, KC.E}, {KC.A, KC.B, KC.E}, {KC.B, KC.E}, {KC.E}, {}],
|
[{KC.A}, {KC.A, KC.E}, {KC.A, KC.B, KC.E}, {KC.B, KC.E}, {KC.E}, {}],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# test combos with layer switch
|
||||||
|
keyboard.test(
|
||||||
|
'match: Combo containing layer switch, within timeout',
|
||||||
|
[
|
||||||
|
(5, True),
|
||||||
|
(2, True),
|
||||||
|
t_within,
|
||||||
|
(2, False),
|
||||||
|
(5, False),
|
||||||
|
t_after,
|
||||||
|
],
|
||||||
|
[{KC.Z}, {}],
|
||||||
|
)
|
||||||
|
|
||||||
|
keyboard.test(
|
||||||
|
'no match: Combo containing layer switch + other, within timeout',
|
||||||
|
[
|
||||||
|
(5, True),
|
||||||
|
(0, True),
|
||||||
|
(0, False),
|
||||||
|
(5, False),
|
||||||
|
t_after,
|
||||||
|
],
|
||||||
|
[{KC.N1}, {}],
|
||||||
|
)
|
||||||
|
|
||||||
# test sequences
|
# test sequences
|
||||||
keyboard.keyboard.active_layers = [1]
|
keyboard.keyboard.active_layers = [1]
|
||||||
keyboard.test(
|
keyboard.test(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user