Просмотр исходного кода

QMK implementation of Selenium33

Fabien Cazenave 1 год назад
Родитель
Сommit
a9255a3740

+ 4 - 4
mods/atomic/kanata.kbd

@@ -38,14 +38,14 @@
 ;;-----------------------------------------------------------------------------
 ;; `Navigation` layer: ESDF or HJKL?
 
-(include deflayer_navigation.kbd)  ;; ESDF on the left, NumPad on the right
-;; (include deflayer_navigation_vim.kbd)  ;; HJKL + NumPad on [Space]+[Q]
+;; (include deflayer_navigation.kbd)  ;; ESDF on the left, NumPad on the right
+(include deflayer_navigation_vim.kbd)  ;; HJKL + NumPad on [Space]+[Q]
 
 ;; Replace XX by the keyboard shortcut of your application launcher, if any.
 ;; Mapped on [Space]+[P] in both navigation layers.
 
-;; (defalias run M-p)  ;; [Command]-[P]
-(defalias run XX)
+(defalias run M-p)  ;; [Command]-[P]
+;; (defalias run XX)
 
 
 ;;-----------------------------------------------------------------------------

+ 25 - 1
mods/selenium33/README.md

@@ -47,7 +47,31 @@ layer can be interesting to use in order to minimize finger movements further
 more. And it makes it easier to mix symbols with numbers (e.g. `[0]`).
 
 
-Download
+Implementations
 --------------------------------------------------------------------------------
 
+### Kanata
+
 ![kanata configuration](selenium.kbd)
+
+It turns out the `Atomic` mod can support all Selenium33 features smoothly.
+You should definitely use `Atomic` and tweak it to your liking instead of using
+this. :-)
+
+
+### QMK
+
+The QMK implementation is a bit different:
+
+- it takes advantage of the 4 thumb keys
+- the Navigation layer uses a mouse emulation on the left hand
+
+In fact, this is what I ended up with for my beloved Ferris in the first place,
+and Arsenik/Selenium is an attempt to fit most of this magic into my laptop keyboard.
+
+![QMK code](qmk/keyoards/ferris/keymaps/1dk)
+
+```bash
+# from the `qmk_firmware` root:
+make ferris/0_2/bling:1dk:flash
+```

+ 124 - 0
mods/selenium33/qmk/keyboards/ferris/keymaps/1dk/config.h

