Merge remote-tracking branch 'origin/master' into develop

master
QMK Bot 2023-07-03 19:22:59 +00:00
commit d55eeb207b
4 changed files with 515 additions and 228 deletions

View File

@ -20,3 +20,61 @@
#define RGB_MATRIX_TIMEOUT 1200000 // 20 minutes (20 * 60 * 1000ms) #define RGB_MATRIX_TIMEOUT 1200000 // 20 minutes (20 * 60 * 1000ms)
#define RGB_DISABLE_WHEN_USB_SUSPENDED #define RGB_DISABLE_WHEN_USB_SUSPENDED
#endif #endif
// Setting DEBOUNCE to 8 to be a little conservative due to issues with Glorious' proprietary hot-swap sockets
#ifdef DEBOUNCE
#undef DEBOUNCE
#endif
#define DEBOUNCE 8
// RGB Matrix Animation modes. Explicitly enabled
// For full list of effects, see:
// https://docs.qmk.fm/#/feature_rgb_matrix?id=rgb-matrix-effects
// #define ENABLE_RGB_MATRIX_ALPHAS_MODS
// #define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
// #define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
#define ENABLE_RGB_MATRIX_BREATHING
// #define ENABLE_RGB_MATRIX_BAND_SAT
// #define ENABLE_RGB_MATRIX_BAND_VAL
// #define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
// #define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
// #define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
#define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
#define ENABLE_RGB_MATRIX_CYCLE_ALL
#define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
#define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
#define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN
#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
#define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
#define ENABLE_RGB_MATRIX_CYCLE_SPIRAL
#define ENABLE_RGB_MATRIX_DUAL_BEACON
#define ENABLE_RGB_MATRIX_RAINBOW_BEACON
// #define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
// #define ENABLE_RGB_MATRIX_RAINDROPS
#define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
// #define ENABLE_RGB_MATRIX_HUE_BREATHING
// #define ENABLE_RGB_MATRIX_HUE_PENDULUM
// #define ENABLE_RGB_MATRIX_HUE_WAVE
#define ENABLE_RGB_MATRIX_PIXEL_RAIN
// #define ENABLE_RGB_MATRIX_PIXEL_FLOW
// #define ENABLE_RGB_MATRIX_PIXEL_FRACTAL
// enabled only if RGB_MATRIX_FRAMEBUFFER_EFFECTS is defined
#define ENABLE_RGB_MATRIX_TYPING_HEATMAP
#define ENABLE_RGB_MATRIX_DIGITAL_RAIN
// enabled only of RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is defined
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
// #define ENABLE_RGB_MATRIX_SOLID_REACTIVE
// #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
// #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
// #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
// #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
#define ENABLE_RGB_MATRIX_SPLASH
// #define ENABLE_RGB_MATRIX_MULTISPLASH
#define ENABLE_RGB_MATRIX_SOLID_SPLASH
#define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
#define RGB_MATRIX_KEYPRESSES
#define RGB_MATRIX_FRAMEBUFFER_EFFECTS

View File

