~ruther/qmk_firmware

98af5bc64e6148915cebcfdd607119b9feefe90d — jonavin 4 years ago 425e1e6
[Keymap] Add jonavin user space / common functions (#13876)

Co-authored-by: Drashna Jaelre <drashna@live.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: Jonavin <=>
M keyboards/gmmk/pro/keymaps/jonavin/keymap.c => keyboards/gmmk/pro/keymaps/jonavin/keymap.c +11 -176
@@ 17,36 17,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include QMK_KEYBOARD_H
#include "rgb_matrix_map.h"

#define ARRAYSIZE(arr)  sizeof(arr)/sizeof(arr[0])

enum custom_layers {
    _BASE,
    _FN1,
    _MO2,
    _MO3,
};

enum custom_keycodes {
  KC_00 = SAFE_RANGE,
  KC_WINLCK,    //Toggles Win key on and off
  RGB_TOI,   // Timeout idle time up
  RGB_TOD,   // Timeout idle time down
};

// Tap Dance Definitions
enum custom_tapdance {
  TD_LSFT_CAPSLOCK,
};

qk_tap_dance_action_t tap_dance_actions[] = {
  // Tap once for shift, twice for Caps Lock
  [TD_LSFT_CAPSLOCK] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
};

#define KC_LSFTCAPS TD(TD_LSFT_CAPSLOCK)

bool _isWinKeyDisabled = false;
#include "jonavin.h"


const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {


@@ 63,8 34,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
        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_INS,           KC_MUTE,
        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_DEL,
        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_PGUP,
        TT(_MO2), 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_PGDN,
        KC_LSFTCAPS,      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_END,
        TT(_LOWER), 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_PGDN,
        KC_LSFTCAPSWIN,   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_END,
        KC_LCTL, KC_LGUI, KC_LALT,                            KC_SPC,                             KC_RALT, MO(_FN1),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
    ),



@@ 77,7 48,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
        _______, KC_WINLCK, _______,                            _______,                          _______, _______, _______, RGB_SPD, RGB_RMOD, RGB_SPI
    ),

    [_MO2] = LAYOUT(
    [_LOWER] = LAYOUT(
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
        _______, _______, _______, _______, _______, _______, _______, KC_P7,   KC_P8,   KC_P9,   KC_P0,   KC_PMNS, KC_PPLS, _______,          _______,
        _______, KC_HOME, KC_UP,   KC_END,  KC_PGUP, _______, KC_TAB,  KC_P4,   KC_P5,   KC_P6,   KC_PDOT, _______, _______, _______,          KC_HOME,


@@ 86,7 57,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
        _______, _______, _______,                            KC_BSPC,                            _______, _______, _______, RCTL(KC_LEFT), RCTL(KC_PGDN), RCTL(KC_RIGHT)
    ),

   [_MO3] = LAYOUT(
   [_RAISE] = LAYOUT(
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,


@@ 98,139 69,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};


// TIMEOUTS
#define TIMEOUT_THRESHOLD_DEFAULT   5    // default timeout minutes
#define TIMEOUT_THRESHOLD_MAX       140  // upper limits (2 hours and 10 minutes -- no rgb indicators above this value)
static uint16_t timeout_timer = 0;
static uint16_t timeout_counter = 0;  //in minute intervals
static uint16_t timeout_threshold = TIMEOUT_THRESHOLD_DEFAULT;

void timeout_reset_timer(void) {
    timeout_timer = timer_read();
    timeout_counter = 0;
};

void timeout_update_threshold(bool increase) {
    if (increase && timeout_threshold < TIMEOUT_THRESHOLD_MAX) timeout_threshold++;
    if (!increase && timeout_threshold > 0) timeout_threshold--;
};


bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
    case KC_00:
        if (record->event.pressed) {
            // when keycode KC_00 is pressed
            SEND_STRING("00");
        } else {
            // when keycode KC_00 is released
        }
        break;
    case KC_WINLCK:
        if (record->event.pressed) {
            _isWinKeyDisabled = !_isWinKeyDisabled; //toggle status
            if(_isWinKeyDisabled) {
                process_magic(GUI_OFF, record);
            } else {
                process_magic(GUI_ON, record);
            }
        } else  unregister_code16(keycode);
        break;
    case RGB_TOI:
        if(record->event.pressed) {
            timeout_update_threshold(true);
        } else  unregister_code16(keycode);
        break;
    case RGB_TOD:
        if(record->event.pressed) {
             timeout_update_threshold(false);  //decrease timeout
        } else  unregister_code16(keycode);
        break;
    default:
        if (record->event.pressed) { //reset activity timer
            #ifdef RGB_MATRIX_ENABLE
                rgb_matrix_enable();
            #endif
            timeout_reset_timer();
        }
        break;
    }
    return true;
};

