Nothing actually changed in layers.md to reflect the subtle layer change
semantics differences introduced by separating shifts from locks on the stack,
but some clarifications would be helpful.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
This (hopefully) makes layer changes more intuitive for users, and more
straightforward to explain and reason about. I believe this is a natural
extension of the activation-order layer stack, and away from the fixed-order
stack of old.
Specifically, it changes things so that layer lock keys will deactivate the
target layer if it is at the top of the active layer stack, but otherwise it
will bring the target layer to the top of the stack, regardless of whether or
not it was previously active. This ought to provide less surprising behaviour
in the case where a layer was active, but hidden (possibly for long enough that
the user can't recall its status). Pressing the layer lock key is now
guaranteed to produce a user-visible change (unless the target layer is 100%
transparent).
Layer shift behaviour is also changed, but not quite in the same way. A layer
shift key will now activate the target layer, as before, but pressing a second
layer shift key for the same target layer won't bring the target layer to the
top of the stack. The idea is that pressing a second identical layer shift
should be interpreted as a continuation of the already-active shift, probably so
that the user can change hands. A user could still forget about a shifted
layer, but it would have to be a sticky OneShot layer shift, so I think this is
reasonable.
The major change is that locked and shifted layers are now tracked separately on
the layer stack (using an offset), which means that locking a layer, then
pressing and releasing a layer shift key for that layer will not result in the
layer being unlocked.
Closes#1009
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
There was a call to `memmove()` call that shifted one extra byte of memory
whenever a layer was deactivated. I don't think that `memmove()` would actually
overwrite the source byte, so it shouldn't have any visible effect, but this is
more correct.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
The new plugin provides a Focus-based interface for setting custom layer names.
The layer names aren't used internally, they're purely for use by host-side
applications.
This addresses the Kaleidoscope-side of keyboardio/Chrysalis#3.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
It was always intended to be public - it is even documented as such! -, but was
mistakenly left private.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of simply echoing "device.reset" into the device port, call
`bin/focus-send`, which sets the `raw` setting on the port, before writing into
it. Without that, the command is not recognised by the firmware.
We could do the stty call in the makefile directly, but to support macOS, we'd
need to treat that specially, and at that point, it's easier to just call
`bin/focus-send`. The sketch relies on having the Kaleidoscope repo available
anyway, so we can safely rely on `bin/focus-send` being there, too.
Because we're now using the tool in the makefiles, `focus-test` was renamed to
`focus-send`.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
A number of devices declared the bootloader in their device properties as
`BootLoader`, while the base class, and anything using it, was looking for
`Bootloader`. This resulted in these devices using the default, dummy
bootloader, rather than the one we intended to set.
This patch corrects that, and everything's using `Bootloader` now, including the
documentation.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This simple plugin does nothing more than provide a `version` focus command,
which will print the firmware version configured at build-time (defaulting to
"0.0.0").
This is a header-only plugin, so that Arduino compiles it in the same
compilation unit as the main sketch, allowing us to set the version from the
sketch, if so desired.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The Model100 has a lot more space available compared to the Model01, so we can
have more layers in EEPROM. While we could have more than 8, 8 is the limit that
OneShot and dual-use keys support via Chrysalis, so to avoid potential
confusion, lets have 8 layers only.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This enables the IdleLEDs, Qukeys, OneShot, Escape-OneShot and DynamicMacros
plugins for the Model100 sketch. None of these - apart from IdleLEDs - cause any
change in behavior unless first configured so.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This new plugin lets us store a default palette and colormap in PROGMEM.
Rather than teaching Colormap to pull from either EEPROM or PROGMEM, this
implements an entirely separate plugin, `DefaultColormap`, which is able
to *push* a palette and colormaps into Colormap.
When `DefaultColormap.setup()` is called, it checks if Colormap's storage area
is empty (both palette and the map must be empty), and if so, copies the
built-in palette and colormap over, and forces a refresh, and it has done its
job.
It does provide an additional Focus command too, `colormap.install`, which will
forcibly copy both palette and colormaps over. Useful for resetting back to a
factory setting.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
To be able to set a theme from the firmware itself, we need a couple of helper
methods. First, we need to be able to update the palette without using Focus,
and we also need to be able to update a single LED without committing it. On top
of that, we'll likely want to know if the theme is initialized.
To this end, we introduce `updatePaletteColor()`, which updates an entry in the
palette, but does not commit it, and `isThemeUninitialized()` which does as the
name suggests: it checks if the palette and the theme slices are all uninitialized.
We also change `updateColorIndexAtPosition()` to not commit. The single user of
it was FingerPainter, and we update that to do an explicit commit after.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This test verifies that PrefixLayer doesn't clear held non-modifier keys from
the report before sending the prefix sequence.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
This new plugin provides a way to set a default (but configurable, via Focus)
led mode, or use a specific one if EEPROM is uninitialized.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This basically reverts 07dcf1dc9b, returning the
plugin to its original behaviour of persisting the current led mode. We do this
because we'll be using a new, different plugin to set the default led mode, to
not conflate the two different functionalities.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
`kaleidoscope::driver::storage::AVREEPROM` wasn't implementing its own
`isSliceUninitialized()` method, and relied on the Base class to do so. However,
since we're not using `virtual` methods, the base class was using
`Base::read()` (which always returns 0) rather than `AVREEPROM::read()`, so
`isSliceUninitialized()` always returned false.
To fix this, we implement the function in `AVREEPROM`, and let the default
implementation in Base always return false.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This plugin provides a shared virtual keys array used by Macros and
DynamicMacros, along with some functions to interact with it (`press()`,
`release()`, `tap()`, `clear()`).
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>