Chrysalis - layout & keyboard settings editor


Appreciate the raw brain dump. Very nicely done. A few of my thoughts:

Layout Editor: How many different layouts can we save? Or none?

Profiles and Devices: Good thinking about plugging in multiple M01s.

LED Theme Editor: Will we have color palettes only? Or a field(s) for RGB/hex? Will there be a mechanism to save a theme and be able to choose a specific one later? Switching? Like say, normal usage/coding/specific game - D3, etc.

Firmware Flasher: Progress bar would be a nice to have (since I’m impatient). Can we have it write to a log file as well? or onscreen diags in verbose, if writing to stdout, then I can live w/o a progress bar.

Great work…

And thanks.


Hey @fishheadsoup, I’m working on the UI side of Chrysalis. It will feature means to import and export layouts as text-files, so you could save as many as you want that way. Having a default folder for layout-files loaded automatically and accessible via a dropdown menu or the like shouldn’t be a problem and is likely a good idea. Does that make sense?


Layouts: one to the keyboard (with limited number of layers, due to EEPROM being only 1k), as many as you like on the host. As @Simon-Claudius said, import/export is something we plan to do, and could be used here too. Or we could just save the extra layouts in the same profile file we save everything else in, and offer a way in the UI to select which one to put on the keyboard.

The palette is necessary, otherwise the theme would not fit in EEPROM, not together with the keymap. For RGB, it would be 3 bytes per color. With a palette, at most one. If we went with RGB, a theme would need 192 bytes, which is one and a half layer. Waaay too much. Right now, it only needs 64 (half a layer), and I’ll be cutting that back to 32 soonish. Plus the palette, of course, because that IS editable.

If there is enough demand, it’s easy to write a plugin for Kaleidoscope that allows using more colors, or even full RGB, at the cost of less layers. Supporting that in Chrysalis should be easy too. But this is not something I plan to do just yet.

The progress bar will depend on the library we use for flashing. If that can provide callbacks we can use to display a progress bar, then yeah, we’ll display one. Otherwise a hourglass or some other indication of work being done will surely be used.

1 Like

One idea I’ve had is using Chrysalis as an aid for learning new layouts.

It could work like this:

  1. I forget a key and hit a few trying to find it,
  2. Give up and press the ‘forgotten key’ key,
  3. That foregrounds Chrysalis with the current layout selected.
  4. Use the ‘train new key’ plugin that invents a key sequence I have to type a few times to background Chrysalis

@algernon: What are we going to call a set of device-specific features, i.e. home screen branding, layout editor GUI, etc?

Not quite sure. In Kaleidoscope, most of these are the Kaleidoscope-Hardware-* plugins. If the homepage, layout editor, etc, could be made so that there is no hardware knowledge hardwired in, but expects a “Hardware” plugin to supply those, that would be grand.

Something like, have a Device singleton object, which the plugins would implicitly depend upon. The object would be supplied by the hardware plugin, and that one would ship the SVGs, home-page branding, and so on. Coupling would be a little tight, because the hardware plugin will have to explicitly support the other plugins. Not sure if that’s the best idea, but it’s the best I see right now.

In the short term, we’ll just hardcode Device to mean the Model01.

Does this sound sane to you?

1 Like

Ideally I’d be able to maintain a branch or fork for the shortcut without too much modification. So happy with hard coding as long as it’s all in one place.

As I’m also working on Shortcut keyboard support I’ve been thinking about this in particular: I mentioned different “distributions” of Chrysalis at some point, e.g. one for the Model 01, one for the Shortcut, etc. that companies/organisations/maintainers would provide in their own fork.

Thinking about it seems neater to have one version that supports all devices and just applies the correct branding and hardware-specific features as the device is detected/selected. This way interested parties would have the option to send us pull requests with their hardware integrations and their hardware would be supported going forward and maintenance requirements for them and us would be kept minimal.

Considering that we’re aiming for a modular structure I think that downloading things as required would be a potential extension of this (similar to what text editors like emacs, Sublime Text and Atom do), i.e. only download/install what’s required.

If this is something that makes sense for us, moving to a hardware-agnostic structure without hardcoding as early as possible would be sensible.

I definitely want to go the route where one distribution can support many devices, because I expect there will be users who have multiple devices running Kaleidoscope, and installing N variants of the same app would be a pain in the backside.

So, yeah - moving the hardware-specific bits to its own place early on is something worth pursuing. The initial device detector could then load the appropriate plugins, and do the dance necessary to set up the Device singleton for the rest of the application.

Initially, the hardware bits could live in the same repo, too, if @matt & @Simon-Claudius find that easier to work with.


Wouldn’t that be the general idea going forward, anyway? Or would you want to split it up somehow?

I’d split it up, like we did with Kaleidoscope too, because that makes it easier to introduce and maintain a new device easier: you don’t have to get the code merged anywhere, which makes it easier to do faster iterations in the beginning, while still not inconveniencing users.

For example, lets say I want to add support for a custom keyboard, nicknamed Twins (for no particular reason at all, no, definitely no reason). This is a custom keyboard no-one else has, and no-one is likely to build one either, let alone mass-produce. For Kaleidoscope, this means I’ll create a Kaleidoscope-Hardware-Twins plugin, that contains the necessary bits. I don’t have to merge it into any master repo, and I can use stubs from day one, for parts that are not implemented yet. It’s convenient to develop, straightforward to work with, and so on. There is also no reason this should be merged anywhere, because this is a one-of-a-kind thing.