void matrix_scan_user(void) {
    if (timeout_threshold > 0) {
        if (timer_elapsed(timeout_timer) >= 60000) { // 1 minute tick
            timeout_counter++;
            timeout_timer = timer_read();
        }
        #ifdef RGB_MATRIX_ENABLE
            if (timeout_threshold > 0 && timeout_counter >= timeout_threshold) {
                rgb_matrix_disable_noeeprom();
            }
        #endif
    } // timeout_threshold = 0 will disable timeout
};


#ifdef ENCODER_ENABLE       // Encoder Functionality
    uint8_t selected_layer = 0;

    bool encoder_update_user(uint8_t index, bool clockwise) {
        if ( clockwise ) {
            if (keyboard_report->mods & MOD_BIT(KC_LSFT) ) { // If you are holding L shift, encoder changes layers
                if(selected_layer  < 3) {
                    selected_layer ++;
                    layer_move(selected_layer);
                }
            } else if (keyboard_report->mods & MOD_BIT(KC_RSFT) ) { // If you are holding R shift, Page up
                unregister_mods(MOD_BIT(KC_LSFT));
                register_code(KC_PGDN);
                register_mods(MOD_BIT(KC_LSFT));
            } else if (keyboard_report->mods & MOD_BIT(KC_LCTL)) {  // if holding Left Ctrl, navigate next word
                    tap_code16(LCTL(KC_RGHT));
            } else if (keyboard_report->mods & MOD_BIT(KC_LALT)) {  // if holding Left Alt, change media next track
                tap_code(KC_MEDIA_NEXT_TRACK);
            } else  {
                switch (selected_layer) {
                case _FN1:
                    timeout_update_threshold(true);
                    break;
                default:
                    tap_code(KC_VOLU);       // Otherwise it just changes volume
                    break;
                }
            }
        } else {
            if (keyboard_report->mods & MOD_BIT(KC_LSFT) ) {
                if (selected_layer  > 0) {
                    selected_layer --;
                    layer_move(selected_layer);
                }
            } else if (keyboard_report->mods & MOD_BIT(KC_RSFT) ) {
                unregister_mods(MOD_BIT(KC_LSFT));
                register_code(KC_PGUP);
                register_mods(MOD_BIT(KC_LSFT));
            } else if (keyboard_report->mods & MOD_BIT(KC_LCTL)) {  // if holding Left Ctrl, navigate previous word
                tap_code16(LCTL(KC_LEFT));
            } else if (keyboard_report->mods & MOD_BIT(KC_LALT)) {  // if holding Left Alt, change media previous track
                tap_code(KC_MEDIA_PREV_TRACK);
            } else {
                switch (selected_layer) {
                case _FN1:
                    timeout_update_threshold(false);
                    break;
                default:
                    tap_code(KC_VOLD);
                    break;
                }
            }
        }

        return true;
    }
#endif

