~ruther/qmk_firmware

e95c1e3f2c5137b114aa947f875c52e4a5c74b5d — Nathan Johnson 8 years ago a9df99b
Adding whiskey_tango_foxtrot_capslock ergodox keymap
A keyboards/ergodox/keymaps/osx_whiskey_tango_foxtrot_capslock/keymap.c => keyboards/ergodox/keymaps/osx_whiskey_tango_foxtrot_capslock/keymap.c +231 -0
@@ 0,0 1,231 @@
/*
 * This is built out of frustration with OSX / Sierra caps lock delay.
 * Fake it till you make it!
 */

#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "timer.h"

#define BASE 0 // default layer
#define SYMB 1 // symbols
#define MDIA 2 // media keys

#define BLINK_BASE  150U // timer threshold for blinking on MDIA layer

typedef enum onoff_t {OFF, ON} onoff;

#define caps_led_on  ergodox_right_led_2_on
#define caps_led_off ergodox_right_led_2_off

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
 *
 * ,--------------------------------------------------.           ,--------------------------------------------------.
 * | Esc    |   1  |   2  |   3  |   4  |   5  |   6  |           |   `  |   7  |   8  |   9  |   0  |   -  |   =    |
 * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
 * | Tab    |   Q  |   W  |   E  |   R  |   T  |   [  |           |   ]  |   Y  |   U  |   I  |   O  |   P  |   \    |
 * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
 * | CapsL  |   A  |   S  |   D  |   F  |   G  |------|           |------|   H  |   J  |   K  |   L  |   ;  |   "    |
 * |--------+------+------+------+------+------| ~L1  |           |  ~L1 |------+------+------+------+------+--------|
 * | LShift |   Z  |   X  |   C  |   V  |   B  |      |           |      |   N  |   M  |   ,  |   .  |   /  | RShift |
 * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
 *   | Ctrl | Opt  | Cmd  | Left | Right|                                       | Down | Up   | Ctrl | Cmd  | Opt  |
 *   `----------------------------------'                                       `----------------------------------'
 *                                        ,-------------.       ,-------------.
 *                                        |      | L1   |       | Alt  | Ctrl   ]
 *                                 ,------|------|------|       |------+--------+------.
 *                                 |      |      | Home |       | PgUp |        |      |
 *                                 |Backsp| Del  |------|       |------|  Enter | Spc  |
 *                                 |      |      | End  |       | PgDn |        |      |
 *                                 `--------------------'       `----------------------'
 */

    [BASE] = KEYMAP(  // layer 0 : default
        // left hand
        KC_ESC,     KC_1,     KC_2,    KC_3,    KC_4,    KC_5,    KC_6,
        KC_TAB,     M(KC_Q),  M(KC_W), M(KC_E), M(KC_R), M(KC_T), KC_LBRC,
        M(KC_CAPS), M(KC_A),  M(KC_S), M(KC_D), M(KC_F), M(KC_G),
        KC_LSFT,    M(KC_Z),  M(KC_X), M(KC_C), M(KC_V), M(KC_B), KC_FN0,
        KC_LCTL,    KC_LALT,  KC_LGUI, KC_LEFT, KC_RGHT,
                                                         KC_TRNS, KC_FN1,
                                                                  KC_HOME,
                                                KC_BSPC, KC_DEL,  KC_END,
        // right hand
        KC_GRV,     KC_7,     KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,
        KC_RBRC,    M(KC_Y),  M(KC_U), M(KC_I), M(KC_O), M(KC_P), KC_BSLS,
                    M(KC_H),  M(KC_J), M(KC_K), M(KC_L), KC_SCLN, KC_QUOT,
        KC_FN0,     M(KC_N),  M(KC_M), KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT,
                              KC_DOWN, KC_UP,   KC_RCTL, KC_RGUI, KC_RALT,
        KC_RALT,    KC_RCTL,
        KC_PGUP,
        KC_PGDN,    KC_ENT,   KC_SPC
    ),