@@ -0,0 +1,124 @@
+#pragma once
+
+/**
+ * Sane defaults for homerow modifiers
+ */
+#define TAPPING_TERM 200
+#define TAPPING_FORCE_HOLD
+#undef  PERMISSIVE_HOLD
+#define IGNORE_MOD_TAP_INTERRUPT
+
+/**
+ * Sane defaults for combos
+ */
+#define COMBO_TERM 30
+
+/**
+ * Underglow configuration
+ */
+#ifdef RGBLIGHT_ENABLE
+#    define RGBLIGHT_EFFECT_BREATHING
+#    define RGBLIGHT_EFFECT_RAINBOW_MOOD
+#    define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+#    define RGBLIGHT_EFFECT_SNAKE
+#    define RGBLIGHT_EFFECT_KNIGHT
+#    define RGBLIGHT_EFFECT_CHRISTMAS
+#    define RGBLIGHT_EFFECT_STATIC_GRADIENT
+#    define RGBLIGHT_EFFECT_RGB_TEST
+#    define RGBLIGHT_EFFECT_ALTERNATING
+#    define RGBLIGHT_EFFECT_TWINKLE
+#    define RGBLIGHT_HUE_STEP 8
+#    define RGBLIGHT_SAT_STEP 8
+#    define RGBLIGHT_VAL_STEP 8
+#endif
+
+/**
+ * Mouse Keys Modes
+ *  - Accelerated: linear acceleration until the max speed is reached (default)
+ *  - Kinetic:  quadradic acceleration until the max speed is reached
+ *  - Inertia:  quadradic acceleration, and deceleration after key release
+ *  - Constant: constant speeds
+ *  - Combined: accelerated by default, constant speed when KC_ACLx is held
+ * https://docs.qmk.fm/#/feature_mouse_keys
+ */
+
+/**
+ * Accelerated Mode, default QMK settings
+// mouse cursor
+#define MOUSEKEY_DELAY              10
+#define MOUSEKEY_INTERVAL           20
+#define MOUSEKEY_MOVE_DELTA         8
+#define MOUSEKEY_MAX_SPEED          10
+#define MOUSEKEY_TIME_TO_MAX        30
+// mouse wheel
+#define MOUSEKEY_WHEEL_DELAY        10
+#define MOUSEKEY_WHEEL_INTERVAL     80
+#define MOUSEKEY_WHEEL_MAX_SPEED    8
+#define MOUSEKEY_WHEEL_TIME_TO_MAX  30
+ */
+
+/**
+ * Accelerated Mode, default Oryx settings
+ * https://github.com/manna-harbour/miryoku_qmk/blob/bdb9fd81e8aa2afb3882f7c0f6ae2d3ba448ac93/users/manna-harbour_miryoku/config.h#L23-L33
+ */
+#define MOUSEKEY_DELAY        0
+#define MOUSEKEY_INTERVAL     16 // matches 60 FPS
+#define MOUSEKEY_MAX_SPEED    6
+#define MOUSEKEY_TIME_TO_MAX  64
+#define MOUSEKEY_WHEEL_DELAY  0
+
+/**
+ * Kinetic Mode, default QMK settings
+#define MK_KINETIC_SPEED
+#define MOUSEKEY_DELAY                        5
+#define MOUSEKEY_INTERVAL                     10
+#define MOUSEKEY_MOVE_DELTA                   16
+#define MOUSEKEY_INITIAL_SPEED                100
+#define MOUSEKEY_BASE_SPEED                   5000
+#define MOUSEKEY_DECELERATED_SPEED            400
+#define MOUSEKEY_ACCELERATED_SPEED            3000
+#define MOUSEKEY_WHEEL_INITIAL_MOVEMENTS      16
+#define MOUSEKEY_WHEEL_BASE_MOVEMENTS         32
+#define MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS  48
+#define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS  8
+ */
+
+/**
+ * Inertia Mode, default QMK settings
+#define MOUSEKEY_INERTIA
+#define MOUSEKEY_DELAY        150
+#define MOUSEKEY_INTERVAL     16 // matches 60 FPS
+#define MOUSEKEY_MAX_SPEED    32
+#define MOUSEKEY_TIME_TO_MAX  32
+#define MOUSEKEY_FRICTION     24
+#define MOUSEKEY_MOVE_DELTA   1
+ */
+
+/**
+ * Inertia Mode, custom settings
+#define MOUSEKEY_INERTIA
+#define MOUSEKEY_DELAY        0
+#define MOUSEKEY_INTERVAL     16 // matches 60 FPS
+#define MOUSEKEY_MAX_SPEED    24
+#define MOUSEKEY_TIME_TO_MAX  24
+#define MOUSEKEY_FRICTION     24
+#define MOUSEKEY_MOVE_DELTA   1
+ */
+
+/**
+ * Constant Mode
+ * The settings below enable constant speed mode, which can be:
+ *  - momentary:     (hold) KC_ACL0 < KC_ACL1 < unmodified < KC_ACL2
+ *  - tap-to-select: (tap)  KC_ACL0 < KC_ACL1 < KC_ACL2
+#define MK_3_SPEED         // enables constant speed modes
+#define MK_MOMENTARY_ACCEL // enables momentary speed mode
+ */
+
+/**
+ * Combined Mode
+ * Adjusts the Accelerated mode top speed when KC_ACLx is held:
+ *  - KC_ACL0: minimal speed
+ *  - KC_ACL1: half the maximal (user defined) speed
+ *  - KC_ACL2: maximal (computer defined) speed
+#define MK_COMBINED
+ */

+ 157 - 0
mods/selenium33/qmk/keyboards/ferris/keymaps/1dk/keymap.c