@ -24,16 +24,22 @@ enum layers {
MAC_FN MAC_FN
}; };
#define KC_TASK LGUI(KC_TAB) enum custom_keycodes {
#define KC_FLXP LGUI(KC_E) CMDQ_TOG = QK_KB_2 // TECH DEBT: Starts at QK_KB_2 to maintain ordering with VIA definitions. See #19884. Revert to QK_KB_0 when VIA catches up with QMK.
#define TO_WINB TO(WIN_BASE) };
#define TO_MACB TO(MAC_BASE)
#define MO_WINF MO(WIN_FN) #define KC_TASK LWIN(KC_TAB) // Open Task Manager
#define MO_MACF MO(MAC_FN) #define KC_FLXP LWIN(KC_E) // Open File Explorer
#define DF_WINB DF(WIN_BASE) // Switch to WIN_BASE layer
#define MO_WINF MO(WIN_FN) // Toggle to WIN_FN layer
#define DF_MACB DF(MAC_BASE) // Switch to MAX_BASE layer
#define MO_MACF MO(MAC_FN) // Toggle to MAC_FN layer
// clang-format off // clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// The GMMK Pro default layout is:
//
// ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Del Rotary(Play/Pause) // ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Del Rotary(Play/Pause)
// ~ 1 2 3 4 5 6 7 8 9 0 - (=) BackSpc Home // ~ 1 2 3 4 5 6 7 8 9 0 - (=) BackSpc Home
// Tab Q W E R T Y U I O P [ ] \ PgUp // Tab Q W E R T Y U I O P [ ] \ PgUp
@ -55,130 +61,246 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Press Fn+N to toggle between 6KRO and NKRO. This setting is persisted to the EEPROM and thus persists between restarts. // Press Fn+N to toggle between 6KRO and NKRO. This setting is persisted to the EEPROM and thus persists between restarts.
// //
// RGB and function keys are inspired by the Keychron Q1 layouts instead of using the default keys. // RGB and function keys are inspired by the Keychron Q1 layouts instead of using the default keys.
// // To clean the EEPROM, hold the ESC key while connecting the keyboard.
// KC_PAUS/KC_BRMU and KC_SCRL/KC_BRMD are aliases for the same keys, but their names reflect better the function in each layout.
[WIN_BASE] = LAYOUT( [WIN_BASE] = LAYOUT(
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_DEL, KC_MUTE, 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_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_HOME, 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_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, 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_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_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_HOME,
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_END, 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_END,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO_WINF, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT KC_LCTL, KC_LWIN, KC_LALT, KC_SPC, KC_RALT, MO_WINF, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
), ),
[WIN_FN] = LAYOUT( [WIN_FN] = LAYOUT(
_______, KC_BRID, KC_BRIU, KC_TASK, KC_FLXP, KC_MPRV, KC_MNXT, KC_MPLY, KC_MSTP, KC_MUTE, KC_VOLD, KC_VOLU, XXXXXXX, KC_INS, XXXXXXX, EE_CLR, KC_BRID, KC_BRIU, KC_TASK, KC_FLXP, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_PSCR, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_PAUS,
RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, QK_BOOT, KC_PAUS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_SAI, RGB_SPI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, QK_BOOT, KC_SCRL,
TO_MACB, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_SCRL, DF_MACB, RGB_RMOD, RGB_HUD, RGB_SAD, RGB_SPD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_PGUP,
_______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, NK_TOGG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, NK_TOGG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_PGDN,
_______, _______, _______, XXXXXXX, _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
), ),
[MAC_BASE] = LAYOUT( [MAC_BASE] = LAYOUT(
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_DEL, KC_MUTE, 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_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_HOME, 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_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, 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_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_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_HOME,
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_END, 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_END,
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RALT, MO_MACF, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT KC_LCTL, KC_LOPT, KC_LCMD, KC_SPC, KC_RCMD, MO_MACF, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
), ),
[MAC_FN] = LAYOUT( [MAC_FN] = LAYOUT(
_______, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, KC_MPRV, KC_MNXT, KC_MPLY, KC_MSTP, KC_MUTE, KC_VOLD, KC_VOLU, XXXXXXX, KC_INS, XXXXXXX, EE_CLR, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_PSCR, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_BRMU,
RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, QK_BOOT, KC_BRMU, RGB_TOG, RGB_MOD, RGB_HUI, RGB_SAI, RGB_SPI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, QK_BOOT, KC_BRMD,
TO_WINB, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_BRMD, DF_WINB, RGB_RMOD, RGB_HUD, RGB_SAD, RGB_SPD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_PGUP,
_______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, NK_TOGG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, NK_TOGG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_PGDN,
_______, _______, _______, XXXXXXX, _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX XXXXXXX, XXXXXXX, CMDQ_TOG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
) )
}; };
// clang-format on // clang-format on
#ifdef ENCODER_MAP_ENABLE
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
[WIN_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) },
[WIN_FN] = { ENCODER_CCW_CW(XXXXXXX, XXXXXXX) },
[MAC_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) },
[MAC_FN] = { ENCODER_CCW_CW(XXXXXXX, XXXXXXX) },
};
#endif
/* To record user preferences */
typedef union {
uint32_t raw; // set to 32-bit of size
struct {
bool rgb_enabled :1; // Artificial RGB ON/OFF flag (1 bit)
bool cmd_q_delay_enabled :1; // Toggle CMD+Q delay (1 bit)
};
} user_config_t;
user_config_t user_config;
/* Delayed keypresses variables and functions */
static uint16_t delayed_press_delay = 0;
static uint16_t delayed_press_keycode = KC_NO;
static uint16_t delayed_press_start_time = 0;
static uint16_t delayed_press_sent_keycode = KC_NO;
static void start_delayed_press(const uint16_t delay, const uint16_t keycode);
static bool is_any_delayed_press_pending(void);
static bool is_delayed_press_pending(const uint16_t keycode);
static bool is_delayed_press_sent(const uint16_t keycode);
static void mark_delayed_press_sent(void);
static void mark_delayed_release_sent(void);
static void cancel_delayed_press(void);
/* CMD+Q delay */
#ifndef CMD_Q_DELAY
#define CMD_Q_DELAY 1000
#endif
#if CMD_Q_DELAY <= 0 || CMD_Q_DELAY >= UINT16_MAX / 2
#error "CMD_Q_DELAY must be a positive integer smaller than UINT16_MAX / 2"
#endif
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#ifdef RGB_MATRIX_ENABLE #ifdef RGB_MATRIX_ENABLE
/* Renaming those to make the purpose on this keymap clearer */ #define CAPS_LOCK_COLOR RGB_RED
#define LED_FLAG_CAPS LED_FLAG_NONE #define WIN_BASE_COLOR RGB_BLUE
#define LED_FLAG_EFFECTS LED_FLAG_INDICATOR #define WIN_FN_COLOR RGB_BLUE
#define MAC_BASE_COLOR RGB_WHITE
#define MAC_FN_COLOR RGB_WHITE
#define UNKNOWN_LAYER_COLOR RGB_PINK
static void set_rgb_caps_leds(void); /* The maximum effects duration */
#ifndef EFFECTS_DURATION
#define EFFECTS_DURATION 2000
#endif
#if EFFECTS_DURATION <= 0 || EFFECTS_DURATION >= UINT16_MAX / 2
#error "EFFECTS_DURATION must be a positive integer smaller than UINT16_MAX / 2"
#endif
/* The interval for the flashing effect */
#ifndef FLASHING_EFFECT_INTERVAL
#define FLASHING_EFFECT_INTERVAL 250
#endif
#if FLASHING_EFFECT_INTERVAL <= 0 || FLASHING_EFFECT_INTERVAL >= UINT16_MAX / 2
#error "FLASHING_EFFECT_INTERVAL must be a positive integer smaller than UINT16_MAX / 2"
#endif
static void set_rgb_layer_winfn(void);
static void set_rgb_layer_macfn(void);
/* Effects functions */
static float flashing_effect(const uint16_t delta_time);
static float static_effect(const uint16_t delta_time);
static float increasing_effect(const uint16_t delta_time);
/* Effect variables and functions */
static uint16_t effect_started_time = 0; static uint16_t effect_started_time = 0;
static uint8_t r_effect = 0x0, g_effect = 0x0, b_effect = 0x0; static uint16_t effect_max_duration = EFFECTS_DURATION;
static void start_effects(void); static uint8_t effect_r = 0x0, effect_g = 0x0, effect_b = 0x0;
static float (*effect_multiplier)(const uint16_t) = static_effect;
static void start_effects(
const uint16_t max_duration,
const uint8_t r_color,
const uint8_t g_color,
const uint8_t b_color,
const float (*multiplier)(const uint16_t));
static void stop_effects(void);
/* The interval time in ms */ /* Delayed keypresses variables with RGB variant */
#ifndef EFFECTS_TIME static void start_delayed_press_with_effects(
#define EFFECTS_TIME 2000 const uint16_t delay,
#endif const uint16_t keycode,
#ifndef EFFECTS_INTERVAL const uint8_t r_color,
#define EFFECTS_INTERVAL 250 const uint8_t g_color,
#endif const uint8_t b_color);
#if EFFECTS_TIME <= 0 || EFFECTS_TIME >= 32767
#error "EFFECTS_TIME must be a positive integer smaller than 32767"
#endif
#if EFFECTS_INTERVAL <= 0 || EFFECTS_INTERVAL >= 32767
#error "EFFECTS_INTERVAL must be a positive integer smaller than 32767"
#endif
#define effect_red() r_effect = 0xFF, g_effect = 0x0, b_effect = 0x0
#define effect_green() r_effect = 0x0, g_effect = 0xFF, b_effect = 0x0
#define effect_blue() r_effect = 0x0, g_effect = 0x0, b_effect = 0xFF
#define effect_white() r_effect = 0xFF, g_effect = 0xFF, b_effect = 0xFF
static uint8_t previous_effect_layer = 255;
layer_state_t layer_state_set_user(layer_state_t state) {
uint8_t current_layer = get_highest_layer(state);
switch (current_layer) {
case WIN_BASE:
if (previous_effect_layer != current_layer) {
previous_effect_layer = current_layer;
effect_blue();
start_effects();
}
break;
case MAC_BASE:
if (previous_effect_layer != current_layer) {
previous_effect_layer = current_layer;
effect_white();
start_effects();
}
break;
}
return state;
}
bool led_update_user(led_t led_state) {
if (led_state.caps_lock) {
if (!rgb_matrix_is_enabled()) {
/* Turn ON the RGB Matrix for CAPS LOCK */
rgb_matrix_set_flags(LED_FLAG_CAPS);
rgb_matrix_enable();
}
} else if (rgb_matrix_get_flags() == LED_FLAG_CAPS) {
/* RGB Matrix was only ON because of CAPS LOCK. Turn it OFF. */
rgb_matrix_set_flags(LED_FLAG_ALL);
rgb_matrix_disable();
}
return true;
}
#endif // RGB_MATRIX_ENABLE #endif // RGB_MATRIX_ENABLE
void eeconfig_init_user(void) { // EEPROM is getting reset!
user_config.raw = 0;
user_config.rgb_enabled = true; // We want this enabled by default
user_config.cmd_q_delay_enabled = true; // We want this enabled by default
eeconfig_update_user(user_config.raw); // Write default value to EEPROM now
}
void keyboard_post_init_user(void) {
#ifdef RGB_MATRIX_ENABLE
// Enable the RGB matrix, if not enabled
if (!rgb_matrix_is_enabled()) {
rgb_matrix_enable();
}
// Set the flags to ALL, if not already set
if (rgb_matrix_get_flags() != LED_FLAG_ALL) {
rgb_matrix_set_flags(LED_FLAG_ALL);
}
#endif
// Read the user config from EEPROM
user_config.raw = eeconfig_read_user();
}
void matrix_scan_user(void) {
if (is_any_delayed_press_pending()) {
if (sync_timer_elapsed(delayed_press_start_time) > delayed_press_delay) {
register_code(delayed_press_keycode);
mark_delayed_press_sent();
}
}
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) { bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (is_delayed_press_sent(keycode)) {
if (!record->event.pressed) {
/* Send key-up event and clear the keycode and stop processing */
unregister_code(keycode);
mark_delayed_release_sent();
return false;
}
} else if (is_delayed_press_pending(keycode)) {
if (!record->event.pressed) {
/* Cancel the pending press and stop processing */
cancel_delayed_press();
return false;
}
} else if (is_any_delayed_press_pending()) {
/* Cancel the pending press and resume processing */
cancel_delayed_press();
}
switch (keycode) { switch (keycode) {
case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:
if (record->event.pressed) {
/* Set the default layout on the EEPROM, let the default layer change callback handle the rest */
set_single_persistent_default_layer(QK_DEF_LAYER_GET_LAYER(keycode));
}
return false;
case CMDQ_TOG:
if (record->event.pressed) {
if (user_config.cmd_q_delay_enabled) {
/* Turning delay OFF */
#ifdef RGB_MATRIX_ENABLE
start_effects(EFFECTS_DURATION, RGB_RED, flashing_effect);
#endif
} else {
/* Turning delay ON */
#ifdef RGB_MATRIX_ENABLE
start_effects(EFFECTS_DURATION, RGB_GREEN, flashing_effect);
#endif
}
user_config.cmd_q_delay_enabled = !user_config.cmd_q_delay_enabled;
eeconfig_update_user(user_config.raw);
}
return false;
case KC_Q:
if (user_config.cmd_q_delay_enabled) {
if (layer_state_is(MAC_BASE)) {
const uint8_t mods = get_mods();
if (mods == MOD_BIT(KC_LCMD) || mods == MOD_BIT(KC_RCMD)) {
if (record->event.pressed) {
#ifdef RGB_MATRIX_ENABLE
start_delayed_press_with_effects(CMD_Q_DELAY, KC_Q, RGB_ORANGE);
#else
start_delayed_press(CMD_Q_DELAY, KC_Q);
#endif
}
return false;
}
}
}
break;
#ifdef RGB_MATRIX_ENABLE #ifdef RGB_MATRIX_ENABLE
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
case NK_TOGG: case NK_TOGG:
if (record->event.pressed) { if (record->event.pressed) {
if (keymap_config.nkro) { if (keymap_config.nkro) {
/* Turning NKRO OFF */ /* Turning NKRO OFF */
effect_red(); start_effects(EFFECTS_DURATION, RGB_RED, flashing_effect);
} else { } else {
/* Turning NKRO ON */ /* Turning NKRO ON */
effect_green(); start_effects(EFFECTS_DURATION, RGB_GREEN, flashing_effect);
} }
start_effects();
} }
break; break;
#endif // NKRO_ENABLE #endif // NKRO_ENABLE
@ -192,99 +314,171 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
case RGB_VAD: case RGB_VAD:
case RGB_SPI: case RGB_SPI:
case RGB_SPD: case RGB_SPD:
if (record->event.pressed) { if (!user_config.rgb_enabled) {
if (rgb_matrix_get_flags() != LED_FLAG_ALL) {
/* Ignore changes to RGB settings while only it's supposed to be OFF */ /* Ignore changes to RGB settings while only it's supposed to be OFF */
return false; // Skip all further processing of this key return false; // Skip all further processing of this key
} }
}
break; break;
case RGB_TOG: case RGB_TOG:
if (record->event.pressed) { if (record->event.pressed) {
if (rgb_matrix_is_enabled()) { user_config.rgb_enabled = !user_config.rgb_enabled;
switch (rgb_matrix_get_flags()) { eeconfig_update_user(user_config.raw);
case LED_FLAG_EFFECTS:
case LED_FLAG_CAPS:
/* Turned ON because of EFFECTS or CAPS, is actually OFF */
/* Change to LED_FLAG_ALL to signal it's really ON */
rgb_matrix_set_flags(LED_FLAG_ALL);
/* Will be re-enabled by the processing of the toggle */
rgb_matrix_disable_noeeprom();
break;
case LED_FLAG_ALL:
/* Is actually ON */
if (effect_started_time > 0) {
/* Signal EFFECTS */
rgb_matrix_set_flags(LED_FLAG_EFFECTS);
/* Will be re-enabled by the processing of the toggle */
rgb_matrix_disable_noeeprom();
} else
if (host_keyboard_led_state().caps_lock) {
/* Signal CAPS */
rgb_matrix_set_flags(LED_FLAG_CAPS);
/* Will be re-enabled by the processing of the toggle */
rgb_matrix_disable_noeeprom();
} }
break; return false;
}
}
}
break;
#endif // RGB_MATRIX_ENABLE #endif // RGB_MATRIX_ENABLE
} }
return true; return true;
} }
#ifdef RGB_MATRIX_ENABLE static void start_delayed_press(const uint16_t delay, const uint16_t keycode) {
bool rgb_matrix_indicators_user(void) { delayed_press_delay = delay;
if (effect_started_time > 0) { delayed_press_keycode = keycode;
/* Render blinking EFFECTS */ delayed_press_start_time = sync_timer_read();
const uint16_t deltaTime = sync_timer_elapsed(effect_started_time); delayed_press_sent_keycode = KC_NO;
if (deltaTime <= EFFECTS_TIME) {
const uint8_t led_state = ((deltaTime / EFFECTS_INTERVAL) + 1) & 0x01;
const uint8_t val_r = led_state * r_effect;
const uint8_t val_g = led_state * g_effect;
const uint8_t val_b = led_state * b_effect;
rgb_matrix_set_color_all(val_r, val_g, val_b);
if (host_keyboard_led_state().caps_lock) {
set_rgb_caps_leds();
}
return false;
} else {
/* EFFECTS duration is finished */
effect_started_time = 0;
if (rgb_matrix_get_flags() == LED_FLAG_EFFECTS) {
/* It was turned ON because of EFFECTS */
if (host_keyboard_led_state().caps_lock) {
/* CAPS is still ON. Demote to CAPS */
rgb_matrix_set_flags(LED_FLAG_CAPS);
} else {
/* There is nothing else keeping RGB enabled. Reset flags and turn if off. */
rgb_matrix_set_flags(LED_FLAG_ALL);
rgb_matrix_disable_noeeprom();
}
}
}
}
if (rgb_matrix_get_flags() == LED_FLAG_CAPS) {
rgb_matrix_set_color_all(0x0, 0x0, 0x0);
}
if (host_keyboard_led_state().caps_lock) {
set_rgb_caps_leds();
}
return false;
} }
static void start_effects(void) { static bool is_any_delayed_press_pending(void) {
effect_started_time = sync_timer_read(); return delayed_press_start_time > 0 && delayed_press_keycode != KC_NO;
if (!rgb_matrix_is_enabled()) {
/* Turn it ON, signal the cause (EFFECTS) */
rgb_matrix_set_flags(LED_FLAG_EFFECTS);
rgb_matrix_enable_noeeprom();
} else if (rgb_matrix_get_flags() == LED_FLAG_CAPS) {
/* It's already ON, promote the cause from CAPS to EFFECTS */
rgb_matrix_set_flags(LED_FLAG_EFFECTS);
} }
static bool is_delayed_press_pending(const uint16_t keycode) {
return delayed_press_start_time > 0 && delayed_press_keycode == keycode;
}
static bool is_delayed_press_sent(const uint16_t keycode) {
return delayed_press_sent_keycode != KC_NO && delayed_press_sent_keycode == keycode;
}
static void mark_delayed_press_sent(void) {
delayed_press_sent_keycode = delayed_press_keycode;
cancel_delayed_press();
}
static void mark_delayed_release_sent(void) {
delayed_press_sent_keycode = KC_NO;
}
static void cancel_delayed_press(void) {
delayed_press_delay = 0;
delayed_press_keycode = KC_NO;
delayed_press_start_time = 0;
#ifdef RGB_MATRIX_ENABLE
stop_effects();
#endif
}
#ifdef RGB_MATRIX_ENABLE
static void start_delayed_press_with_effects(
const uint16_t delay,
const uint16_t keycode,
const uint8_t r_color,
const uint8_t g_color,
const uint8_t b_color) {
start_delayed_press(delay, keycode);
start_effects(delay, r_color, g_color, b_color, increasing_effect);
}
/*
Effects when switching layers
*/
static uint8_t previous_layer = UINT8_MAX;
layer_state_t default_layer_state_set_user(layer_state_t state) {
const uint8_t current_layer = get_highest_layer(state);
if (previous_layer != current_layer) {
// For some reason, setting the default layer alone doesn't change it fully
layer_move(current_layer);
switch (current_layer) {
case WIN_BASE:
start_effects(EFFECTS_DURATION, WIN_BASE_COLOR, flashing_effect);
break;
case MAC_BASE:
start_effects(EFFECTS_DURATION, MAC_BASE_COLOR, flashing_effect);
break;
default:
// This should not ever happen, but let's display something if it does!
start_effects(EFFECTS_DURATION, UNKNOWN_LAYER_COLOR, static_effect);
break;
}
previous_layer = current_layer;
}
return state;
}
static void start_effects(
const uint16_t max_duration,
const uint8_t r_color,
const uint8_t g_color,
const uint8_t b_color,
const float (*multiplier)(const uint16_t)) {
effect_r = r_color;
effect_g = g_color;
effect_b = b_color;
effect_multiplier = multiplier;
effect_max_duration = max_duration;
effect_started_time = sync_timer_read();
}
static void stop_effects(void) {
effect_r = 0x0;
effect_g = 0x0;
effect_b = 0x0;
effect_multiplier = static_effect;
effect_max_duration = EFFECTS_DURATION;
effect_started_time = 0;
}
static float flashing_effect(const uint16_t delta_time) {
return ((delta_time / FLASHING_EFFECT_INTERVAL) + 1) & 0x01;
}
static float static_effect(const uint16_t delta_time) {
return 1.0;
}
static float increasing_effect(const uint16_t delta_time) {
return MAX(0.0, MIN(1.0, ((float) delta_time) / effect_max_duration));
}
bool rgb_matrix_indicators_user(void) {
if (effect_started_time > 0) {
const uint16_t delta_time = sync_timer_elapsed(effect_started_time);
if (delta_time <= effect_max_duration) {
/* Render effect */
const float multiplier = effect_multiplier(delta_time);
const uint8_t val_r = multiplier * effect_r;
const uint8_t val_g = multiplier * effect_g;
const uint8_t val_b = multiplier * effect_b;
rgb_matrix_set_color_all(val_r, val_g, val_b);
return false;
} else {
/* Effect duration is finished */
stop_effects();
}
}
if (host_keyboard_led_state().caps_lock) {
rgb_matrix_set_color_all(CAPS_LOCK_COLOR);
} else if (!user_config.rgb_enabled) {
rgb_matrix_set_color_all(RGB_OFF);
}
switch (get_highest_layer(layer_state)) {
case WIN_BASE:
case MAC_BASE:
break;
case WIN_FN:
set_rgb_layer_winfn();
return false;
case MAC_FN:
set_rgb_layer_macfn();
return false;
default:
// This should never happen, but if it does, let's display something!
rgb_matrix_set_color_all(UNKNOWN_LAYER_COLOR);
return false;
}
return true;
} }
// RGB led number layout, function of the key // RGB led number layout, function of the key
@ -298,38 +492,69 @@ static void start_effects(void) {
// 87, led 07 88, led 18 // 87, led 07 88, led 18
// 91, led 08 92, led 19 // 91, led 08 92, led 19
static void set_rgb_caps_leds(void) { static void set_rgb_layer_winfn(void) {
rgb_matrix_set_color(0, 0xFF, 0x0, 0x0); // ESC rgb_matrix_set_color(0, WIN_FN_COLOR);
rgb_matrix_set_color(6, 0xFF, 0x0, 0x0); // F1 rgb_matrix_set_color(6, WIN_FN_COLOR);
rgb_matrix_set_color(12, 0xFF, 0x0, 0x0); // F2 rgb_matrix_set_color(12, WIN_FN_COLOR);
rgb_matrix_set_color(18, 0xFF, 0x0, 0x0); // F3 rgb_matrix_set_color(18, WIN_FN_COLOR);
rgb_matrix_set_color(23, 0xFF, 0x0, 0x0); // F4 rgb_matrix_set_color(23, WIN_FN_COLOR);
rgb_matrix_set_color(28, 0xFF, 0x0, 0x0); // F5 rgb_matrix_set_color(28, WIN_FN_COLOR);
rgb_matrix_set_color(34, 0xFF, 0x0, 0x0); // F6 rgb_matrix_set_color(34, WIN_FN_COLOR);
rgb_matrix_set_color(39, 0xFF, 0x0, 0x0); // F7 rgb_matrix_set_color(39, WIN_FN_COLOR);
rgb_matrix_set_color(44, 0xFF, 0x0, 0x0); // F8 rgb_matrix_set_color(44, WIN_FN_COLOR);
rgb_matrix_set_color(50, 0xFF, 0x0, 0x0); // F9 rgb_matrix_set_color(50, WIN_FN_COLOR);
rgb_matrix_set_color(56, 0xFF, 0x0, 0x0); // F10 rgb_matrix_set_color(56, WIN_FN_COLOR);
rgb_matrix_set_color(61, 0xFF, 0x0, 0x0); // F11 rgb_matrix_set_color(61, WIN_FN_COLOR);
rgb_matrix_set_color(66, 0xFF, 0x0, 0x0); // F12 rgb_matrix_set_color(66, WIN_FN_COLOR);
rgb_matrix_set_color(69, 0xFF, 0x0, 0x0); // Prt rgb_matrix_set_color(2, WIN_FN_COLOR);
rgb_matrix_set_color(67, 0xFF, 0x0, 0x0); // Left side LED 1 rgb_matrix_set_color(3, WIN_FN_COLOR);
rgb_matrix_set_color(68, 0xFF, 0x0, 0x0); // Right side LED 1 rgb_matrix_set_color(8, WIN_FN_COLOR);
rgb_matrix_set_color(70, 0xFF, 0x0, 0x0); // Left side LED 2 rgb_matrix_set_color(9, WIN_FN_COLOR);
rgb_matrix_set_color(71, 0xFF, 0x0, 0x0); // Right side LED 2 rgb_matrix_set_color(14, WIN_FN_COLOR);
rgb_matrix_set_color(73, 0xFF, 0x0, 0x0); // Left side LED 3 rgb_matrix_set_color(15, WIN_FN_COLOR);
rgb_matrix_set_color(74, 0xFF, 0x0, 0x0); // Right side LED 3 rgb_matrix_set_color(20, WIN_FN_COLOR);
rgb_matrix_set_color(76, 0xFF, 0x0, 0x0); // Left side LED 4 rgb_matrix_set_color(21, WIN_FN_COLOR);
rgb_matrix_set_color(77, 0xFF, 0x0, 0x0); // Right side LED 4 rgb_matrix_set_color(25, WIN_FN_COLOR);
rgb_matrix_set_color(80, 0xFF, 0x0, 0x0); // Left side LED 5 rgb_matrix_set_color(26, WIN_FN_COLOR);
rgb_matrix_set_color(81, 0xFF, 0x0, 0x0); // Right side LED 5 rgb_matrix_set_color(38, WIN_FN_COLOR);
rgb_matrix_set_color(83, 0xFF, 0x0, 0x0); // Left side LED 6 rgb_matrix_set_color(93, WIN_FN_COLOR);
rgb_matrix_set_color(84, 0xFF, 0x0, 0x0); // Right side LED 6 rgb_matrix_set_color(72, WIN_FN_COLOR);
rgb_matrix_set_color(87, 0xFF, 0x0, 0x0); // Left side LED 7 rgb_matrix_set_color(75, WIN_FN_COLOR);
rgb_matrix_set_color(88, 0xFF, 0x0, 0x0); // Right side LED 7 rgb_matrix_set_color(86, WIN_FN_COLOR);
rgb_matrix_set_color(91, 0xFF, 0x0, 0x0); // Left side LED 8 rgb_matrix_set_color(82, WIN_FN_COLOR);
rgb_matrix_set_color(92, 0xFF, 0x0, 0x0); // Right side LED 8 }
rgb_matrix_set_color(3, 0xFF, 0x0, 0x0); // CAPS LED
static void set_rgb_layer_macfn(void) {
rgb_matrix_set_color(0, MAC_FN_COLOR);
rgb_matrix_set_color(6, MAC_FN_COLOR);
rgb_matrix_set_color(12, MAC_FN_COLOR);
rgb_matrix_set_color(18, MAC_FN_COLOR);
rgb_matrix_set_color(23, MAC_FN_COLOR);
rgb_matrix_set_color(28, MAC_FN_COLOR);
rgb_matrix_set_color(34, MAC_FN_COLOR);
rgb_matrix_set_color(39, MAC_FN_COLOR);
rgb_matrix_set_color(44, MAC_FN_COLOR);
rgb_matrix_set_color(50, MAC_FN_COLOR);
rgb_matrix_set_color(56, MAC_FN_COLOR);
rgb_matrix_set_color(61, MAC_FN_COLOR);
rgb_matrix_set_color(66, MAC_FN_COLOR);
rgb_matrix_set_color(2, MAC_FN_COLOR);
rgb_matrix_set_color(3, MAC_FN_COLOR);
rgb_matrix_set_color(8, MAC_FN_COLOR);
rgb_matrix_set_color(9, MAC_FN_COLOR);
rgb_matrix_set_color(14, MAC_FN_COLOR);
rgb_matrix_set_color(15, MAC_FN_COLOR);
rgb_matrix_set_color(20, MAC_FN_COLOR);
rgb_matrix_set_color(21, MAC_FN_COLOR);
rgb_matrix_set_color(25, MAC_FN_COLOR);
rgb_matrix_set_color(26, MAC_FN_COLOR);
rgb_matrix_set_color(38, MAC_FN_COLOR);
rgb_matrix_set_color(93, MAC_FN_COLOR);
rgb_matrix_set_color(72, MAC_FN_COLOR);
rgb_matrix_set_color(75, MAC_FN_COLOR);
rgb_matrix_set_color(86, MAC_FN_COLOR);
rgb_matrix_set_color(82, MAC_FN_COLOR);
rgb_matrix_set_color(17, MAC_FN_COLOR);
} }
#endif // RGB_MATRIX_ENABLE #endif // RGB_MATRIX_ENABLE

View File

@ -7,15 +7,23 @@ The differences are as follows:
- Dedicated MacOS and Windows/Linux layers - Dedicated MacOS and Windows/Linux layers
- Switching between them by pressing Fn + CAPS LOCK - Switching between them by pressing Fn + CAPS LOCK
- VIA support
- Disabled Mouse Keys (to fix issues with KVM switches and also because they're not used here anyway) - Disabled Mouse Keys (to fix issues with KVM switches and also because they're not used here anyway)
- RGB turns off after 20 minutes of inactivity - RGB turns off after 20 minutes of inactivity
- RGB turns off when USB is suspended - RGB turns off when USB is suspended
- Layer 0: - Layer 0:
- Print Screen (default) -> Delete - Delete -> Insert
- Delete (default) -> Home - Page Up -> Delete
- Page Down -> Home
- Layer 1 (accessed by pressing Fn): - Layer 1 (accessed by pressing Fn):
- Fn + Delete -> Insert - Fn + Insert -> Pause
- Fn + Home -> Print Screen - Fn + Delete -> Scroll Lock
- Fn + Esc -> Clear EEPROM
- Fn + (Left) CMD (macOS layout) -> Toggle the CMD + Q delay
On the Mac layer, pressing CMD + Q will not immediately send the combination.\
There's a configurable delay (defaults to 1 second) to send it.\
This is done mainly to prevent hitting CMD + Q by mistake when alternating between applications with CMD + Tab.
This keymap also includes CAPS LOCK ON indicator.\ This keymap also includes CAPS LOCK ON indicator.\
All left and right side LEDs, and the Caps key LED will turn solid red while CAPS LOCK is ON. All left and right side LEDs, and the Caps key LED will turn solid red while CAPS LOCK is ON.

View File

@ -3,21 +3,17 @@
# Disabling MouseKey because it breaks my KVM switch # Disabling MouseKey because it breaks my KVM switch
MOUSEKEY_ENABLE = no MOUSEKEY_ENABLE = no
# Cherry MX-style switches and diodes are not susceptible to noise, no need for noise-resistant algorithms. # Ensure sym_defer_g is used.
# This significantly reduces latency. # It seems sym_defer_pk results in significant chattering, even with an 8ms debounce time.
# DEBOUNCE_TYPE = sym_defer_g
# The matrix scan frequency seems to be around 1820 Hz, so even sym_defer_g would perform ok,
# but the "defer" part would mean we would wait DEBOUNCE ms before sending any events.
# Using "asym_eager_defer_pk" does not seem to benefit us in anything.
# The GMMK Pro has more then enough system resources for a per-key algorithm.
# Using an "eager" algorithm leads to extremely low latency while also reducing the chances of chattering
# due to it's "post-event" debouncing (of sorts).
#
# I have observed zero chattering or double-keypress issues on my Gateron Yellow switches.
# Most chattering issues on the GMMK Pro seem to be related to its proprietary hot-swap sockets anyway.
DEBOUNCE_TYPE = sym_eager_pk
# Useful for debugging # Useful for debugging
# CONSOLE_ENABLE = yes # CONSOLE_ENABLE = yes
# DEBUG_MATRIX_SCAN_RATE_ENABLE = yes # DEBUG_MATRIX_SCAN_RATE_ENABLE = yes
# DEBUG_MATRIX_SCAN_RATE = yes # DEBUG_MATRIX_SCAN_RATE = yes
# Encoder Map support
ENCODER_MAP_ENABLE = yes
# Enables VIA
VIA_ENABLE = yes