/* Keymap 1: Symbol Layer
 *
 * ,--------------------------------------------------.           ,--------------------------------------------------.
 * |   `    |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |           |      |  F7  |  F8  |  F9  |  F10 |  F11 |   F12  |
 * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
 * |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        |
 * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
 * |        |      |      |      |      |      |------|           |------|      |      |      |      |      |        |
 * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
 * |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        |
 * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
 *   |      |      |      |      |      |                                       |      |      |      |      |      |
 *   `----------------------------------'                                       `----------------------------------'
 *                                        ,-------------.       ,-------------.
 *                                        |   L0 |  L2  |       |      |      |
 *                                 ,------|------|------|       |------+------+------.
 *                                 |      |      |      |       |      |      |      |
 *                                 |      |      |------|       |------|      |      |
 *                                 |      |      |      |       |      |      |      |
 *                                 `--------------------'       `--------------------'
 */
// SYMBOLS
    [SYMB] = KEYMAP(
       // left hand
       KC_GRV ,KC_F1,  KC_F2,  KC_F3,  KC_F4,  KC_F5,  KC_F6,
       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_FN3, KC_FN2,
                                                       KC_TRNS,
                                       KC_TRNS,KC_TRNS,KC_TRNS,
       // right hand
       KC_TRNS, KC_F7,   KC_F8,  KC_F9,   KC_F10,  KC_F11,  KC_F12,
       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
    ),
/* Keymap 2: Media and tenkey
 *
 * ,--------------------------------------------------.           ,--------------------------------------------------.
 * |  BOOTL |      | Mute | Vol- | Vol+ | F14  | F15  |           |      |      | NumLk|   /  |  *   |  -   |        |
 * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
 * |        |      |      |      |      |      |      |           |      |      |  7   |  8   |  9   |  +   |        |
 * |--------+------+------+------+------+------|      |           |      |------+-----+-------+------+------+--------|
 * |        |      |      |      |      |      |------|           |------|      |  4   |  5   |  6   |  +   |        |
 * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
 * |        |      |      |      |      |      |      |           |      |      |  1   |  2   |  3   | Enter|        |
 * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
 *   |      |      |      |      |      |                                       |  0   |  0   |  .   | Enter|      |
 *   `----------------------------------'                                       `----------------------------------'
 *                                        ,-------------.       ,-------------.
 *                                        |  L1  |      |       |      |      |
 *                                 ,------|------|------|       |------+------+------.
 *                                 |      |      |      |       |      |      |      |
 *                                 |      |      |------|       |------|      |      |
 *                                 |      |      |      |       |      |      |      |
 *                                 `--------------------'       `--------------------'
 */
    // MEDIA AND TENKEY
    [MDIA] = KEYMAP(
       KC_NO,   KC_NO,   KC_MUTE, KC_VOLD, KC_VOLU, KC_F14,  KC_F15,
       KC_TRNS, KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,
       KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,
       KC_TRNS, KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,
       KC_TRNS, KC_TRNS, KC_TRNS, KC_NO,   KC_NO,
                                                    KC_FN4,  KC_NO,
                                                             KC_TRNS,
                                           KC_TRNS, KC_TRNS, KC_TRNS,
       // right hand
       KC_NO,   KC_NO,   KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, KC_NO,
       KC_NO,   KC_NO,   KC_P7,   KC_P8,   KC_P9,   KC_PPLS, KC_NO,
                KC_NO,   KC_P4,   KC_P5,   KC_P6,   KC_PPLS, KC_NO,
       KC_NO,   KC_NO,   KC_P1,   KC_P2,   KC_P3,   KC_PENT, KC_NO,
                         KC_P0,   KC_P0,   KC_PDOT, KC_PENT, KC_NO,
       KC_NO,   KC_NO,
       KC_TRNS,
       KC_TRNS, KC_TRNS, KC_TRNS
    ),
};

const uint16_t PROGMEM fn_actions[] = {
    ACTION_LAYER_MOMENTARY(SYMB),               // FN0 - Momentary Layer 1 (Symbols)
    ACTION_LAYER_ON(SYMB,ON_RELEASE),           // FN1 - Enable Layer 1 (Symbols)
    ACTION_LAYER_ON(MDIA,ON_RELEASE),           // FN2 - Enable Layer 2 (Media)
    ACTION_LAYER_OFF(SYMB,ON_RELEASE),          // FN3 - Disable Layer 1 (Symbols)
    ACTION_LAYER_OFF(MDIA,ON_RELEASE),          // FN4 - Disable Layer 2 (MMedia)
    ACTION_LAYER_MOMENTARY(MDIA)                // FN5 - Momentary Layer 2 (Mdia)
};


