Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to set the default layouts #618

Closed
yulei opened this issue Dec 12, 2019 · 8 comments
Closed

How to set the default layouts #618

yulei opened this issue Dec 12, 2019 · 8 comments
Assignees

Comments

@yulei
Copy link
Contributor

yulei commented Dec 12, 2019

hi there, I pushed several keyboards( noah) to qmk recently, but while using the config.qmk.fm. They don't load the default keymap layouts. Are there specific requirements to setup the default keymap layouts? thanks

@yanfali
Copy link
Collaborator

yanfali commented Dec 12, 2019

@noroadsleft you wanna help out @yulei

@noroadsleft
Copy link
Member

noroadsleft commented Dec 12, 2019

@yulei,

Configurator takes its default keymaps from
https://github.com/qmk/qmk_configurator/tree/master/public/keymaps

As you can see, the files are JSON format. As much as possible, I try to keep these such that they behave the same as running make <keyboard>:default from qmk_firmware.

Here's what the JSON keymap for the Matrix 8XV1.2 OG would look like:

{
  "keyboard": "matrix/m12og",
  "keymap": "default_8551ab3",
  "commit": "8551ab3daf97e62f7b679ed7d8042141300566e3",
  "layout": "LAYOUT_tkl_ansi",
  "layers": [
    [
      "KC_ESC",             "KC_F1",   "KC_F2",   "KC_F3",   "KC_F4",   "KC_F5",   "KC_F6",   "KC_F7",   "KC_F8",   "KC_F9",   "KC_F10",  "KC_F11",  "KC_F12",     "KC_PSCR", "KC_SLCK", "LT(1,KC_PAUS)",
      "KC_GRV",  "KC_1",    "KC_2",    "KC_3",    "KC_4",    "KC_5",    "KC_6",    "KC_7",    "KC_8",    "KC_9",    "KC_0",    "KC_MINS", "KC_EQL",  "KC_BSPC",    "KC_INS",  "KC_HOME", "KC_PGUP",
      "KC_TAB",  "KC_Q",    "KC_W",    "KC_E",    "KC_R",    "KC_T",    "KC_Y",    "KC_U",    "KC_I",    "KC_O",    "KC_P",    "KC_LBRC", "KC_RBRC", "KC_BSLS",    "KC_DEL",  "KC_END",  "KC_PGDN",
      "KC_CAPS", "KC_A",    "KC_S",    "KC_D",    "KC_F",    "KC_G",    "KC_H",    "KC_J",    "KC_K",    "KC_L",    "KC_SCLN", "KC_QUOT",            "KC_ENT",
      "KC_LSFT",            "KC_Z",    "KC_X",    "KC_C",    "KC_V",    "KC_B",    "KC_N",    "KC_M",    "KC_COMM", "KC_DOT",  "KC_SLSH",            "KC_RSFT",               "KC_UP",
      "KC_LCTL", "KC_LGUI", "KC_LALT",                                       "KC_SPC",                                         "KC_RALT", "MO(1)",   "KC_RCTL",    "KC_LEFT", "KC_DOWN", "KC_RGHT"
    ],
    [
      "KC_MUTE",            "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",    "KC_TRNS", "KC_TRNS", "KC_TRNS",
      "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",    "KC_TRNS", "KC_TRNS", "KC_TRNS",
      "KC_NLCK", "RGB_TOG", "RGB_MOD", "RGB_HUI", "RGB_HUD", "RGB_SAI", "RGB_SAD", "RGB_VAI", "RGB_VAD", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",    "KC_TRNS", "KC_TRNS", "KC_TRNS",
      "RESET",   "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",            "KC_TRNS",
      "KC_TRNS",            "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",            "KC_TRNS",               "KC_VOLU",
      "KC_TRNS", "KC_TRNS", "KC_TRNS",                                       "KC_MPLY",                                        "KC_TRNS", "KC_TRNS", "KC_TRNS",    "KC_MPRV", "KC_VOLD", "KC_MNXT"
    ]
  ]
}

keyboard and keymap are the keyboard and keymap names, respectively, same as you'd pass to make.
commit is an optional key that I use for internal tracking. Configurator ignores it, but it helps me a great deal to have it present.
layout is the name of the layout macro used by the default keymap
layers is an array representing the keycodes for each layer. The white space doesn't matter here, but I like to make these easy for humans to read.

There are a couple of caveats and esoteric issues with JSON keymaps:

You can't use default as the value for the keymap key

Configurator's API knows the keymap.c files in qmk_firmware exist, even though it can't use them. When you run a compile task in Configurator, the keymap data gets HTTP POSTed to an API endpoint that converts the submitted JSON to a keymap.c file. As part of this process, the API, working from a cloned qmk_firmware repo, attempts to create keyboards/<keyboard>/keymaps/<keymap_name>/keymap.c in that repo, but because it's a cloned repo, that file already exists, and the API errors out and the user is never presented with a firmware file to flash.

To get around this, I append a partial commit hash to the keymap name. It doesn't really matter what you append to the keymap name; I arbitrarily decided on partial commit hashes and that works for me. In fact, I've grown to prefer it.