@@ -0,0 +1,157 @@
+// https://docs.qmk.fm/#/feature_combo
+// https://docs.qmk.fm/#/feature_macros
+// https://docs.qmk.fm/#/feature_mouse_keys
+
+#include QMK_KEYBOARD_H
+
+// homerow mod-taps (aliases for readability + re-use in combo definitions)
+#define HM_A    LSFT_T(KC_A)
+#define HM_S    LGUI_T(KC_S)
+#define HM_D    LALT_T(KC_D)
+#define HM_F    LCTL_T(KC_F)
+#define HM_J    LCTL_T(KC_J)
+#define HM_K    LALT_T(KC_K)
+#define HM_L    LGUI_T(KC_L)
+#define HM_SCLN LSFT_T(KC_SCLN)
+
+// 1dk-specific key codes
+#define CC_1DK       KC_SCLN   // Lafayette: main dead key on [;]
+#define CC_SCLN LSFT(KC_COMM)  // ";" on Shift+[,]
+#define CC_COLN LSFT(KC_DOT)   // ":" on Shift+[.]
+#define CC_LT        KC_NUBS   // "<" on [Non-US-Backslash]
+#define CC_GT   LSFT(KC_NUBS)  // ">" on Shift+[Non-US-Backslash]
+
+// 1dk-specific macros
+enum macro_keycodes {
+    // dead key, number/sign
+    ODK_1 = SAFE_RANGE,
+    ODK_2,
+    ODK_3,
+    ODK_4,
+    ODK_5,
+    ODK_6,
+    ODK_7,
+    ODK_8,
+    ODK_9,
+    ODK_0,
+    ODK_MN,
+    ODK_EQ,
+    // dead key, shift + number/sign
+    ODK_S1,
+    ODK_S2,
+    ODK_S3,
+    ODK_S4,
+    ODK_S5,
+    ODK_S6,
+    ODK_S7,
+    ODK_S8,
+    ODK_S9,
+    ODK_S0,
+    ODK_SMN,
+    ODK_SEQ,
+};
+
+// keyboard layout
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+    // Base layer: QWERTY with home row mods and thumb mod-taps
+    [0] = LAYOUT_split_3x5_2(
+        KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,      KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,
+        HM_A,    HM_S,    HM_D,    HM_F,    KC_G,      KC_H,    HM_J,    HM_K,    HM_L,    HM_SCLN,
+        KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,      KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH,
+                    LT(2,KC_BSPC), LSFT_T(KC_ENT),     LT(3,KC_TAB), LT(1,KC_SPC)
+    ),
+
+    // Code layer: Lafayette/ErgoL AltGr symbols
+    [1] = LAYOUT_split_3x5_2(
+        KC_1,    KC_LBRC, KC_RBRC, KC_DLR,  KC_PERC,   KC_CIRC, KC_AMPR, KC_ASTR, KC_QUOT, KC_0,
+        KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_EQL,    KC_PLUS, KC_MINS, CC_LT,   CC_GT,   KC_DQUO,
+        KC_TILD, KC_GRV,  KC_PIPE, KC_UNDS, KC_PSLS,   KC_BSLS, KC_AT,   KC_HASH, KC_EXLM, KC_QUES,
+                                   KC_SPC,  KC_ENT,    KC_TRNS, KC_TRNS
+    ),
+
+    // Num layer: number row with 1dk+num macros and punctuation signs
+    [2] = LAYOUT_split_3x5_2(
+        KC_EXLM, ODK_2,   ODK_3,   ODK_5,   KC_PERC,   ODK_6,   ODK_7,   ODK_8,   ODK_9,   ODK_0,
+        KC_1,    KC_2,    KC_3,    KC_4,    KC_5,      KC_6,    KC_7,    KC_8,    KC_9,    KC_0,
+        ODK_S1,  ODK_S2,  ODK_S3,  ODK_S4,  ODK_S5,    ODK_SMN, ODK_MN,  CC_SCLN, CC_COLN, KC_QUES,
+                                   KC_TRNS, KC_TRNS,   KC_ESC,  LSFT(KC_SPC)
+    ),
+
+    // Navigation layer: arrow keys and mouse emulation (constant mode)
+    // (note: KC_BTN4/BTN5 should be the mouse prev/next buttons)
+    [3] = LAYOUT_split_3x5_2(
+#if defined(MK_3_SPEED) || defined(MK_COMBINED)
+        KC_BRIU, KC_BTN4, KC_MS_U, KC_BTN5, KC_VOLU,   KC_HOME, KC_PGDN, KC_PGUP, KC_END,  KC_DEL,
+        KC_BRID, KC_MS_L, KC_MS_D, KC_MS_R, KC_VOLD,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT, LSFT(KC_ENT),
+        KC_SLEP, KC_BTN3, KC_WH_U, KC_WH_D, KC_MUTE,   KC_NO,   KC_ACL0, KC_ACL1, KC_ACL2, KC_NO,
+                                   KC_BTN1, KC_BTN2,   KC_TRNS, KC_TRNS
+#else
+        KC_BRIU, KC_BTN4, KC_MS_U, KC_BTN5, KC_VOLU,   KC_HOME, KC_PGDN, KC_PGUP, KC_END,  KC_DEL,
+        KC_BRID, KC_MS_L, KC_MS_D, KC_MS_R, KC_VOLD,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT, LSFT(KC_ENT),
+        KC_SLEP, KC_NO,   KC_NO,   KC_BTN3, KC_MUTE,   KC_WH_L, KC_WH_D, KC_WH_U, KC_WH_R, KC_NO,
+                                   KC_BTN1, KC_BTN2,   KC_TRNS, KC_TRNS
+#endif
+    )
+
+};
+
+// https://getreuer.info/posts/keyboards/macros/#simple-macros
+#define RETURN_1DK(key) tap_code(CC_1DK); tap_code(key); return false;
+#define RETURN_S1DK(key) tap_code(CC_1DK); \
+    register_code(KC_LSFT); tap_code(key); unregister_code(KC_LSFT); \
+    return false;
+bool process_record_user(uint16_t keycode, keyrecord_t* record) {
+    if (record->event.pressed) switch (keycode) {
+        // send dead key + number/sign
+        case ODK_1 ... ODK_0: RETURN_1DK(KC_1 + keycode - ODK_1);
+        case ODK_MN:          RETURN_1DK(KC_MINS);
+        case ODK_EQ:          RETURN_1DK(KC_EQL);
+        // send dead key + shift + number/sign
+        case ODK_S1 ... ODK_S0: RETURN_S1DK(KC_1 + keycode - ODK_S1);
+        case ODK_SMN:           RETURN_S1DK(KC_MINS);
+        case ODK_SEQ:           RETURN_S1DK(KC_EQL);
+    }
+    return true;
+}
+
+/**
+ * Combos
+ */
+
+#ifdef COMBO_ENABLE
+
+enum combos {
+    COMBO_DF,
+    COMBO_JK,
+    COMBO_DOT_COMM,
+    COMBO_COUNT
+};
+uint16_t COMBO_LEN = COMBO_COUNT; // required by the COMBO macro
+const uint16_t PROGMEM df_combo[]       = {HM_D,    HM_F,    COMBO_END};
+const uint16_t PROGMEM jk_combo[]       = {HM_J,    HM_K,    COMBO_END};
+const uint16_t PROGMEM dot_comm_combo[] = {KC_DOT,  KC_COMM, COMBO_END};
+
+combo_t key_combos[COMBO_COUNT] = {
+    [COMBO_DF] = COMBO(df_combo, KC_ENT),
+    [COMBO_JK] = COMBO(jk_combo, KC_ESC),
+    [COMBO_DOT_COMM] = COMBO_ACTION(dot_comm_combo),
+};
+
+void process_combo_event(uint16_t combo_index, bool pressed) {
+    if (pressed) switch(combo_index) {
+        case COMBO_DOT_COMM:
+            tap_code16(LCTL(KC_BSPC));
+            break;
+    }
+}
+
+#endif
+
+/**
+ * Rotary encoders
+ */
+
+#if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
+const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {};
+#endif // defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)