const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
    static onoff caps_state = OFF;
    switch(id) {
    case KC_CAPS:
        if (record->event.pressed) {
            // Toggle caps state;
            if (caps_state == OFF) {
                // Turn it on then!
                caps_led_on();
                caps_state = ON;
            } else {
                caps_led_off();
                caps_state = OFF;
            }
        }
        break;
    default:
        if (record->event.pressed) {
            bool shifted = false;
            if (caps_state == ON && get_mods() == 0) {
                register_code(KC_LSFT);
                shifted = true;
            }
            register_code(id);
            if(shifted) {
                unregister_code(KC_LSFT);
            }
        } else {
            unregister_code(id);
        }
        break;
    }
    return MACRO_NONE;
};

// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {

}
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
    uint8_t layer = biton32(layer_state);

    static onoff board_led_state = OFF;
    static uint16_t dt = 0;
    static uint8_t oldlayer = 0;

    if(oldlayer != layer) {
        // Layer was just toggled.
        if(layer == BASE) {
            ergodox_board_led_off();
            board_led_state = OFF;
        } else {
            ergodox_board_led_on();
            board_led_state = ON;
        }
    } else if (layer >= MDIA) {
        // We need to do blinking.
        if(timer_elapsed(dt) > BLINK_BASE) {
            // toggle
            dt = timer_read();
            if(board_led_state == OFF) {
                ergodox_board_led_on();
                board_led_state = ON;
            } else {
                ergodox_board_led_off();
                board_led_state = OFF;
            }
        }
    }
    oldlayer = layer;
}

A keyboards/ergodox/keymaps/osx_whiskey_tango_foxtrot_capslock/osx_whiskey_tango_foxtrot_capslock.png => keyboards/ergodox/keymaps/osx_whiskey_tango_foxtrot_capslock/osx_whiskey_tango_foxtrot_capslock.png +0 -0
A keyboards/ergodox/keymaps/osx_whiskey_tango_foxtrot_capslock/readme.md => keyboards/ergodox/keymaps/osx_whiskey_tango_foxtrot_capslock/readme.md +38 -0
@@ 0,0 1,38 @@
# The extra special ergodox build for MacOS Sierra caps lock users

###Do you
- Hate the OSX / MacOS caps lock delay?
- Have an ergodox?

###Then this might just be for you!

[This](http://apple.stackexchange.com/questions/81234/how-to-remove-caps-lock-delay-on-apple-macbook-pro-aluminum-keyboard)
and [this](http://sleepycow.org/2014/07/removing-the-caps-lock-delay-on-a-macbook/)
are good workarounds for the caps lock delay, however none of these
work on Sierra.  This abomination of a keymap simulates capslock to the best
of its abilities.
This means that it keeps track of caps lock state internally rather than
sending a caps lock keypress to the OS.  It is smart enough to check for
modifiers, such as Control being held down, and stop it with the hanky panky
and just send on the key event unmolested even if FakeCaps is enabled.  And
since the macro isn't even registered on the non-alphas, it will not affect
them regardless.  Only in the event that FakeCaps is enabled and an alpha key
is pressed will it sneak in a shift keydown before the alpha keydown and
immediately afterward sneaks in a shift keyup.  Generally this works well,
however there is one known issue:

- Holding down a key will only have the first character in caps.  For instance,
  with caps lock on, if you hold down the 'a' key, you get:

  ```
  Aaaaaaaaaaaaaaaaaa
  ```

I have only tested this on an original Ergodox with a Teensy 2.0.

####Some other small tweaks
 - Layer 0 board light is off
 - Layer 1 board light is on solid
 - Layer 2 board light blinks at speed controlled by BLINK_BASE

![osx whiskey tango foxtrot](osx_whiskey_tango_foxtrot_capslock.png)