Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 23 additions & 17 deletions keyberon/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1918,13 +1918,11 @@ impl<'a, const C: usize, const R: usize, T: 'a + Copy + std::fmt::Debug> Layout<
// tap-dance action, would one expect the tap-dance to be repeated or the inner
// action that was most activated within the tap-dance?
//
// Currently the answer to these questions is: what is easy/possible to do? E.g.
// fork and switch are inconsistent with each other even though the actions are
// conceptually very similar. This is because switch can potentially activate
// multiple actions (but not always), so uses the action queue, while fork does
// not. As another example, tap-dance and tap-hold will repeat the inner action and
// not the outer (tap-dance|hold) but multi will repeat the entire outer multi
// action.
// Currently the answer to these questions is: what is easy/possible to do?
// It is not consistent whether it is the outer or inner action.
// The actions tap-dance and tap-hold will repeat the inner action and
// not the outer (tap-dance|hold),
// but multi will repeat the entire outer multi action.
if let Some(ac) = self.rpt_action {
self.do_action(
ac,
Expand Down Expand Up @@ -2374,7 +2372,7 @@ impl<'a, const C: usize, const R: usize, T: 'a + Copy + std::fmt::Debug> Layout<
let historical_keys = self.historical_keys.iter_hevents();
let historical_coords = self.historical_inputs.iter_hevents();
let layers = self.trans_resolution_layer_order().into_iter();
let action_queue = &mut self.action_queue;
let mut action_queue: ActionQueue<T> = Default::default();
for ac in sw.actions(
active_keys,
active_coords,
Expand All @@ -2385,13 +2383,24 @@ impl<'a, const C: usize, const R: usize, T: 'a + Copy + std::fmt::Debug> Layout<
// assertions.
self.default_layer as u16,
) {
action_queue.push_back(Some((coord, 0, ac, layer_stack.collect())));
action_queue.push_back(Some((coord, delay, ac, layer_stack.clone().collect())));
}
// Switch is not properly repeatable. This has to use the action queue for the
// purpose of proper Custom action handling, because a single switch action can
// activate multiple inner actions. But because of the use of the action queue,
// switch has no way to set `rpt_action` after the queue is depleted. I suppose
// that can be fixable, but for now will keep it as-is.

let mut custom = CustomEvent::NoEvent;
while let Some(Some((coord, delay, action, layer_stack))) = action_queue.pop_front()
{
custom.update(self.do_action(
dbg!(action),
coord,
delay,
is_oneshot,
&mut layer_stack.into_iter(),
custom_activation_count,
));
}

self.rpt_action = Some(action);
return custom;
}
}
CustomEvent::NoEvent
Expand Down Expand Up @@ -5020,9 +5029,6 @@ mod test {
assert_keys(&[], layout.keycodes());

layout.event(Press(0, 2));
// No idea why we have to wait 2 ticks here. Is this a bug in switch?
assert_eq!(CustomEvent::NoEvent, layout.tick());
assert_keys(&[], layout.keycodes());
assert_eq!(CustomEvent::NoEvent, layout.tick());
assert_keys(&[B], layout.keycodes());

Expand Down
24 changes: 14 additions & 10 deletions src/kanata/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1230,10 +1230,13 @@ impl Kanata {
cur_keys.extend(layout.keycodes());
let mut reverse_release_order = false;

// Deal with unmodded. Unlike other custom actions, this should come before key presses and
// releases. I don't quite remember why custom actions come after the key processing, but I
// remember that it is intentional. However, since unmodded needs to modify the key lists,
// it should come before.
// Deal with unmodded and other early custom actions.
// Unlike other custom actions, these should come before key presses and releases.
// I don't quite remember why custom actions come after the key processing,
// but I remember that it is intentional.
// However, since unmodded needs to modify the key lists,
// and SequenceNoerase may need to be evaluated within multi before a key
// that completes the sequence, it should come before.
match custom_event {
CustomEvent::Press(custact) => match custact {
CustomAction::Unmodded { keys, mods } => {
Expand All @@ -1243,6 +1246,12 @@ impl Kanata {
CustomAction::Unshifted { keys } => {
self.unshifted_keys.extend(keys.iter());
}
CustomAction::SequenceNoerase(noerase_count) => {
if let Some(state) = self.sequence_state.get_active() {
log::debug!("adding noerase: {noerase_count}");
add_noerase(state, *noerase_count);
}
}
_ => {}
},
CustomEvent::Release(custact) => match custact {
Expand Down Expand Up @@ -1689,12 +1698,7 @@ impl Kanata {
self.sequence_state.activate(*input_mode, *timeout);
}
}
CustomAction::SequenceNoerase(noerase_count) => {
if let Some(state) = self.sequence_state.get_active() {
log::debug!("pressed cancel sequence key");
add_noerase(state, *noerase_count);
}
}
CustomAction::SequenceNoerase(..) => {}
CustomAction::Repeat => {
let keycode = self.last_pressed_key;
let osc: OsCode = keycode.into();
Expand Down
2 changes: 1 addition & 1 deletion src/tests/sim_tests/chord_sim_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ d:t u:t t:10
// The key history should unpause, so on pressing `t` again,
// position 2 is now where bspc is because C was sent.
assert_eq!(
"t:1ms dn:BSpace t:10ms up:BSpace t:10ms dn:C t:1ms up:C t:9ms dn:B t:1ms up:B",
"t:1ms dn:BSpace t:10ms up:BSpace t:9ms dn:C t:1ms up:C t:9ms dn:B t:1ms up:B",
result
);
}
2 changes: 1 addition & 1 deletion src/tests/sim_tests/switch_sim_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,5 @@ fn sim_switch_trans_not_top_layer() {
"d:b t:20 d:a t:10 u:a t:100 d:a t:10 u:a t:100",
)
.to_ascii();
assert_eq!("t:21ms dn:B t:9ms up:B t:101ms dn:B t:9ms up:B", result);
assert_eq!("t:20ms dn:B t:10ms up:B t:100ms dn:B t:10ms up:B", result);
}
Loading