Obviously, I’d want Chrysalis to support this keyboard too. For similar reasons (being a one-of-a-kind keyboard), having explicit support for it in the main repo does not make much sense. No-one but me can test it, no-one else is interested in maintaining it. It would just be a burden for everyone else to carry mostly unused code around.

This is why pushing hardware stuff to plugins is sweet. Makes it easier to add and maintain device support. From a user perspective, initially, this may mean some extra work of installing the plugins (though we can do what we for Kaleidoscope with the Arduino-Boards repo, and include some of the hardware bits in a collection of “recommended default set of available plugins”), but later on, we can move towards a way to install plugins on-demand. Along with their dependencies, and so on. (That would be useful for Kaleidoscope too, by the way.)

I hope the intent is clear from this description :slight_smile:


Great. The end goal of this is pretty much what I’d consider idea.

Hey @fishheadsoup, I’m working on the UI side of Chrysalis. It will feature means to import and export layouts as text-files, so you could save as many as you want that way. Having a default folder for layout-files loaded automatically and accessible via a dropdown menu or the like shouldn’t be a problem and is likely a good idea. Does that make sense?

perfect. works for me. thanks.

It could work like this:

I forget a key and hit a few trying to find it,
Give up and press the ‘forgotten key’ key,
That foregrounds Chrysalis with the current layout selected.
Use the ‘train new key’ plugin that invents a key sequence I have to type a few times to background Chrysalis

This is a slick idea.

A short update, until I sum things up in a blog post: a lot of things have been happening around Chrysalis, it can go as far as detecting any number of Kaleidoscope-powered devices, connect to any of them (only one at a time, a limitation that will remain for the foreseeable future), and issue custom commands. This may not seem much, but this is the foundation we can build the rest on. And it is looking sweet.

There are also plans to ship the Chrysalis plugins together with the respective Kaleidoscope plugin, which makes it easier to keep them in sync, provide assets, and so on and so forth.

And while talking plugins: while Chrysalis is not yet set up to use plugins in a convenient way, we can - technically - split plugins out by turning them into NodeJS packages, and adding them as dependencies for Chrysalis. This is what I’ll be going with in the short term, until we figure out a better way. But the plugins being NodeJS packages is something that’ll likely remain so.

In short: lots of low-level, architectural work has been done on Chrysalis in the past week, and we are making very good progress. There is a reasonable chance that we’ll have something usable by the time PVTs ship.

Mind you, the factory firmware will likely not come with all the plugins required for Chrysalis compiled in, so we’ll ship Chrysalis with a custom firmware HEX you can flash on the keyboard. That firmware will behave exactly as the factory one, but will have a number of other plugins enabled. Okay, there may be less LED effects, we’ll see how big it will grow. The goal here is that once you unbox your Model 01, you download Chrysalis, hit a button, hold your PROG key, and have a new firmware flashed. And from that point on, you can use all of Chrysalis’ features.


Another quick update, because I did not get around to write a blog post yet.

I spent the weekend rewriting Chrysalis from JavaScript to ClojureScript (which compiles to JS, but is a language much closer to my heart), which brought a lot of goodies:

Most of the work was done on lower levels, on the architecture of the application, but as you can see from the picture, there are some visible updates too. The palette will be going to be an editable thing in the end, the current display is a placeholder until we get around to doing a palette editor.


Finally managed to put together a blog post, with video & pictures inside :wink:


It’s been a while I posted in this topic, hasn’t it? Chrysalis has been dormant for a long time, even though @james.nvc and @Simon-Claudius improved it quite a bit in my absence. For a number of reasons, a decision was made to rewrite Chrysalis in JavaScript (primarily to lower the barrier of entry), and I just tagged a new release:

I also compiled a short blog post about it:

Which happens to include a video:

It’s different than the previous incarnation of Chrysalis. It doesn’t have a device selector, nor a REPL, nor a wire spy, or a LED editor. It does allow you to edit your keymap however (provided you have an adequately set up firmware; see the release notes), in a not very hostile way.

I’ve successfully used Chrysalis to experiment with a few things on my layout, and it’s been an integral part of my experimenting workflow for a week or so now.


I just tagged another release of Chrysalis, with lots of UI improvements, and even more polishing. It’s still far from being perfect or ready for a beta release, but it’s at a stage where I’d like to ask you all to give it a try, and if possible, provide feedback (bugs you found, things that could be made better, things that were surprising, etc). Any testing and feedback you can provide goes a long way towards a beta - and an eventual 1.0 - release.

To spike your interest, a few screenshots from the 0.0.6 release:

1 Like

Wow, this is really fantastic.

Is the layer drop down at the top right for selecting which layer the keyboard starts with? “Default layer” being in smaller text and below the drop box isn’t triggering my UI brain to naturally understand that.

Keys that I have Qukeys/DualUse modifiers on show up as raw codes. Ex: CTL_T(A) shows as #49173.That’s the biggest impediment to me being able to use this now since I have a lot of them. So one vote for dual use support although that does sound like a lot of work.