+ 4 - 0
mods/selenium33/qmk/keyboards/ferris/keymaps/1dk/rules.mk

@@ -0,0 +1,4 @@
+BOOTMAGIC_ENABLE = yes      # Enable Bootmagic Lite
+TAP_DANCE_ENABLE = no
+ENCODER_ENABLE = no
+COMBO_ENABLE = yes

+ 23 - 15
mods/selenium33/selenium.kbd

@@ -13,18 +13,26 @@
 (defsrc
   q    w    e    r    t         y    u    i    o    p
   a    s    d    f    g         h    j    k    l    ;
-  z    x    c    v    b         n    m    ,    .    /
-            lalt          spc             ralt
+  z    x    c    v    b   102d  n    m    ,    .    /
+            lalt           spc            ralt
 )
 
+;; Use this instead if you want to apply an angle mod:
+;; (defsrc
+;;   q    w    e    r    t         y    u    i    o    p
+;;   a    s    d    f    g         h    j    k    l    ;
+;;   102d z    x    c    v    b    n    m    ,    .    /
+;;             lalt           spc            ralt
+;; )
+
 ;; Base layer (active by default when kanata starts up):
 ;;  - the 3 main thumb keys become mod/taps
 ;;  - home-row mods on SDF and JKL
 ;;  - CapsLock becomes Escape
 (deflayer qwerty
-  _    _    _    _    _         _    _    _    _    _    
-  _    @ss  @dd  @ff  _         _    @jj  @kk  @ll  _    
-  _    _    _    _    _         _    _    _    _    _    
+  q    w    e    r    t         y    u    i    o    p
+  a    @ss  @dd  @ff  g         h    @jj  @kk  @ll  ;
+  z    x    c    v    b   102d  n    m    ,    .    /
             @sft          @nav            @ssm
 )
 
