Browse Source

QMK implementation of Selenium33

Fabien Cazenave 1 year ago
parent
commit
a9255a3740

+ 4 - 4
mods/atomic/kanata.kbd

@@ -38,14 +38,14 @@
 ;;-----------------------------------------------------------------------------
 ;;-----------------------------------------------------------------------------
 ;; `Navigation` layer: ESDF or HJKL?
 ;; `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.
 ;; Replace XX by the keyboard shortcut of your application launcher, if any.
 ;; Mapped on [Space]+[P] in both navigation layers.
 ;; 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]`).
 more. And it makes it easier to mix symbols with numbers (e.g. `[0]`).
 
 
 
 
-Download
+Implementations
 --------------------------------------------------------------------------------
 --------------------------------------------------------------------------------
 
 
+### Kanata
+
 ![kanata configuration](selenium.kbd)
 ![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
 (defsrc
   q    w    e    r    t         y    u    i    o    p
   q    w    e    r    t         y    u    i    o    p
   a    s    d    f    g         h    j    k    l    ;
   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):
 ;; Base layer (active by default when kanata starts up):
 ;;  - the 3 main thumb keys become mod/taps
 ;;  - the 3 main thumb keys become mod/taps
 ;;  - home-row mods on SDF and JKL
 ;;  - home-row mods on SDF and JKL
 ;;  - CapsLock becomes Escape
 ;;  - CapsLock becomes Escape
 (deflayer qwerty
 (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
             @sft          @nav            @ssm
 )
 )
 
 
@@ -32,7 +40,7 @@
 (deflayer symbols
 (deflayer symbols
   AG-q AG-w AG-e AG-r AG-t      AG-y AG-u AG-i AG-o AG-p
   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-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
             @num           spc            @sym
 )
 )
 
 
@@ -40,7 +48,7 @@
 (deflayer numrow
 (deflayer numrow
   S-1  S-2  S-3  S-4  S-5       S-6  S-7  S-8  S-9  S-0
   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
   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
             @num          S-spc           @sym
 )
 )
 
 
@@ -50,7 +58,7 @@
 (deflayer numpad
 (deflayer numpad
   XX   home up   end  pgup      XX   7    8    9    XX
   XX   home up   end  pgup      XX   7    8    9    XX
   XX   lft  down rght pgdn      -    4    5    6    0
   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
             @std           spc            @std
 )
 )
 
 
@@ -63,8 +71,8 @@
 (deflayer numnav
 (deflayer numnav
   tab  _    _    _    _         _    _    _    _    _
   tab  _    _    _    _         _    _    _    _    _
   @all _    _    _    _         _    _    _    _    _
   @all _    _    _    _         _    _    _    _    _
-  @ndo @cut @cpy @pst S-tab     _    _    _    _    _
-            _              _              _
+  @ndo @cut @cpy @pst S-tab _   _    _    _    _    _
+            _               _             _
 )
 )
 
 
 ;; Vim-Navigation layer:
 ;; Vim-Navigation layer:
@@ -74,18 +82,18 @@
 ;; The `lrld` action stands for "live reload". This will re-parse everything
 ;; 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.
 ;; except for linux-dev, i.e. you cannot live reload and switch keyboard devices.
 (deflayer vimnav
 (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
   @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
 ;; Function layer
 (deflayer funpad
 (deflayer funpad
   f1   f2   f3   f4   XX        XX   XX   XX   XX   XX
   f1   f2   f3   f4   XX        XX   XX   XX   XX   XX
   f5   f6   f7   f8   XX        XX   lctl lalt lmet _
   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
 ;; `defalias` is used to declare a shortcut for a more complicated action to keep