Custom Layout

The ADM42 is a keyboard that comes with optimized layouts out-of-the-box, allowing for easy selection without the need to reflash the firmware.

However, if your favorite layout is not available, you can easily add your own.

First, pull our repository and ensure you can build and flash the official firmware.

Then, edit keyboards/adm42/v2/keymaps/default/keymap.c

A custom layout entry (_CUSTOM) is already available in the source code. Once you configure it with your preferred layout, you can select it, like other layouts, from the system layer.

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    // Set your custom layout here!
    [_CUSTOM] = LAYOUT_3x12_6(
            LW_GRV,  KC_Q,    KC_D,    KC_R,    KC_W,    KC_B,    KC_J,    KC_F,    KC_U,    KC_P,    KC_SCLN, RW_EQU,
            LC_TAB,  KC_A,    KC_S,    KC_H,    KC_T,    KC_G,    KC_Y,    KC_N,    KC_E,    KC_O,    KC_I,    RC_QUT,
            KC_LALT, KC_Z,    KC_X,    KC_M,    KC_C,    KC_V,    KC_K,    KC_L,    KC_COMM, KC_DOT,  KC_SLSH, LOR_ALT,
                                       LLS_ESC, LS_BPC,  LLA_DEL, LLE_ENT, RS_SPC,  LLS_COMP

If you need to define dual-function keys, please refer to the section below.

Dual-Function Keys

First, check if the dual-function key you need is already defined. These keys are named using a specific nomenclature:

  • L|R: Left|Right
  • W|C|S: Super|Control|Shift
  • Keycode (QMK nomenclature)

For example:

  • LW_GRV ⇒ Left Super / Grave
  • RC_QUT ⇒ Right Control / Quote

If the dual-function key already exists, you can simply reuse it in your custom layout.

Creating a new Dual-Function key

To create a new dual-function key, start by creating a unique keycode following the existings ones in custom_keycodes.

enum custom_keycodes {

Each dual-function key has an entry that describes the key and how it reacts in certain contexts.

typedef struct {
    // Config
    uint16_t mod;
    uint16_t tap;
    bool left; // Physical side on the keyboard, for Opposite MODs as TAP
    bool force_shift; // If true, always tap the tap key with SHIFT
    bool pending_mod; // If true, this mode is allowed to be pending

    // Contexts for immediate tap
    bool context_overlap; // A (tap) key is currently pressed
    bool context_previous; // Another tap has just been done
} modtap;

In the modtaps[] array, add the entry for your keycode at the appropriate position. The keycode should be in the same relative position as it appears in custom_keycodes.

static modtap modtaps[] = {
    // LW_GRV
    {.mod = KC_LWIN, .tap = KC_GRV, .left = true, .context_overlap = true, .context_previous = true},