More os modes
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
#include QMK_KEYBOARD_H
|
#include QMK_KEYBOARD_H
|
||||||
#include "keymap_introspection.h"
|
#include "keymap_introspection.h"
|
||||||
#include "dynamic_keymap.h"
|
#include "dynamic_keymap.h"
|
||||||
#include "mac_mode.h"
|
#include "os_mode.h"
|
||||||
|
|
||||||
enum custom_keycodes {
|
enum custom_keycodes {
|
||||||
CK_MCMD = SAFE_RANGE, // toggle mac-command mode
|
CK_OSMODE = SAFE_RANGE, // cycle OS mode
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -121,7 +121,7 @@ ________________________________________________________________________________
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
[1] = LAYOUT(
|
[1] = LAYOUT(
|
||||||
QK_BOOT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, CK_MCMD, KC_MPLY,
|
QK_BOOT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, CK_OSMODE, KC_MPLY,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_VAD, RGB_VAI, KC_TRNS, KC_VOLU,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_VAD, RGB_VAI, KC_TRNS, KC_VOLU,
|
||||||
KC_PSCR, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLD,
|
KC_PSCR, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLD,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_MUTE,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_MUTE,
|
||||||
@@ -148,62 +148,65 @@ ________________________________________________________________________________
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Override layer resolution: in mac mode, any modifier forces layer 0 (ignores FN)
|
// Override layer resolution: any modifier forces layer 0 (ignores FN)
|
||||||
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) {
|
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) {
|
||||||
if (mac_mode && (get_mods() & (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI))) {
|
if (os_mode != OS_MODE_NONE && get_mods()) {
|
||||||
layer = 0;
|
layer = 0;
|
||||||
}
|
}
|
||||||
if (key.row < MATRIX_ROWS && key.col < MATRIX_COLS) {
|
|
||||||
return keycode_at_keymap_location(layer, key.row, key.col);
|
return keycode_at_keymap_location(layer, key.row, key.col);
|
||||||
}
|
|
||||||
return KC_NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gui_tapped = false;
|
static bool super_tapped = false;
|
||||||
|
|
||||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
// Cycle OS mode (FN+Del)
|
||||||
|
if (keycode == CK_OSMODE) {
|
||||||
|
if (record->event.pressed) {
|
||||||
|
os_mode = (os_mode + 1) % 4;
|
||||||
|
os_mode_manual = true;
|
||||||
|
rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_COLOR);
|
||||||
|
switch (os_mode) {
|
||||||
|
case OS_MODE_NONE: rgb_matrix_sethsv_noeeprom(HSV_RED); break;
|
||||||
|
case OS_MODE_LINUX: rgb_matrix_sethsv_noeeprom(HSV_GREEN); break;
|
||||||
|
case OS_MODE_MAC: rgb_matrix_sethsv_noeeprom(HSV_YELLOW); break;
|
||||||
|
case OS_MODE_WINDOWS: rgb_matrix_sethsv_noeeprom(HSV_BLUE); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No rewrites in none mode
|
||||||
|
if (os_mode == OS_MODE_NONE) return true;
|
||||||
|
|
||||||
// Any other key pressed while GUI held means it's being used as a modifier
|
// Any other key pressed while GUI held means it's being used as a modifier
|
||||||
if (record->event.pressed && keycode != KC_LGUI) {
|
if (record->event.pressed && keycode != KC_LGUI) {
|
||||||
gui_tapped = false;
|
super_tapped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (keycode) {
|
switch (keycode) {
|
||||||
// Mac mode: tap Super -> Cmd+Space (Spotlight)
|
// Mac mode: tap Super -> Cmd+Space (Spotlight)
|
||||||
// Linux: tap Super passes through normally (KDE app menu)
|
// Linux/Windows: tap Super passes through normally (KDE app menu)
|
||||||
case KC_LGUI:
|
case KC_LGUI:
|
||||||
if (mac_mode) {
|
if (os_mode == OS_MODE_MAC) {
|
||||||
if (record->event.pressed) {
|
if (record->event.pressed) {
|
||||||
gui_tapped = true;
|
super_tapped = true;
|
||||||
register_mods(MOD_BIT(KC_LGUI));
|
register_mods(MOD_BIT(KC_LGUI));
|
||||||
} else {
|
} else {
|
||||||
if (gui_tapped) {
|
if (super_tapped) {
|
||||||
tap_code(KC_SPC); // GUI still held, sends Super+Space
|
tap_code(KC_SPC); // GUI still held, sends Super+Space
|
||||||
gui_tapped = false;
|
super_tapped = false;
|
||||||
}
|
}
|
||||||
unregister_mods(MOD_BIT(KC_LGUI));
|
unregister_mods(MOD_BIT(KC_LGUI));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CK_MCMD:
|
|
||||||
if (record->event.pressed) {
|
|
||||||
mac_mode = !mac_mode;
|
|
||||||
mac_mode_manual = true;
|
|
||||||
// Flash LEDs to indicate mode: green = mac, red = normal
|
|
||||||
rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_COLOR);
|
|
||||||
if (mac_mode) {
|
|
||||||
rgb_matrix_sethsv_noeeprom(HSV_GREEN);
|
|
||||||
} else {
|
|
||||||
rgb_matrix_sethsv_noeeprom(HSV_BLUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
// Mac mode rewrites:
|
// Mac mode rewrites:
|
||||||
// Ctrl+C/V -> Super+C/V (copy/paste)
|
// Ctrl+C/V -> Super+C/V (copy/paste)
|
||||||
// Ctrl+Shift+C/V -> Super+C/V (terminal copy/paste)
|
// Ctrl+Shift+C/V -> Super+C/V (terminal copy/paste)
|
||||||
case KC_C:
|
case KC_C:
|
||||||
case KC_V:
|
case KC_V:
|
||||||
if (mac_mode && record->event.pressed) {
|
if (os_mode == OS_MODE_MAC && record->event.pressed) {
|
||||||
if (rewrite_mods(keycode, CTRL_TO_SUPER)) return false;
|
if (rewrite_mods(keycode, CTRL_TO_SUPER)) return false;
|
||||||
if (rewrite_mods(keycode, CTRL_SHIFT_TO_SUPER)) return false;
|
if (rewrite_mods(keycode, CTRL_SHIFT_TO_SUPER)) return false;
|
||||||
}
|
}
|
||||||
@@ -218,7 +221,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
case KC_W:
|
case KC_W:
|
||||||
case KC_L:
|
case KC_L:
|
||||||
case KC_R:
|
case KC_R:
|
||||||
if (mac_mode && record->event.pressed) {
|
if (os_mode == OS_MODE_MAC && record->event.pressed) {
|
||||||
if (rewrite_mods(keycode, CTRL_TO_SUPER)) return false;
|
if (rewrite_mods(keycode, CTRL_TO_SUPER)) return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -228,7 +231,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
case KC_Z:
|
case KC_Z:
|
||||||
case KC_T:
|
case KC_T:
|
||||||
case KC_N:
|
case KC_N:
|
||||||
if (mac_mode && record->event.pressed) {
|
if (os_mode == OS_MODE_MAC && record->event.pressed) {
|
||||||
if (rewrite_mods(keycode, CTRL_TO_SUPER)) return false;
|
if (rewrite_mods(keycode, CTRL_TO_SUPER)) return false;
|
||||||
if (rewrite_mods(keycode, CTRL_SHIFT_TO_CMD_SHIFT)) return false;
|
if (rewrite_mods(keycode, CTRL_SHIFT_TO_CMD_SHIFT)) return false;
|
||||||
}
|
}
|
||||||
@@ -238,7 +241,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
// Ctrl+Left/Right -> Alt+Left/Right (word navigation)
|
// Ctrl+Left/Right -> Alt+Left/Right (word navigation)
|
||||||
case KC_LEFT:
|
case KC_LEFT:
|
||||||
case KC_RGHT:
|
case KC_RGHT:
|
||||||
if (mac_mode && record->event.pressed) {
|
if (os_mode == OS_MODE_MAC && record->event.pressed) {
|
||||||
if (rewrite_mods(keycode, CTRL_ALT_TO_CTRL)) return false;
|
if (rewrite_mods(keycode, CTRL_ALT_TO_CTRL)) return false;
|
||||||
if (rewrite_mods(keycode, CTRL_TO_ALT)) return false;
|
if (rewrite_mods(keycode, CTRL_TO_ALT)) return false;
|
||||||
}
|
}
|
||||||
@@ -246,7 +249,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
// Mac mode rewrites:
|
// Mac mode rewrites:
|
||||||
// Ctrl+Backspace -> Alt+Backspace (delete word backward)
|
// Ctrl+Backspace -> Alt+Backspace (delete word backward)
|
||||||
case KC_BSPC:
|
case KC_BSPC:
|
||||||
if (mac_mode && record->event.pressed) {
|
if (os_mode == OS_MODE_MAC && record->event.pressed) {
|
||||||
if (rewrite_mods(keycode, CTRL_TO_ALT)) return false;
|
if (rewrite_mods(keycode, CTRL_TO_ALT)) return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -254,38 +257,41 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
// Home -> Super+Left (line start)
|
// Home -> Super+Left (line start)
|
||||||
// End -> Super+Right (line end)
|
// End -> Super+Right (line end)
|
||||||
case KC_HOME:
|
case KC_HOME:
|
||||||
if (mac_mode && record->event.pressed) {
|
if (os_mode == OS_MODE_MAC && record->event.pressed) {
|
||||||
if (rewrite_mods_and_key(NONE_TO_SUPER, KC_LEFT)) return false;
|
if (rewrite_mods_and_key(NONE_TO_SUPER, KC_LEFT)) return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KC_END:
|
case KC_END:
|
||||||
if (mac_mode && record->event.pressed) {
|
if (os_mode == OS_MODE_MAC && record->event.pressed) {
|
||||||
if (rewrite_mods_and_key(NONE_TO_SUPER, KC_RGHT)) return false;
|
if (rewrite_mods_and_key(NONE_TO_SUPER, KC_RGHT)) return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// Mac mode rewrites:
|
// Mac mode rewrites:
|
||||||
// Alt+F4 -> Super+Q (quit app)
|
// Alt+F4 -> Super+Q (quit app)
|
||||||
case KC_F4:
|
case KC_F4:
|
||||||
if (mac_mode && record->event.pressed) {
|
if (os_mode == OS_MODE_MAC && record->event.pressed) {
|
||||||
if (rewrite_mods_and_key(ALT_TO_SUPER, KC_Q)) return false;
|
if (rewrite_mods_and_key(ALT_TO_SUPER, KC_Q)) return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// Mac mode rewrites:
|
// Mac mode rewrites:
|
||||||
// Alt+Tab -> Super+Tab (app switcher)
|
// Alt+Tab -> Super+Tab (app switcher)
|
||||||
case KC_TAB:
|
case KC_TAB:
|
||||||
if (mac_mode && record->event.pressed) {
|
if (os_mode == OS_MODE_MAC && record->event.pressed) {
|
||||||
if (rewrite_mods(keycode, ALT_TO_SUPER)) return false;
|
if (rewrite_mods(keycode, ALT_TO_SUPER)) return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// Workspace overview (both modes):
|
// Workspace overview:
|
||||||
// Super+Up -> Super+W (KDE overview, linux)
|
// Super+Up -> Super+W (KDE overview, linux)
|
||||||
// Super+Up -> Ctrl+Up (Mission Control, mac)
|
// Super+Up -> Ctrl+Up (Mission Control, mac)
|
||||||
|
// Super+Up -> Super+Tab (Task View, windows)
|
||||||
case KC_UP:
|
case KC_UP:
|
||||||
if (record->event.pressed) {
|
if (record->event.pressed) {
|
||||||
if (mac_mode) {
|
if (os_mode == OS_MODE_MAC) {
|
||||||
if (rewrite_mods(keycode, SUPER_TO_CTRL)) return false;
|
if (rewrite_mods(keycode, SUPER_TO_CTRL)) return false;
|
||||||
} else {
|
} else if (os_mode == OS_MODE_LINUX) {
|
||||||
if (rewrite_mods_and_key(SUPER_TO_SUPER, KC_W)) return false;
|
if (rewrite_mods_and_key(SUPER_TO_SUPER, KC_W)) return false;
|
||||||
|
} else if (os_mode == OS_MODE_WINDOWS) {
|
||||||
|
if (rewrite_mods_and_key(SUPER_TO_SUPER, KC_TAB)) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
extern bool mac_mode;
|
|
||||||
extern bool mac_mode_manual;
|
|
||||||
@@ -2,28 +2,48 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "rgb_matrix.h"
|
#include "rgb_matrix.h"
|
||||||
|
|
||||||
#include "mac_mode.h"
|
#include "os_mode.h"
|
||||||
|
|
||||||
bool mac_mode = false;
|
os_mode_t os_mode = OS_MODE_NONE;
|
||||||
bool mac_mode_manual = false;
|
bool os_mode_manual = false;
|
||||||
static bool os_detected = false;
|
static bool os_detected = false;
|
||||||
static uint32_t flash_start = 0;
|
static uint32_t flash_start = 0;
|
||||||
|
|
||||||
|
static void flash_mode_color(void) {
|
||||||
|
rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_COLOR);
|
||||||
|
switch (os_mode) {
|
||||||
|
case OS_MODE_NONE: rgb_matrix_sethsv_noeeprom(HSV_RED); break;
|
||||||
|
case OS_MODE_LINUX: rgb_matrix_sethsv_noeeprom(HSV_GREEN); break;
|
||||||
|
case OS_MODE_MAC: rgb_matrix_sethsv_noeeprom(HSV_YELLOW); break;
|
||||||
|
case OS_MODE_WINDOWS: rgb_matrix_sethsv_noeeprom(HSV_BLUE); break;
|
||||||
|
}
|
||||||
|
flash_start = timer_read32();
|
||||||
|
}
|
||||||
|
|
||||||
// Poll OS detection after USB enumeration settles (~2s)
|
// Poll OS detection after USB enumeration settles (~2s)
|
||||||
// Flash indicator color for 500ms then restore default animation
|
// Flash indicator color for 500ms then restore default animation
|
||||||
void matrix_scan_user(void) {
|
void matrix_scan_user(void) {
|
||||||
if (!os_detected && !mac_mode_manual && timer_elapsed32(0) > 2000) {
|
if (!os_detected && !os_mode_manual && timer_elapsed32(0) > 2000) {
|
||||||
os_detected = true;
|
os_detected = true;
|
||||||
os_variant_t os = detected_host_os();
|
os_variant_t os = detected_host_os();
|
||||||
mac_mode = (os == OS_MACOS || os == OS_IOS);
|
switch (os) {
|
||||||
rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_COLOR);
|
case OS_MACOS:
|
||||||
if (mac_mode) {
|
case OS_IOS:
|
||||||
rgb_matrix_sethsv_noeeprom(HSV_GREEN);
|
os_mode = OS_MODE_MAC;
|
||||||
} else {
|
break;
|
||||||
rgb_matrix_sethsv_noeeprom(HSV_BLUE);
|
case OS_LINUX:
|
||||||
|
os_mode = OS_MODE_LINUX;
|
||||||
|
break;
|
||||||
|
case OS_WINDOWS:
|
||||||
|
os_mode = OS_MODE_WINDOWS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
os_mode = OS_MODE_NONE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
flash_start = timer_read32();
|
flash_mode_color();
|
||||||
}
|
}
|
||||||
|
// Restore default RGB animation after 500ms indicator flash
|
||||||
if (flash_start && timer_elapsed32(flash_start) > 500) {
|
if (flash_start && timer_elapsed32(flash_start) > 500) {
|
||||||
flash_start = 0;
|
flash_start = 0;
|
||||||
rgb_matrix_reload_from_eeprom();
|
rgb_matrix_reload_from_eeprom();
|
||||||
|
|||||||
18
keymaps/custom/os_mode.h
Normal file
18
keymaps/custom/os_mode.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// Active OS mode, determines which shortcut rewrites are applied.
|
||||||
|
// Set automatically by OS detection or manually via FN+Del cycle.
|
||||||
|
typedef enum {
|
||||||
|
OS_MODE_NONE, // no shortcut rewrites
|
||||||
|
OS_MODE_LINUX, // linux-specific rewrites (e.g. Super+Up -> Super+W)
|
||||||
|
OS_MODE_MAC, // Ctrl->Super rewrites, Spotlight tap, etc.
|
||||||
|
OS_MODE_WINDOWS, // reserved, currently same as none
|
||||||
|
} os_mode_t;
|
||||||
|
|
||||||
|
// Current mode, defined in os_detect.c
|
||||||
|
extern os_mode_t os_mode;
|
||||||
|
|
||||||
|
// True once user manually cycles mode via FN+Del, prevents OS detection override
|
||||||
|
extern bool os_mode_manual;
|
||||||
Reference in New Issue
Block a user