#ifdef RGB_MATRIX_ENABLE
    // Capslock, Scroll lock and Numlock  indicator on Left side lights.
    void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {


@@ 247,7 85,7 @@ void matrix_scan_user(void) {
            rgb_matrix_set_color(LED_L6, RGB_RED);
            rgb_matrix_set_color(LED_L7, RGB_RED);
        }
        if (_isWinKeyDisabled) {
        if (keymap_config.no_gui) {
            rgb_matrix_set_color(LED_LWIN, RGB_RED);  //light up Win key when disabled
        }
        switch(get_highest_layer(layer_state)){  // special handling per layer


@@ 258,6 96,7 @@ void matrix_scan_user(void) {
            rgb_matrix_set_color(LED_FN, RGB_RED); //FN key

            // Add RGB Timeout Indicator -- shows 0 to 139 using F row and num row;  larger numbers using 16bit code
            uint16_t timeout_threshold = get_timeout_threshold();
            if (timeout_threshold <= 10) rgb_matrix_set_color(LED_LIST_FUNCROW[timeout_threshold], RGB_RED);
            else if (timeout_threshold < 140) {
                rgb_matrix_set_color(LED_LIST_FUNCROW[(timeout_threshold / 10)], RGB_RED);


@@ 268,7 107,7 @@ void matrix_scan_user(void) {
                rgb_matrix_set_color(LED_LIST_NUMROW[12], RGB_RED);
            }
            break;
        case _MO2:
        case _LOWER:
            for (uint8_t i=0; i<ARRAYSIZE(LED_LIST_NUMPAD); i++) {
                rgb_matrix_set_color(LED_LIST_NUMPAD[i], RGB_MAGENTA);
            }


@@ 276,7 115,7 @@ void matrix_scan_user(void) {
            rgb_matrix_set_color(LED_R5, RGB_MAGENTA);
            rgb_matrix_set_color(LED_R6, RGB_MAGENTA);
            break;
        case _MO3:
        case _RAISE:
            rgb_matrix_set_color(LED_R6, RGB_GREEN);
            rgb_matrix_set_color(LED_R7, RGB_GREEN);
            rgb_matrix_set_color(LED_R8, RGB_GREEN);


@@ 296,12 135,8 @@ void matrix_scan_user(void) {
#endif


void keyboard_post_init_user(void) {

    if (IS_HOST_LED_ON(USB_LED_NUM_LOCK)) { // turn on Num lock by defautl so that the numpad layer always has predictable results
        tap_code(KC_NUMLOCK);
    }
    timeout_timer = timer_read(); // set inital time for ide timeout
void keyboard_post_init_keymap(void) {
    // keyboard_post_init_user() moved to userspace
    #ifdef RGB_MATRIX_ENABLE
        rgb_matrix_set_color_all(RGB_NAUTILUS); // Default startup colour
    #endif

M keyboards/gmmk/pro/keymaps/jonavin/readme.md => keyboards/gmmk/pro/keymaps/jonavin/readme.md +13 -0
@@ 29,6 29,19 @@
    - Win Key light up red when Win Lock mode enabled
    - Layer 2 activation lights up Numpad area

rules.mk OPTIONS - Active features from userspace
STARTUP_NUMLOCK_ON = yes
    - turns on NUMLOCK by default

ENCODER_DEFAULTACTIONS_ENABLE = yes
    - Enabled default encoder funtions
  
TD_LSFT_CAPSLOCK_ENABLE = yes
    - This will enable double tap on Left Shift to toggle CAPSLOCK when using KC_LSFTCAPS

IDLE_TIMEOUT_ENABLE = yes
    - Enables Timer functionality; for RGB idle timeouts that can be changed dynamically

## All layers diagram
Default layer
![image](https://user-images.githubusercontent.com/71780717/124177658-82324880-da7e-11eb-9421-b69100131062.png)

M keyboards/gmmk/pro/keymaps/jonavin/rules.mk => keyboards/gmmk/pro/keymaps/jonavin/rules.mk +5 -0
@@ 2,3 2,8 @@ VIA_ENABLE = yes
MOUSEKEY_ENABLE = no
TAP_DANCE_ENABLE = yes
BOOTMAGIC_ENABLE = lite

TD_LSFT_CAPSLOCK_ENABLE = yes
IDLE_TIMEOUT_ENABLE = yes
STARTUP_NUMLOCK_ON = yes
ENCODER_DEFAULTACTIONS_ENABLE = yes

M keyboards/keebio/quefrency/keymaps/jonavin/keymap.c => keyboards/keebio/quefrency/keymaps/jonavin/keymap.c +15 -66
@@ 1,4 1,4 @@
/* Copyright 2021 Jonavin Eng
/* Copyright 2021 Jonavin Eng @Jonavin
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by


@@ 16,36 16,7 @@


#include QMK_KEYBOARD_H

// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
enum custom_layers {
    _BASE,
    _FN1,
    _MO2,
    _MO3,
};

enum custom_keycodes {
  DOUBLEZERO = SAFE_RANGE,
  KC_WINLCK,   //Toggles Win key on and off
};

// Tap Dance Definitions
enum custom_tapdance {
  TD_LSFT_CAPSLOCK,
};

qk_tap_dance_action_t tap_dance_actions[] = {
  // Tap once for shift, twice for Caps Lock
  [TD_LSFT_CAPSLOCK] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
};

#define KC_LSFTCAPS TD(TD_LSFT_CAPSLOCK)

bool _isWinKeyDisabled = false;
#include "jonavin.h"

#ifdef RGBLIGHT_ENABLE
    // Custom RGB Colours


@@ 56,7 27,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [_BASE] = LAYOUT_65(
      KC_GESC, 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_BSLS, KC_INS,
      KC_PSCR, 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_BSPC, KC_DEL,
      TT(_MO2), 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_PGUP,
      TT(_LOWER), 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_PGUP,
      KC_LSFTCAPS, 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_PGDN,
      KC_LCTL, KC_LGUI, KC_LALT, LT(_FN1, KC_SPC), KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(_FN1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
    [_FN1] = LAYOUT_65(


@@ 65,13 36,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
      KC_CAPS, KC_NO, RGB_VAD, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_HOME,
      KC_TRNS, KC_NO, RGB_HUI, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, RGB_MOD, KC_END,
      KC_TRNS, KC_WINLCK, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_APP, RGB_SPD, RGB_RMOD, RGB_SPI),
    [_MO2] = LAYOUT_65(
      KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_P7, KC_P8, KC_P9, KC_P0, KC_PMNS, KC_PPLS, KC_PSLS, KC_PEQL, KC_TRNS,
      KC_TAB, KC_HOME, KC_UP, KC_END, KC_PGUP, KC_NO, KC_NO, KC_P4, KC_P5, KC_P6, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_TRNS,
      KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, KC_NO, KC_TAB, KC_P1, KC_P2, KC_P3, KC_NO, KC_PAST, KC_PENT, KC_HOME,
      KC_TRNS, KC_NO, KC_DEL, KC_INS, KC_NO, KC_NO, KC_NLCK, KC_P0, DOUBLEZERO, KC_PDOT, KC_PSLS, KC_TRNS, RCTL(KC_PGUP), KC_END,
    [_LOWER] = LAYOUT_65(
      KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_P7, KC_P8, KC_P9, KC_P0, KC_PMNS, KC_PPLS,   KC_PSLS, KC_PEQL, KC_TRNS,
      KC_TAB, KC_HOME, KC_UP, KC_END, KC_PGUP, KC_NO, KC_NO, KC_P4, KC_P5, KC_P6, KC_NO, KC_NO, KC_NO,   KC_TRNS, KC_TRNS,
      KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, KC_NO,   KC_TAB,  KC_P1,   KC_P2,   KC_P3,   KC_NO,   KC_PAST, KC_PENT, KC_HOME,
      KC_TRNS, KC_NO,   KC_DEL,  KC_INS,  KC_NO,   KC_NO,   KC_NLCK, KC_P0,   KC_00,   KC_PDOT, KC_PSLS, KC_TRNS, RCTL(KC_PGUP), KC_END,
      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_BSPC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RCTL(KC_LEFT), RCTL(KC_PGDN), RCTL(KC_RIGHT)),
    [_MO3] = LAYOUT_65(
    [_RAISE] = LAYOUT_65(
      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_TRNS, KC_DOWN, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,


@@ 80,27 51,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};


bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
    case DOUBLEZERO:
        if (record->event.pressed) {
            // when keycode DOUBLEZERO is pressed
            SEND_STRING("00");
        } else {
            // when keycode DOUBLEZERO is released
        }
        break;
    case KC_WINLCK:
        if (record->event.pressed) {
            _isWinKeyDisabled = !_isWinKeyDisabled; //toggle status
            if(_isWinKeyDisabled) {
                process_magic(GUI_OFF, record);
            } else {
                process_magic(GUI_ON, record);
            }
        } else  unregister_code16(keycode);
        break;
    }
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
    // process_record_user() moved to userspace
    return true;
};



@@ 183,22 135,19 @@ bool encoder_update_user(uint8_t index, bool clockwise) {

    bool led_update_user(led_t led_state) {
        rgblight_set_layer_state(_rgbCAPS, led_state.caps_lock);
        rgblight_set_layer_state(_rgbWINLOCK, _isWinKeyDisabled);
        rgblight_set_layer_state(_rgbWINLOCK, keymap_config.no_gui);
        return true;
    }

    layer_state_t layer_state_set_user(layer_state_t state) {
        rgblight_set_layer_state(_rgbFN, layer_state_cmp(state, _FN1));
        rgblight_set_layer_state(_rgbNUMPAD, layer_state_cmp(state, _MO2));
        rgblight_set_layer_state(_rgbNUMPAD, layer_state_cmp(state, _LOWER));
        return state;
    }
#endif // RGBLIGHT_ENABLE

void keyboard_post_init_user(void) {

    if (IS_HOST_LED_ON(USB_LED_NUM_LOCK)) { // turn on Num lock by defautl so that the numpad layer always has predictable results
        tap_code(KC_NUMLOCK);
    }
void keyboard_post_init_keymap(void) {
    // keyboard_post_init_user() moved to userspace
    #ifdef RGBLIGHT_ENABLE
        rgblight_mode(1); // single colour mode
        rgblight_setrgb(RGB_GODSPEED); // Default startup colour

M keyboards/keebio/quefrency/keymaps/jonavin/readme.md => keyboards/keebio/quefrency/keymaps/jonavin/readme.md +7 -0
@@ 18,6 18,13 @@
    - Add capslock indicator, win key lock indicator
    - Fn and layer 2 indicators using RGB underglow

rules.mk OPTIONS - Active features from userspace
STARTUP_NUMLOCK_ON = yes
    - turns on NUMLOCK by default

TD_LSFT_CAPSLOCK_ENABLE = yes
    - This will enable double tap on Left Shift to toggle CAPSLOCK when using KC_LSFTCAPS

## All layers diagram

Default Layer

M keyboards/keebio/quefrency/keymaps/jonavin/rules.mk => keyboards/keebio/quefrency/keymaps/jonavin/rules.mk +3 -0
@@ 4,3 4,6 @@ LTO_ENABLE = yes

MOUSEKEY_ENABLE = no
TAP_DANCE_ENABLE = yes

TD_LSFT_CAPSLOCK_ENABLE = yes
STARTUP_NUMLOCK_ON = yes

M keyboards/mechwild/mercutio/keymaps/jonavin/keymap.c => keyboards/mechwild/mercutio/keymaps/jonavin/keymap.c +4 -43
@@ 18,35 18,7 @@

#include QMK_KEYBOARD_H
#include <stdio.h>

enum custom_layers {
    _BASE,
    _FN1,
    _LOWER,
    _RAISE,
};

enum custom_keycodes {
  ENCFUNC = SAFE_RANGE, // encoder function keys
  KC_WINLCK,    //Toggles Win key on and off
};

// Tap Dance Definitions
enum custom_tapdance {
  TD_LSFT_CAPSLOCK,
};

qk_tap_dance_action_t tap_dance_actions[] = {
  // Tap once for shift, twice for Caps Lock
  [TD_LSFT_CAPSLOCK] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
};

bool _isWinKeyDisabled = false;

#define KC_LSFTCAPS TD(TD_LSFT_CAPSLOCK)
#define KC_CAD	LALT(LCTL(KC_DEL))
#define KC_AF4	LALT(KC_F4)
#define KC_TASK	LCTL(LSFT(KC_ESC))
#include "jonavin.h"

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT_all(


@@ 113,13 85,12 @@ static void set_selectedkey(uint8_t idx) {

}

void keyboard_post_init_user(void) {
void keyboard_post_init_keymap(void) {
  // Call the keyboard post init code.
    //selectedkey_rec = keyselection[selectedkey_idx];
    set_selectedkey(selectedkey_idx);
}

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
    case ENCFUNC:
        if (record->event.pressed) {


@@ 128,16 99,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
            // when keycode is released
        }
        break;
    case KC_WINLCK:
        if (record->event.pressed) {
            _isWinKeyDisabled = !_isWinKeyDisabled; //toggle status
            if(_isWinKeyDisabled) {
                process_magic(GUI_OFF, record);
            } else {
                process_magic(GUI_ON, record);
            }
        } else  unregister_code16(keycode);
        break;
    }
    return true;
};


@@ 274,7 235,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
                default:
                    oled_write_P(PSTR("Layer ?"), false);    // Should never display, here as a catchall
            }
            oled_write_P(_isWinKeyDisabled ? PSTR(" WL") : PSTR("   "), false);
            oled_write_P(keymap_config.no_gui ? PSTR(" WL") : PSTR("   "), false);
            oled_set_cursor(8,3);
            if (get_highest_layer(layer_state) == selected_layer) {
                oled_write_P(PSTR("             "), false);

M keyboards/mechwild/mercutio/keymaps/jonavin/readme.md => keyboards/mechwild/mercutio/keymaps/jonavin/readme.md +7 -0
@@ 38,6 38,13 @@ Features
        While holding Left Alt, media next track or previous track


rules.mk OPTIONS - Active features from userspace
STARTUP_NUMLOCK_ON = yes
    - turns on NUMLOCK by default

TD_LSFT_CAPSLOCK_ENABLE = yes
    - This will enable double tap on Left Shift to toggle CAPSLOCK when using KC_LSFTCAPS

Default Layers
![image](https://user-images.githubusercontent.com/71780717/127014682-3aa05136-6dc7-4a40-9be1-89a5b584848a.png)


M keyboards/mechwild/mercutio/keymaps/jonavin/rules.mk => keyboards/mechwild/mercutio/keymaps/jonavin/rules.mk +3 -0
@@ 3,3 3,6 @@ VIA_ENABLE = yes
MOUSEKEY_ENABLE = yes
WPM_ENABLE = yes
TAP_DANCE_ENABLE = yes

TD_LSFT_CAPSLOCK_ENABLE = yes
STARTUP_NUMLOCK_ON = yes

A users/jonavin/config.h => users/jonavin/config.h +30 -0
@@ 0,0 1,30 @@
/* Copyright 2021 Jonavin Eng
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#define TAPPING_TOGGLE 2           // TT () set to two taps

/*  Handle GRAVESC combo keys */
#define GRAVE_ESC_ALT_OVERRIDE     // Always send Escape if Alt is pressed
#define GRAVE_ESC_CTRL_OVERRIDE    // Always send Escape if Control is pressed

#define TAPPING_TERM 180

#ifdef RGB_MATRIX_ENABLE
    #define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_SOLID_COLOR
    #define RGB_DISABLE_WHEN_USB_SUSPENDED true
#endif

A users/jonavin/jonavin.c => users/jonavin/jonavin.c +231 -0
@@ 0,0 1,231 @@

/* Copyright 2021 Jonavin Eng @Jonavin

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#include QMK_KEYBOARD_H
#include "jonavin.h"


#ifdef TD_LSFT_CAPSLOCK_ENABLE
  // Tap once for shift, twice for Caps Lock but only if Win Key in not disabled
    void dance_LSFT_finished(qk_tap_dance_state_t *state, void *user_data) {
        if (state->count == 1 || keymap_config.no_gui) {
            register_code16(KC_LSFT);
        } else {
            register_code(KC_CAPS);
        }
    }

    void dance_LSFT_reset(qk_tap_dance_state_t *state, void *user_data) {
        if (state->count == 1 || keymap_config.no_gui) {
            unregister_code16(KC_LSFT);
        } else {
            unregister_code(KC_CAPS);
        }
    }

    qk_tap_dance_action_t tap_dance_actions[] = {
    // Tap once for shift, twice for Caps Lock
        [TD_LSFT_CAPSLOCK] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
        [TD_LSFT_CAPS_WIN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_LSFT_finished, dance_LSFT_reset),
    };
#endif  // TD_LSFT_CAPSLOCK_ENABLE

// TIMEOUTS
#ifdef IDLE_TIMEOUT_ENABLE
    static uint16_t timeout_timer = 0;
    static uint16_t timeout_counter = 0;  //in minute intervals
    static uint16_t timeout_threshold = TIMEOUT_THRESHOLD_DEFAULT;

    uint16_t get_timeout_threshold(void) {
        return timeout_threshold;
    }

    void timeout_reset_timer(void) {
        timeout_timer = timer_read();
        timeout_counter = 0;
    };

    void timeout_update_threshold(bool increase) {
        if (increase && timeout_threshold < TIMEOUT_THRESHOLD_MAX) timeout_threshold++;
        if (!increase && timeout_threshold > 0) timeout_threshold--;
    };

    void timeout_tick_timer(void) {
        if (timeout_threshold > 0) {
            if (timer_elapsed(timeout_timer) >= 60000) { // 1 minute tick
                timeout_counter++;
                timeout_timer = timer_read();
            }
            #ifdef RGB_MATRIX_ENABLE
                if (timeout_threshold > 0 && timeout_counter >= timeout_threshold) {
                    rgb_matrix_disable_noeeprom();
                }
            #endif
        } // timeout_threshold = 0 will disable timeout
    }

    __attribute__((weak)) void matrix_scan_keymap(void) {}

    void matrix_scan_user(void) {
        timeout_tick_timer();
        matrix_scan_keymap();
    }
#endif // IDLE_TIMEOUT_ENABLE


#if defined(ENCODER_ENABLE) && defined(ENCODER_DEFAULTACTIONS_ENABLE)       // Encoder Functionality
    #ifndef DYNAMIC_KEYMAP_LAYER_COUNT
        #define DYNAMIC_KEYMAP_LAYER_COUNT 4  //default in case this is not already defined elsewhere
    #endif
    #ifndef ENCODER_DEFAULTACTIONS_INDEX
        #define ENCODER_DEFAULTACTIONS_INDEX 0  // can select encoder index if there are multiple encoders
    #endif

uint8_t selected_layer = 0;

__attribute__((weak)) bool encoder_update_keymap(uint8_t index, bool clockwise) { return true; }

bool encoder_update_user(uint8_t index, bool clockwise) {
    if (!encoder_update_keymap(index, clockwise)) { return false; }
    if (index != ENCODER_DEFAULTACTIONS_INDEX) {return true;}  // exit if the index doesn't match
        if ( clockwise ) {
            if (keyboard_report->mods & MOD_BIT(KC_LSFT) ) { // If you are holding L shift, encoder changes layers
                if(selected_layer  < (DYNAMIC_KEYMAP_LAYER_COUNT - 1)) {
                    selected_layer ++;
                    layer_move(selected_layer);
                }
            } else if (keyboard_report->mods & MOD_BIT(KC_RSFT) ) { // If you are holding R shift, Page up
                unregister_mods(MOD_BIT(KC_RSFT));
                register_code(KC_PGDN);
                register_mods(MOD_BIT(KC_RSFT));
            } else if (keyboard_report->mods & MOD_BIT(KC_LCTL)) {  // if holding Left Ctrl, navigate next word
                    tap_code16(LCTL(KC_RGHT));
            } else if (keyboard_report->mods & MOD_BIT(KC_LALT)) {  // if holding Left Alt, change media next track
                tap_code(KC_MEDIA_NEXT_TRACK);
            } else  {
                switch (selected_layer) {
                case _FN1:
                    #ifdef IDLE_TIMEOUT_ENABLE
                        timeout_update_threshold(true);
                    #endif
                    break;
                default:
                    tap_code(KC_VOLU);       // Otherwise it just changes volume
                    break;
                }
            }
        } else {
            if (keyboard_report->mods & MOD_BIT(KC_LSFT) ) {
                if (selected_layer  > 0) {
                    selected_layer --;
                    layer_move(selected_layer);
                }
            } else if (keyboard_report->mods & MOD_BIT(KC_RSFT) ) {
                unregister_mods(MOD_BIT(KC_RSFT));
                register_code(KC_PGUP);
                register_mods(MOD_BIT(KC_RSFT));
            } else if (keyboard_report->mods & MOD_BIT(KC_LCTL)) {  // if holding Left Ctrl, navigate previous word
                tap_code16(LCTL(KC_LEFT));
            } else if (keyboard_report->mods & MOD_BIT(KC_LALT)) {  // if holding Left Alt, change media previous track
                tap_code(KC_MEDIA_PREV_TRACK);
            } else {
                switch (selected_layer) {
                case _FN1:
                    #ifdef IDLE_TIMEOUT_ENABLE
                        timeout_update_threshold(false);
                    #endif
                    break;
                default:
                    tap_code(KC_VOLD);
                    break;
                }
            }
        }

        return true;
    }
#endif // ENCODER_ENABLE


// PROCESS KEY CODES
__attribute__ ((weak))  bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; }

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    if (!process_record_keymap(keycode, record)) { return false; }
     switch (keycode) {
    case KC_00:
        if (record->event.pressed) {
            // when keycode KC_00 is pressed
            SEND_STRING("00");
        } else unregister_code16(keycode);
        break;
    case KC_WINLCK:
        if (record->event.pressed) {
            keymap_config.no_gui = !keymap_config.no_gui; //toggle status
        } else  unregister_code16(keycode);
        break;

#ifdef IDLE_TIMEOUT_ENABLE
    case RGB_TOI:
        if(record->event.pressed) {
            timeout_update_threshold(true);
        } else  unregister_code16(keycode);
        break;
    case RGB_TOD:
        if(record->event.pressed) {
             timeout_update_threshold(false);  //decrease timeout
        } else  unregister_code16(keycode);
        break;
#endif // IDLE_TIMEOUT_ENABLE

    default:
        if (record->event.pressed) {
            #ifdef RGB_MATRIX_ENABLE
                rgb_matrix_enable();
            #endif
            #ifdef IDLE_TIMEOUT_ENABLE
                timeout_reset_timer();  //reset activity timer
            #endif
        }
        break;
    }
    return true;
};


// Turn on/off NUM LOCK if current state is different
void activate_numlock(bool turn_on) {
    if (IS_HOST_LED_ON(USB_LED_NUM_LOCK) != turn_on) {
        tap_code(KC_NUMLOCK);
    }
}


// INITIAL STARTUP

__attribute__ ((weak)) void keyboard_post_init_keymap(void) {}

void keyboard_post_init_user(void) {
    keyboard_post_init_keymap();
    #ifdef STARTUP_NUMLOCK_ON
        activate_numlock(true); // turn on Num lock by default so that the numpad layer always has predictable results
    #endif // STARTUP_NUMLOC_ON
    #ifdef IDLE_TIMEOUT_ENABLE
        timeout_timer = timer_read(); // set inital time for ide timeout
    #endif
}

A users/jonavin/jonavin.h => users/jonavin/jonavin.h +82 -0
@@ 0,0 1,82 @@

/* Copyright 2021 Jonavin Eng @Jonavin

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

// DEFINE MACROS
#define ARRAYSIZE(arr)  sizeof(arr)/sizeof(arr[0])


// LAYERS
enum custom_user_layers {
    _BASE,
    _FN1,
    _LOWER,
    _RAISE,
};

// KEYCODES
enum custom_user_keycodes {
  KC_00 = SAFE_RANGE,
  ENCFUNC,
  KC_WINLCK,    //Toggles Win key on and off
  RGB_TOI,      // Timeout idle time up
  RGB_TOD,      // Timeout idle time down
};

#define KC_CAD	LALT(LCTL(KC_DEL))
#define KC_AF4	LALT(KC_F4)
#define KC_TASK	LCTL(LSFT(KC_ESC))


#ifdef TD_LSFT_CAPSLOCK_ENABLE
    // Tap Dance Definitions
    enum custom_tapdance {
        TD_LSFT_CAPSLOCK,
        TD_LSFT_CAPS_WIN
    };

    #define KC_LSFTCAPS     TD(TD_LSFT_CAPSLOCK)
    #define KC_LSFTCAPSWIN  TD(TD_LSFT_CAPS_WIN)
#else // regular Shift
    #define KC_LSFTCAPS    KC_LSFT
#endif // TD_LSFT_CAPSLOCK_ENABLE



#ifdef RGB_MATRIX_ENABLE
//RGB custom colours
    #define RGB_GODSPEED 0x00, 0xE4, 0xFF // colour for matching keycaps
    #define RGB_NAUTILUS 0x00, 0xA4, 0xA9 // Nautilus Font colours
#endif


// IDLE TIMEOUTS
#ifdef IDLE_TIMEOUT_ENABLE
    #define TIMEOUT_THRESHOLD_DEFAULT   5    // default timeout minutes
    #define TIMEOUT_THRESHOLD_MAX       140  // upper limits (2 hours and 10 minutes -- no rgb indicators above this value)

    //prototype  functions
    uint16_t get_timeout_threshold(void);
    void timeout_reset_timer(void);
    void timeout_update_threshold(bool increase);
    void timeout_tick_timer(void);
#endif  //IDLE_TIMEOUT_ENABLE


// OTHER FUNCTION PROTOTYPE
void activate_numlock(bool turn_on);

A users/jonavin/readme.md => users/jonavin/readme.md +76 -0
@@ 0,0 1,76 @@
Copyright 2021 Jonavin Eng @Jonavin

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

LAYERS:
    0 = _BASE
    1 = _FN1
    2 = _LOWER
    3 = _RAISE

KEYCODES:
    KC_CAD          Ctrl-Alt-Del	  
    KC_AF4	        Alt-F4
    KC_TASK	        Windows Task Manager (Ctrl-Shift-Esc) 
    LSFT_CAPSLOCK   When LSFT_CAPSLOCK_ENABLE is defined, hold for Shift double tap for CAPSLOCK; otherwise, just Shift
    KC_00           double zero "00"
    KC_WINLCK       toggles LGui/Win key lock
    RGB_TOI         Increase Timeout idle time threshold
    RGB_TOD         Decrease Timeout idle time threshold

ENABLE FEATURES your keymap rules.mk

STARTUP_NUMLOCK_ON = yes
    turns on NUMLOCK by default

ENCODER_DEFAULTACTIONS_ENABLE = yes
    Enabled default encoder funtions
    When enabled, use this in the keymap for an additional encoder processing 
        bool encoder_update_keymap(uint8_t index, bool clockwise)
  
    OPTION: set ENCODER_DEFAULTACTIONS_INDEX to the encoder number if the encoder is not index 0
  
TD_LSFT_CAPSLOCK_ENABLE = yes
    This will enable double tap on Left Shift to toggle CAPSLOCK
        KC_LSFTCAPS to bind to left Shift to enable feature
        KC_LSFTCAPSWIN does the same thing but will not turn on CAPS when Win Lkey is disabled

IDLE_TIMEOUT_ENABLE = yes
    Enables Timer functionality; for RGB idle timeouts that can be changed dynamically
    When enabled, use this in the keymap for an additional matrix processing     
        void matrix_scan_keymap(void)
    
    Functions:
        u16int_t get_timeout_threshold(void)            // returns the current timeout threshold
        void timeout_update_threshold(bool increase)    // change threshold: true = increase, false = decrease     
        void timeout_reset_timer(void)                  // resets timer (put in process_record_user if you override it)
        void timeout_tick_timer(void)                   // registers time ticks (put in maxtrix_scan_user if you override it)

Other Functions:
    - activate_numlock(bool turn_on)                    // true = turn on NUM LOCK, false = off 

KEYMAP LEVEL ADDITIONAL PROCESSING FUNCTIONS
    bool process_record_keymap(uint16_t keycode, keyrecord_t *record)
    void keyboard_post_init_keymap(void)

LIST OF COMPATIBLE KEYMAPS
    - gmmk/pro
    - gmmk/pro/ansi
    - keebio/quefrency/rev3
    - mechwild/mercutio
    - mechwild/murphpad (*)
    - mechwild/OBE (*)
    - nopunin10did/kastenwagen (*)

    (*) coming soon

A users/jonavin/rules.mk => users/jonavin/rules.mk +13 -0
@@ 0,0 1,13 @@
SRC += jonavin.c
ifeq ($(strip $(ENCODER_DEFAULTACTIONS_ENABLE)), yes)
    OPT_DEFS += -DENCODER_DEFAULTACTIONS_ENABLE
endif
ifeq ($(strip $(TD_LSFT_CAPSLOCK_ENABLE)), yes)
    OPT_DEFS += -DTD_LSFT_CAPSLOCK_ENABLE
endif
ifeq ($(strip $(IDLE_TIMEOUT_ENABLE)), yes)
    OPT_DEFS += -DIDLE_TIMEOUT_ENABLE
endif
ifeq ($(strip $(STARTUP_NUMLOCK_ON)), yes)
    OPT_DEFS += -DSTARTUP_NUMLOCK_ON
endif