While the original plugin was written independently, significant developments
were made while working for Keyboard.io. As such, I feel it is appropriate to
assign copyright to the company.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
If we do not clear `should_cancel_` there, it remains set indefinitely (until it
gets unset for some other reason, like interrupting a non-sticky OneShot). If it
is set, we can't enter sticky mode.
So clear it when canceling stickiness with a third tap, just like we clear it in
`afterEachCycle`.
Fixes#34.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The default `onSetup` will call `.begin`, to support initializing plugins using
the V1 plugins while using `KALEIDOSCOPE_INIT_PLUGINS`. However, plugins that
implement a compatibility layer so that they can be used with both the new API,
and with `Kaleidoscope.use()` will have a `.begin` method too. Which the default
`onSetup` will call, and we'll register the compatibility layer too, in addition
to the new-style event handlers. This results in many things running twice,
which leads to all kinds of problems.
For this reason, override `onSetup`, so that it does not call `begin`. When used
with `Kaleidoscope.use()`, the plugin will still work, so compatibility is
maintained. But the bug is now gone.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Sometimes one wants a longer timeout, also wants the sticky behaviour on
double-tap, but would like to use a shorter timeout for the sticky behaviour.
The new `double_tap_timeout` property accomplishes just this.
Defaults to using `time_out`, for backwards compatibility.
Fixes#30.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
When we activate a OneShot key, use the coordinates of the (last) physical key
that triggered it. This is done by keeping an array of positions for each
possible OneShot key. While this costs us 16 bytes of RAM and a bit of code, the
benefit is that plugins ordered after OneShot will know where OneShot was
triggered from.
Fixes#13.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
When clearing a sticky, also cancel the OneShot state, and clear the pressed
bits too.
Thanks to @glasser for experimenting and coming up with the full fix.
Fixes#17.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
If a one-shot key is held, or is sticky, then we do not care about the timeout.
The `isActive()` method was adjusted to do so.
Signed-off-by: Gergely Nagy <kaleidoscope@gergo.csillger.hu>
The `OneShot.isActive(key)` method was returning true even if a key timed out,
when `OneShot.isActive()` already returned false. It now takes the timeout into
consideration too.
Signed-off-by: Gergely Nagy <kaleidoscope@gergo.csillger.hu>
We want to phase out `event_handler_hook_use` and `loop_hook_use`, so use the
new methods instead.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
If we do not turn `should_cancel_` off, the next time one taps a one-shot key,
the flag will still be on (because nothing else turned it off, and it was set
before `hold_time_out_` happened, because the normal one-shot timeout is shorter
than that). If the flag is on, the loop hook will turn any and all one-shot
effects off.
In practice, this resulted in one-shot keys not working properly if they were
held for a longer period before.
Fixes#12, with many thanks to @ToyKeeper for finding and reporting the issue
with reproduction steps.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
When we hold the OSL key, we do not need to mask out interruptors, because they
are not going to interrupt. As such, flip the `should_mask_on_interrupt_` bit on
OSL key release.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
Instead of computing the one-shot index when it is needed, compute it once at
the beginning. Even if we don't use it, we still save a few bytes by not
computing it in two branches.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
The goal is to have one-shot modified symbols repeat (without modifier) when
held, but mask out one-shot layer interrupting keys, similar to how momentary
layers are masked out.
This fixes#11.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
We do not need to check if the key we received is masked - the core event
handler does that for us, and we won't even see masked keys. This saves us a few
bytes of code.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
When holding a one-shot key and tapping another that would cancel the one-shot
effect, when we release the one-shot key within `hold_time_out`, do not start
the oneshot effect.
This is done by only clearing the `should_cancel_` flag in `loopHook` when
cancellation did happen. If we clear anyway, then the flag set by the
interrupting keypress will be lost by the time we release the one-shot key.
Reported by @ToyKeeper, thanks a lot for the detailed explanation!
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
Now that we have key masking functionality provided by KeyboardHardware, use
that instead of going with our own.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
To make it easier in the future to increase the amount of one-shot
layers available, use a union+struct combo, that allows scaling between
16 and 32 bits. This way we won't have to use all 32 bits, and can make
do with 24 only, still saving us almost a hundred bytes.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
Instead of supporting up to 24 one-shot layers, support only 8. This
allows us to fit all state in 16 bits, down from 32, saving us almost
200 bytes of program memory.
Partially addresses #8.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
There are - or will be - better ways to experiment, drop these, lest
anyone starts depending on them.
Fixes#7.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
Loop counter depends on the speed of the loop, timers don't. As such, timers are
much more reliable, even at the cost of using more data space.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
When a key interrupts the one-shot, mask the position out until a key release.
This is needed, because even a short tap usually results in a short hold, which
in turn - without the mask - handles the key.
Instead, we now mask the position out until it is released, so no such problems
arise. Fixes#4.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
We want to treat the one-shot keys as active even when they were interrupted -
as long as their state is not cleared. This is because when using isActive from
another plugin, or macro, that is usually in response to a key press that
already sets up `shouldCancel` - yet, the modifier is technically active still!
So `isActive` does not check the to-be-cancelled flag anymore. This makes the
Escape-OneShot plugin much more reliable as a consequence.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
Useful when writing an event handler that needs to check if a modifier is
active, but may run before OneShot has a chance to re-register the given
modifier.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
When another one-shot key is pressed, reset the timer, and handle it as if
starting anew, but without cancelling any previous one-shots. This allows one to
chain one-shots together.
Fixes#3.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>