@@ -32,7 +40,7 @@
 (deflayer symbols
   AG-q AG-w AG-e AG-r AG-t      AG-y AG-u AG-i AG-o AG-p
   AG-a AG-s AG-d AG-f AG-g      AG-h AG-j AG-k AG-l AG-;
-  AG-z AG-x AG-c AG-v AG-b      AG-n AG-m AG-, AG-. AG-/
+  AG-z AG-x AG-c AG-v AG-b  _   AG-n AG-m AG-, AG-. AG-/
             @num           spc            @sym
 )
 
@@ -40,7 +48,7 @@
 (deflayer numrow
   S-1  S-2  S-3  S-4  S-5       S-6  S-7  S-8  S-9  S-0
   1    2    3    4    5         6    7    8    9    0
-  @dk1 @dk2 @dk3 @dk4 @dk5      XX   -    ,    .    /
+  @dk1 @dk2 @dk3 @dk4 @dk5  _   XX   -    ,    .    /
             @num          S-spc           @sym
 )
 
@@ -50,7 +58,7 @@
 (deflayer numpad
   XX   home up   end  pgup      XX   7    8    9    XX
   XX   lft  down rght pgdn      -    4    5    6    0
-  XX   XX   XX   XX   XX        ,    1    2    3    .
+  XX   XX   XX   XX   XX    _   ,    1    2    3    .
             @std           spc            @std
 )
 
@@ -63,8 +71,8 @@
 (deflayer numnav
   tab  _    _    _    _         _    _    _    _    _
   @all _    _    _    _         _    _    _    _    _
-  @ndo @cut @cpy @pst S-tab     _    _    _    _    _
-            _              _              _
+  @ndo @cut @cpy @pst S-tab _   _    _    _    _    _
+            _               _             _
 )
 
 ;; Vim-Navigation layer:
@@ -74,18 +82,18 @@
 ;; The `lrld` action stands for "live reload". This will re-parse everything
 ;; except for linux-dev, i.e. you cannot live reload and switch keyboard devices.
 (deflayer vimnav
-  @pad @cls bck  fwd  XX        home pgdn pgup end  M-p
+  @pad @cls bck  fwd  XX        home pgdn pgup end  XX
   @all @sav S-tab tab XX        lft  down up   rght @fun
-  @ndo @cut @cpy @pst XX        @mwl @mwd @mwu @mwr XX
-            del            _              esc
+  @ndo @cut @cpy @pst XX    _   @mwl @mwd @mwu @mwr XX
+            del             _             esc
 )
 
 ;; Function layer
 (deflayer funpad
   f1   f2   f3   f4   XX        XX   XX   XX   XX   XX
   f5   f6   f7   f8   XX        XX   lctl lalt lmet _
-  f9   f10  f11  f12  XX        XX   XX   XX   XX   XX
-            _              _              _
+  f9   f10  f11  f12  XX    _   XX   XX   XX   XX   XX
+            _               _             _
 )
 
 ;; `defalias` is used to declare a shortcut for a more complicated action to keep