Skip to content

Defining keyboard layouts

Nick Coutsos edited this page Oct 8, 2023 · 4 revisions

💡 If you're looking for a quick way to visualize layout changes check out the Keymap Layout Tools Helper App

Overview: What is the layout?

Keymap Editor is very much a data-driven application. It is meant to facilitate editing of ZMK keymaps, sourced either locally or in other GitHub repositories, in part by making it easier to select the appropriate behaviours and key codes defined in ZMK itself. In addition to this, it relies on data that defines a visual layout for the keymap you wish to edit. From ZMK's perspective there is simply an array of bindings to process--one for each key available. For this to make sense to you, the user, the editor needs to arrange those keys into something more familiar.

Is your keyboard row-staggered or column-staggered? Unibody or split? Are all keys the same size? Do thumb keys sit at an angle from the rest of the keyboard?

Not all of these details are equally important, but they can help you to navigate the keyboard and assign the correct bindings to the correct keys.

How are layouts defined?

There is currently no layout definition for ZMK-powered keyboard firmware. For the purposes of this project I have defined one based on QMK's info.json which in turn is based on Keyboard Layout Editor's format. QMK's format is a stricter version of the KLE layout format, with extra details relevant to QMK firmware definition/compilation. Most of these details don't apply to the format used here.

Differences from QMK Format

At the top-level only the "layouts" key is required, and in the "layouts" object only one child object is required; the editor will default to choosing the first key, regardless of name.

Aside from this the important part is the Key Dictionary Format. Keymap Editor will look at all of the values defined in that list except for "matrix" and will instead look for "row" and "col" values.

🚨These don't correlate to GPIO pins like the keyboard matrix🚨, but instead define a roughly ortholinear layout of the keys. Regardless of whether your keyboard is row-staggered or column-staggered, this kind of layout makes textual representations easier.

Example

For a simple-ish example of a layout, look at the zmk-config-corne-demo repository. It has a smaller set of keys split into two halves and three main rows, plus a smaller thumb row with a little bit of rotation. In this case the rotation adds very little but it helps to visually match the Corne layout a little better.

Automatic layout generation

If you want to get up and running with the keymap editor without having to do a lot of manual work--firstly I would recommend going to the hosted Keymap Editor and select the Demo Keyboard source. This doesn't require any GitHub repository, local ZMK files, or authentication, and will let you just see what it's like to change keymap/combo/macro definitions.

If you already have a zmk-config repo of your own but no info.json you can try opening it in the app and checking Enable Automatic Layout Parsing in the settings dialog. This will tell the keymap editor to look for the matrix transformation defined for your keyboard and infer a layout from that.

The firmware for the corne keyboard defines a matrix transform with the following map:

		map = <
RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5)  RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10) RC(0,11)
RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5)  RC(1,6) RC(1,7) RC(1,8) RC(1,9) RC(1,10) RC(1,11)
RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5)  RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10) RC(2,11)
                        RC(3,3) RC(3,4) RC(3,5)  RC(3,6) RC(3,7) RC(3,8)
		>;

By comparing the location of each RC(#,#) token we're able to create a layout like the following:

oooooooooooo
oooooooooooo
oooooooooooo
   oooooo

The result is decent. It doesn't capture the different size of the two inner thumb keys, the fact that the other pairs of thumb keys are offset from the finger columns, and the slight sweep of the thumb clusters. It also doesn't capture the fact that the corne is a split keyboard, although given adequate spacing between clusters of keys it will include an extra column if space in the layout.

Not all keyboards work out this well due to technical limitations but this is meant to reduce the barrier of entry and not a permanent solution. Still in this case its enough to get started, and if you save your keymap changes it will produce a layout info.json file that you can further customize. Given enough interest in using this tool for a keyboard I would expect a user or vendor might produce a more accurate layout and share it with the community.