You'll notice that the text appended to the keymap name is the first seven characters of the commit key. This JSON key is optional, but I use it for internal tracking. It's the SHA of the last commit to modify a board's default keymap.c in qmk_firmware. I get this by running git log -1 master -- keyboards/<keyboard>/keymaps/default/keymap.c on my local clone of qmk_firmware (on which I check for updates several times a day).

Configurator's UI code only understand one variant of each supported keycode

For the most part, Configurator uses the short-form keycodes internally, and doesn't understand the full-length codes, even though they do work. If you were to use KC_RIGHT in a JSON file, it won't render the same as the short-form KC_RGHT, though the end result of the compile task is the same. Here's a non-exhaustive list of codes I can think of to watch for here:

Do Not Use: Instead Use:
KC_LCTRL KC_LCTL
KC_RCTRL KC_RCTL
KC_LSHIFT KC_LSFT
KC_RSHIFT KC_RSFT
KC_RIGHT KC_RGHT
_______ KC_TRNS
XXXXXXX KC_NO

If you submit a PR for a new or modified keymap, I'll check it and advise if I'd like changes for these sorts of keycodes.

Layers can only be mentioned by number

A common QMK convention is to name layers with something like:

enum layer_names {
    _BASE,
    _MEDIA,
    _FN
};

This works in C, but for Configurator, you must use the layer's numeric index – MO(_FN) would need to be MO(2) in the above example.

No support for custom code of any kind

Features that require adding functions to the keymap.c file, such as Tap Dance or Unicode, can't be compiled in Configurator at all. Even setting TAP_DANCE_ENABLE = yes in qmk_firmware at the keyboard level will prevent Configurator from compiling any firmware for that keyboard. This is limited both by the API and the current spec of our JSON keymap format.

Custom keycodes are "unsupported"

I say "unsupported" in quotes because there is a way around this: If the logic for a custom keycode is implemented at the keyboard level instead of the keymap level in qmk_firmware, that keycode can be used in Configurator and it will compile and work. (I need to document how to do this at some point.)


This may have been more than you cared to know at this point, but feel free to ask me any questions regarding JSON keymaps.

Configurator can't compile Matrix Noah firmware at this time; it fails with the following error:

Compiling: lib/chibios/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c                                  lib/chibios/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c: In function 'i2c_lld_serve_event_interrupt':
lib/chibios/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c:934:14: error: macro "qEvt" requires 2 arguments, but only 1 given
   qEvt(0x0000);
              ^
lib/chibios/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c:934:3: error: 'qEvt' undeclared (first use in this function)
   qEvt(0x0000);
   ^~~~
lib/chibios/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c:934:3: note: each undeclared identifier is reported only once for each function it appears in
lib/chibios/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c:137:19: error: large integer implicitly truncated to unsigned type [-Werror=overflow]
   i2cQ=(info); }
                   ^
lib/chibios/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c:938:1: note: in expansion of macro 'qEvt'
 qEvt(0x9999,0);
 ^~~~
cc1: all warnings being treated as errors
 [ERRORS]  
 | 
 | 
 | 
tmk_core/rules.mk:377: recipe for target '.build/obj_matrix_noah/lib/chibios/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.o' failed
make32/LLD/I2Cv1/hal_i2c_lld.o] Error 1
Makefile:560: recipe for target 'matrix/noah:default_265c415' failed
make: *** atrix/noah:default_265c415] Error 1
Make finished with errors

Sadly I'm not a C programmer (or any kind of programmer), so I can't tell you why this happens. In short, I won't be adding any default keymap for the Noah at this time.

The 8XV1.2 does work, however, so here, have a pull request:

@yulei
Copy link
Contributor Author

yulei commented Dec 13, 2019

thanks for the detailed explanation. Yes noah can't compile with the current qmk configurator. It should caused by the back end system. I fired an issue here but not sure whether it was the right place.

And about the current implementation of the keymap compiling process, could we introduced a extra layer to abstract the keymap<->keyboard matrix mapping (something like the unimap implementation of the tmk). An standard keyboard(key matrix) was used as an intermediate layer, the keyboard maker maintains the mapping from keymap to the standard keyboard and from the standard keyboard to custom key matrix, thus one info.json can be used for the keyboard layout rendering and keymap compilations at same time.

@noroadsleft
Copy link
Member

We've talked about doing just that, but that requires the API gaining additional functionality, and there's not much movement happening on the API because we simply don't have the labor and expertise to push it forward at this time. skullydazed developed the API entirely on his own and there's not anyone else who knows it well enough. We've simply outgrown it.

@vosechu
Copy link

vosechu commented Jan 27, 2020

@yulei That is such a helpful post! Can we get this added to the readme or the wiki?

@vosechu
Copy link

vosechu commented Jan 27, 2020

er, @noroadsleft wrote it. Sorry.

@noroadsleft
Copy link
Member

@vosechu I've been meaning to put this on the QMK Firmware docs for some time; internally we've been talking about restructuring the docs for some time, but there are other projects that have needed more attention.

@fauxpark
Copy link
Member

Closing for inactivity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants