#include QMK_KEYBOARD_H #include "keymap_german.h" enum layer_names { _BL, _LOWER, _RAISE, _FUNC, _SHIFT }; enum custom_keycodes { LOWER = SAFE_RANGE, RAISE }; // clang-format off const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // Base Layer (QWERTY logical layout, German OS) // ,-----------------------------------------------------------------------------------. // | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del | // |------+------+------+------+------+------+------+------+------+------+------+------| // | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | // |------+------+------+------+------+-------------+------+------+------+------+------| // | Esc | A | S | D | F | G | H | J | K | L | ; | ' | // |------+------+------+------+------+------|------+------+------+------+------+------| // | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | // |------+------+------+------+------+------+------+------+------+------+------+------| // | Ctrl | GUI | GUI | Alt |Lower | Space |Raise | Left | Down | Up |Right | // `-----------------------------------------------------------------------------------' // [_BL] = LAYOUT( KC_ESC, DE_1, DE_2, DE_3, DE_4, DE_5, DE_6, DE_7, DE_8, DE_9, DE_0, KC_DEL, KC_TAB, DE_Q, DE_W, DE_E, DE_R, DE_T, DE_Y, DE_U, DE_I, DE_O, DE_P, KC_BSPC, KC_ESC, DE_A, DE_S, DE_D, DE_F, DE_G, DE_H, DE_J, DE_K, DE_L, DE_SCLN, DE_QUOT, KC_LSFT, DE_Z, DE_X, DE_C, DE_V, DE_B, DE_N, DE_M, DE_COMM, DE_DOT, DE_SLSH, KC_ENT, KC_LCTL, KC_LGUI, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT ), // Lower // ,-----------------------------------------------------------------------------------. // | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Del | // |------+------+------+------+------+-------------+------+------+------+------+------| // | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp | // |------+------+------+------+------+-------------+------+------+------+------+------| // | Del | | | | | | | _ | + | { | } | | | // |------+------+------+------+------+------|------+------+------+------+------+------| // | | | | | | | | ~ | | | Home | End | | // |------+------+------+------+------+------+------+------+------+------+------+------| // | | | | | | | | Next | Vol- | Vol+ | Play | // `-----------------------------------------------------------------------------------' // [_LOWER] = LAYOUT( DE_TILD, DE_EXLM, DE_AT, DE_HASH, DE_DLR, DE_PERC, DE_CIRC, DE_AMPR, DE_ASTR, DE_LPRN, DE_RPRN, KC_DEL, DE_TILD, DE_EXLM, DE_AT, DE_HASH, DE_DLR, DE_PERC, DE_CIRC, DE_AMPR, DE_ASTR, DE_LPRN, DE_RPRN, KC_BSPC, KC_DEL, _______, _______, _______, _______, _______, _______, DE_UNDS, DE_PLUS, DE_LCBR, DE_RCBR, DE_PIPE, _______, _______, _______, _______, _______, _______, _______, DE_TILD, DE_PIPE, KC_HOME, KC_END, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY ), // Raise // ,-----------------------------------------------------------------------------------. // | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del | // |------+------+------+------+------+------+------+------+------+------+------+------| // | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | // |------+------+------+------+------+-------------+------+------+------+------+------| // | Del | | | | | | | - | = | [ | ] | \ | // |------+------+------+------+------+------|------+------+------+------+------+------| // | | | | | | | | # | / | Pg Up| Pg Dn| | // |------+------+------+------+------+------+------+------+------+------+------+------| // | | | | | | | | Next | Vol- | Vol+ | Play | // `-----------------------------------------------------------------------------------' // [_RAISE] = LAYOUT( DE_GRV, DE_1, DE_2, DE_3, DE_4, DE_5, DE_6, DE_7, DE_8, DE_9, DE_0, KC_DEL, DE_GRV, DE_1, DE_2, DE_3, DE_4, DE_5, DE_6, DE_7, DE_8, DE_9, DE_0, KC_BSPC, KC_DEL, _______, _______, _______, _______, _______, _______, DE_MINS, DE_EQL, DE_LBRC, DE_RBRC, DE_BSLS, _______, _______, _______, _______, _______, _______, _______, DE_HASH, DE_SLSH, KC_PGUP, KC_PGDN, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY ), // Func (Lower + Raise = German characters) // ,-----------------------------------------------------------------------------------. // | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del | // |------+------+------+------+------+------+------+------+------+------+------+------| // | Tab | Q | W | E | R | T | Y | Ü | I | Ö | P | Bksp | // |------+------+------+------+------+-------------+------+------+------+------+------| // | Esc | Ä | ß | D | F | G | H | J | K | L | ; | ' | // |------+------+------+------+------+------|------+------+------+------+------+------| // | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | // |------+------+------+------+------+------+------+------+------+------+------+------| // | Ctrl | GUI | GUI | Alt |Lower | Space |Raise | Left | Down | Up |Right | // `-----------------------------------------------------------------------------------' // [_FUNC] = LAYOUT( KC_ESC, DE_1, DE_2, DE_3, DE_4, DE_5, DE_6, DE_7, DE_8, DE_9, DE_0, KC_DEL, KC_TAB, DE_Q, DE_W, DE_E, DE_R, DE_T, DE_Y, DE_UDIA, DE_I, DE_ODIA, DE_P, KC_BSPC, KC_ESC, DE_ADIA, DE_SS, DE_D, DE_F, DE_G, DE_H, DE_J, DE_K, DE_L, DE_SCLN, DE_QUOT, KC_LSFT, DE_Z, DE_X, DE_C, DE_V, DE_B, DE_N, DE_M, DE_COMM, DE_DOT, DE_SLSH, KC_ENT, KC_LCTL, KC_LGUI, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT ), // Shift (US-style symbol overrides) // // Shift is NOT registered at the OS level. This layer only has entries // for keys where US shifted output differs from German shifted output. // Everything else is transparent and gets Shift added back automatically // in process_record_user. // // ,-----------------------------------------------------------------------------------. // | | | @ | # | | | ^ | & | * | ( | ) | | // |------+------+------+------+------+------+------+------+------+------+------+------| // | | | | | | | | | | | | | // |------+------+------+------+------+-------------+------+------+------+------+------| // | | | | | | | | | | | : | " | // |------+------+------+------+------+------|------+------+------+------+------+------| // | | | | | | | | | < | > | ? | | // |------+------+------+------+------+------+------+------+------+------+------+------| // | | | | | | | | | | | | // `-----------------------------------------------------------------------------------' // [_SHIFT] = LAYOUT( _______, _______, DE_AT, DE_HASH, _______, _______, DE_CIRC, DE_AMPR, DE_ASTR, DE_LPRN, DE_RPRN, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, DE_COLN, DE_DQUO, _______, _______, _______, _______, _______, _______, _______, _______, DE_LABK, DE_RABK, DE_QUES, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ) }; // clang-format on // Check whether a key at a given row/col has an explicit (non-transparent) // entry on the _SHIFT layer. static bool is_shift_layer_key(uint8_t row, uint8_t col) { uint16_t kc = keymaps[_SHIFT][row][col]; return kc != KC_TRNS && kc != KC_NO; } bool process_record_user(uint16_t keycode, keyrecord_t* record) { switch (keycode) { case LOWER: if (record->event.pressed) { layer_on(_LOWER); update_tri_layer(_LOWER, _RAISE, _FUNC); } else { layer_off(_LOWER); update_tri_layer(_LOWER, _RAISE, _FUNC); } return false; case RAISE: if (record->event.pressed) { layer_on(_RAISE); update_tri_layer(_LOWER, _RAISE, _FUNC); } else { layer_off(_RAISE); update_tri_layer(_LOWER, _RAISE, _FUNC); } return false; case KC_LSFT: if (record->event.pressed) { layer_on(_SHIFT); } else { layer_off(_SHIFT); } // Do NOT register shift — we handle it ourselves return false; default: // When _SHIFT layer is active and the key fell through // (transparent on _SHIFT), add Shift so it behaves normally if (IS_LAYER_ON(_SHIFT) && record->event.pressed) { if (!is_shift_layer_key(record->event.key.row, record->event.key.col)) { register_mods(MOD_BIT(KC_LSFT)); tap_code16(keycode); unregister_mods(MOD_BIT(KC_LSFT)); return false; } } break; } return true; }