~andrew/qmk

67ccb462c37357137fbaa4b750bf5cc76eef278d — Andrew Reisner 4 months ago d5d1bb3
Add Charybdis keyboard.
M flake.lock => flake.lock +20 -0
@@ 1,5 1,24 @@
{
  "nodes": {
    "bastardkb-qmk-firmware": {
      "flake": false,
      "locked": {
        "lastModified": 1754834270,
        "narHash": "sha256-Y3r9yuydAUL6ApQphGMJr2XmsZNrCQY4AwYJlHYVrPE=",
        "ref": "refs/heads/bkb-master",
        "rev": "8f3b92fff27e6356120913a4ec6b21a017d0fef6",
        "revCount": 28842,
        "submodules": true,
        "type": "git",
        "url": "https://github.com/Bastardkb/bastardkb-qmk"
      },
      "original": {
        "ref": "refs/heads/bkb-master",
        "submodules": true,
        "type": "git",
        "url": "https://github.com/Bastardkb/bastardkb-qmk"
      }
    },
    "flake-utils": {
      "inputs": {
        "systems": "systems"


@@ 72,6 91,7 @@
    },
    "root": {
      "inputs": {
        "bastardkb-qmk-firmware": "bastardkb-qmk-firmware",
        "flake-utils": "flake-utils",
        "keyball-qmk-firmware": "keyball-qmk-firmware",
        "nixpkgs": "nixpkgs",

M flake.nix => flake.nix +52 -16
@@ 11,6 11,12 @@
      flake = false;
    };

    # BastardKB QMK fork (for Charybdis RP2040/Splinky UF2 builds)
    bastardkb-qmk-firmware = {
      url = "git+https://github.com/Bastardkb/bastardkb-qmk?ref=refs/heads/bkb-master&submodules=1";
      flake = false;
    };

    # ZSA fork of QMK firmware (for Voyager, Moonlander, Planck EZ, Ergodox EZ)
    zsa-qmk-firmware = {
      url = "git+https://github.com/zsa/qmk_firmware?submodules=1";


@@ 24,7 30,7 @@
    };
  };

  outputs = { self, nixpkgs, flake-utils, qmk-firmware, zsa-qmk-firmware, keyball-qmk-firmware }:
  outputs = { self, nixpkgs, flake-utils, qmk-firmware, zsa-qmk-firmware, keyball-qmk-firmware, bastardkb-qmk-firmware }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs {


@@ 62,6 68,7 @@
            milc
            pygments
            dotty-dict
            intelhex
          ]))

          # Additional dependencies


@@ 74,34 81,48 @@

        # Helper to link userspace into QMK firmware
        setupUserspace = qmkSrc: pkgs.runCommand "qmk-with-userspace" {} ''
          cp -r ${qmkSrc} $out
          chmod -R +w $out
          mkdir -p "$out"
          # Dereference symlinks from source snapshot so overlay writes stay in $out.
          cp -rL ${qmkSrc}/. "$out"
          chmod -R u+w "$out"
          # Recreate overlay roots as writable real directories.
          for d in keyboards users layouts; do
            rm -rf "$out/$d"
            mkdir -p "$out/$d"
            if [ -d "${qmkSrc}/$d" ]; then
              cp -rL "${qmkSrc}/$d"/. "$out/$d/"
            fi
          done
          chmod -R u+w "$out/keyboards" "$out/users" "$out/layouts"

          # Link keyboards from userspace
          if [ -d ${self}/keyboards ]; then
            for kb in ${self}/keyboards/*; do
              kbname=$(basename $kb)
          if [ -d "${self}/keyboards" ]; then
            for kb in "${self}"/keyboards/*; do
              [ -e "$kb" ] || continue
              kbname=$(basename "$kb")
              if [ -d "$out/keyboards/$kbname" ]; then
                # Merge with existing keyboard (copy keymaps)
                cp -r $kb/* $out/keyboards/$kbname/ 2>/dev/null || true
                cp -r "$kb"/. "$out/keyboards/$kbname/"
              else
                # New keyboard, copy entirely
                cp -r $kb $out/keyboards/
                cp -r "$kb" "$out/keyboards/"
              fi
            done
          fi

          # Link users directory
          if [ -d ${self}/users ]; then
            cp -r ${self}/users/* $out/users/ 2>/dev/null || true
          if [ -d "${self}/users" ]; then
            mkdir -p "$out/users"
            cp -r "${self}/users"/. "$out/users/"
          fi

          # Link layouts
          if [ -d ${self}/layouts ]; then
            for layout in ${self}/layouts/*; do
              layoutname=$(basename $layout)
              mkdir -p $out/layouts/$layoutname
              cp -r $layout/* $out/layouts/$layoutname/ 2>/dev/null || true
          if [ -d "${self}/layouts" ]; then
            for layout in "${self}"/layouts/*; do
              [ -e "$layout" ] || continue
              layoutname=$(basename "$layout")
              mkdir -p "$out/layouts/$layoutname"
              cp -r "$layout"/. "$out/layouts/$layoutname/"
            done
          fi
        '';


@@ 110,6 131,7 @@
        qmkUpstream = setupUserspace qmk-firmware;
        qmkZsa = setupUserspace zsa-qmk-firmware;
        qmkKeyball = setupUserspace keyball-qmk-firmware;
        qmkBastard = setupUserspace bastardkb-qmk-firmware;

        # Build a QMK firmware
        buildFirmware = { name, keyboard, keymap, qmkSource }:


@@ 129,7 151,8 @@
              mkdir -p $HOME

              # Build the firmware
              make ${keyboard}:${keymap}
              make ${keyboard}:${keymap} \
                UF2CONV="${pkgs.python3}/bin/python3 util/uf2conv.py"

              runHook postBuild
            '';


@@ 183,7 206,16 @@
            qmkSource = qmkKeyball;
          };

          # BastardKB Charybdis (RP2040 Splinky) - uses BastardKB QMK fork
          charybdis-init = buildFirmware {
            name = "charybdis-init";
            keyboard = "bastardkb/charybdis/4x6";
            keymap = "init";
            qmkSource = qmkBastard;
          };

          # Ploopyco Trackball - uses upstream QMK

          ploopyco-trackball-rev1_005-pers = buildFirmware {
            name = "ploopyco-trackball-rev1_005-pers";
            keyboard = "ploopyco/trackball/rev1_005";


@@ 230,6 262,9 @@
            echo "  Keyball (use holykeebs/qmk_firmware):"
            echo "    - keyball/keyball39:init"
            echo ""
            echo "  BastardKB (use BastardKB qmk fork):"
            echo "    - bastardkb/charybdis/4x6:init"
            echo ""
            echo "  Ploopyco (use upstream qmk_firmware):"
            echo "    - ploopyco/trackball/rev1_005:pers"
            echo "    - ploopyco/trackball/rev1_007:pers"


@@ 237,6 272,7 @@
            echo "Build with: nix build .#<keyboard-name>"
            echo "  e.g.: nix build .#voyager-pers"
            echo "        nix build .#keyball39-init"
            echo "        nix build .#charybdis-init"
            echo "        nix build .#all"
            echo ""
          '';

A keyboards/bastardkb/charybdis/4x6/keymaps/init/config.h => keyboards/bastardkb/charybdis/4x6/keymaps/init/config.h +31 -0
@@ 0,0 1,31 @@
/**
 * Copyright 2021 Charly Delay <charly@codesink.dev> (@0xcharly)
 *
 * 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

#ifndef __arm__
/* Disable unused features. */
#    define NO_ACTION_ONESHOT
#endif // __arm__

/* Charybdis-specific features. */

#ifdef POINTING_DEVICE_ENABLE
// Automatically enable the pointer layer when moving the trackball.  See also:
// - `CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_TIMEOUT_MS`
// - `CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_THRESHOLD`
// #define CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_ENABLE
#endif // POINTING_DEVICE_ENABLE

A keyboards/bastardkb/charybdis/4x6/keymaps/init/keymap.c => keyboards/bastardkb/charybdis/4x6/keymaps/init/keymap.c +278 -0
@@ 0,0 1,278 @@
/**
 * Copyright 2021 Charly Delay <charly@codesink.dev> (@0xcharly)
 *
 * 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

#ifdef CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_ENABLE
#    include "timer.h"
#endif // CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_ENABLE

enum charybdis_keymap_layers {
    LAYER_BASE = 0,
    LAYER_TRANSPARENT,
    LAYER_GAMING,
    LAYER_POINTER,
    LAYER_SYMBOL,
    LAYER_SETTINGS,
};

/** \brief Automatically enable sniping-mode on the pointer layer. */
#define CHARYBDIS_AUTO_SNIPING_ON_LAYER LAYER_POINTER

#ifdef CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_ENABLE
static uint16_t auto_pointer_layer_timer = 0;

#    ifndef CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_TIMEOUT_MS
#        define CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_TIMEOUT_MS 1000
#    endif // CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_TIMEOUT_MS

#    ifndef CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_THRESHOLD
#        define CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_THRESHOLD 8
#    endif // CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_THRESHOLD
#endif     // CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_ENABLE

#define LOWER MO(LAYER_POINTER)
#define RAISE MO(LAYER_SYMBOL)
#define MO_SET MO(LAYER_SETTINGS)
#define PT_Z LT(LAYER_SETTINGS, KC_Z)
#define PT_SLSH LT(LAYER_SETTINGS, KC_SLSH)

#ifndef POINTING_DEVICE_ENABLE
#    define DRGSCRL KC_NO
#    define DRG_TOG KC_NO
#    define DPI_MOD KC_NO
#    define DPI_RMOD KC_NO
#    define S_D_MOD KC_NO
#    define S_D_RMOD KC_NO
#    define SNIPING KC_NO
#endif // !POINTING_DEVICE_ENABLE

#define HR_A KC_A
#define HR_S MT(MOD_LALT, KC_S)
#define HR_D MT(MOD_LSFT, KC_D)
#define HR_F MT(MOD_LCTL, KC_F)

#define HR_J MT(MOD_RCTL, KC_J)
#define HR_K MT(MOD_RSFT, KC_K)
#define HR_L MT(MOD_RALT, KC_L)
#define HR_SCLN KC_SCLN

#define KC_EUNDO LCTL(LSFT(KC_MINUS))
#define KC_AENTER LCTL(LALT(KC_ENT))
#define WAYFULL LGUI(LSFT(KC_F))
#define WAYHALF LGUI(LSFT(KC_D))
#define KC_CAD LCTL(LALT(KC_DEL))

enum {
    TD_UNDO,
};

// Combo for caps word
const uint16_t PROGMEM capsword_combo[] = {HR_D, HR_K, COMBO_END};

combo_t key_combos[] = {
    COMBO(capsword_combo, QK_CAPS_WORD_TOGGLE),
};

tap_dance_action_t tap_dance_actions[] = {
    [TD_UNDO] = ACTION_TAP_DANCE_DOUBLE(KC_U, KC_EUNDO),
};

#define TD_U TD(TD_UNDO)

#define LT_TAB LT(LAYER_POINTER, KC_TAB)
#define LT_BSPC LT(LAYER_SYMBOL, KC_BSPC)
#define MT_ENT MT(MOD_RGUI, KC_ENT)
#define LT_SPC LT(LAYER_SYMBOL, KC_SPC)

// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  [LAYER_BASE] = LAYOUT(
  // ╭──────────────────────────────────────────────────────╮ ╭──────────────────────────────────────────────────────╮
        KC_ESC,    KC_1,    KC_2,    KC_3,    KC_4,    KC_5,       KC_6,    KC_7,    KC_8,    KC_9,    KC_0, KC_MINS,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
        KC_TAB,    KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,       KC_Y,    TD_U,    KC_I,    KC_O,    KC_P, KC_BSLS,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       KC_LSFT,    HR_A,    HR_S,    HR_D,    HR_F,    KC_G,       KC_H,    HR_J,    HR_K,    HR_L, HR_SCLN, KC_QUOT,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       MO_SET,    PT_Z,    KC_X,    KC_C,    KC_V,    KC_B,       KC_N,    KC_M, KC_COMM,  KC_DOT, PT_SLSH, MO_SET,
  // ╰──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────╯
                                   LT_TAB, LT_BSPC, KC_LGUI,     MT_ENT,  LT_SPC,
                                           KC_LALT, KC_BSPC,     KC_DEL
  //                            ╰───────────────────────────╯ ╰──────────────────╯
  ),

  [LAYER_TRANSPARENT] = LAYOUT(
  // ╭──────────────────────────────────────────────────────╮ ╭──────────────────────────────────────────────────────╮
       _______, _______, _______, _______, _______, _______,    _______, _______, _______, _______, _______, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, _______, _______, _______, _______, _______,    _______, _______, _______, _______, _______, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, _______, _______, _______, _______, _______,    _______, _______, _______, _______, _______, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, _______, _______, _______, _______, _______,    _______, _______, _______, _______, _______, _______,
  // ╰──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────╯
                                  _______, _______, _______,    _______, _______,
                                           _______, _______,    _______
  //                            ╰───────────────────────────╯ ╰──────────────────╯
  ),

  [LAYER_GAMING] = LAYOUT(
  // ╭──────────────────────────────────────────────────────╮ ╭──────────────────────────────────────────────────────╮
       _______, _______, _______, _______, _______, _______,    _______, _______, _______, _______, _______, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, _______, _______, KC_E,    _______, _______,    _______, KC_U,    _______, _______, _______, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, KC_A,    KC_S,    KC_D,    KC_F,    _______,    _______, KC_J,    KC_K,    KC_L, KC_SCLN, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, _______, _______, _______, _______, KC_B,       _______, _______, _______, _______, _______, _______,
  // ╰──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────╯
                                  _______, _______, _______,    _______, _______,
                                           _______, _______,    _______
  //                            ╰───────────────────────────╯ ╰──────────────────╯
  ),

  [LAYER_POINTER] = LAYOUT(
  // ╭──────────────────────────────────────────────────────╮ ╭──────────────────────────────────────────────────────╮
       _______, _______, _______, _______, _______, _______,    _______, _______, _______, _______, _______, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, _______, _______, _______, _______, _______,    KC_SLSH,    KC_7,    KC_8,    KC_9, KC_ASTR, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, _______, _______, _______, _______, _______,    KC_MINS,    KC_4,    KC_5,    KC_6, KC_PLUS, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, DRG_TOG, DRGSCRL, MS_BTN2, MS_BTN1, _______,      KC_0,    KC_1,    KC_2,    KC_3,  KC_DOT, _______,
  // ╰──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────╯
                                  _______, _______, _______,    _______, _______,
                                           _______, _______,    _______
  //                            ╰───────────────────────────╯ ╰──────────────────╯
  ),

  [LAYER_SYMBOL] = LAYOUT(
  // ╭──────────────────────────────────────────────────────╮ ╭──────────────────────────────────────────────────────╮
       _______, _______, _______, _______, _______, _______,    _______, _______, _______, _______, _______, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, KC_GRV, KC_TILDE, KC_HASH, KC_AMPR, KC_PIPE,     KC_CIRC, KC_LCBR, KC_RCBR, KC_LBRC, KC_RBRC, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, KC_EXLM,  KC_UNDS, KC_COLN,  KC_EQL,  KC_DLR,       KC_AT, KC_LPRN, KC_RPRN, KC_UNDS, KC_SCLN, _______,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       _______, KC_PERC,  KC_QUES, KC_ASTR, KC_PLUS, KC_BSLS,     KC_SLSH, KC_MINS,   KC_LT,   KC_GT,  KC_DQT, _______,
  // ╰──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────╯
                                  _______, _______, _______,    _______, _______,
                                           _______, _______,    _______
  //                            ╰───────────────────────────╯ ╰──────────────────╯
  ),

  [LAYER_SETTINGS] = LAYOUT(
  // ╭──────────────────────────────────────────────────────╮ ╭──────────────────────────────────────────────────────╮
       RM_TOGG, XXXXXXX, XXXXXXX, XXXXXXX, DRG_TOG, TG(LAYER_TRANSPARENT),        DRGSCRL, _______,   KC_UP, _______, QK_BOOT,  EE_CLR,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       WAYHALF, WAYFULL,  KC_CAD, KC_AENTER, S_D_MOD, XXXXXXX,    DPI_MOD, KC_LEFT, KC_DOWN, KC_RGHT, XXXXXXX, XXXXXXX,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       RM_NEXT, RM_PREV, RM_VALU, RM_VALD, S_D_RMOD, XXXXXXX,   DPI_RMOD, _______, _______, _______, _______, XXXXXXX,
  // ├──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────┤
       QK_BOOT,  EE_CLR, _______, _______, _______, _______,      SNIPING, _______, _______, _______,  KC_PGDN,  EE_CLR,
  // ╰──────────────────────────────────────────────────────┤ ├──────────────────────────────────────────────────────╯
                                  _______, _______, _______,    _______, _______,
                                           _______, _______,    _______
  //                            ╰───────────────────────────╯ ╰──────────────────╯
  ),
};
// clang-format on

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case HR_L:
            if (record->event.pressed && record->tap.count && layer_state_is(LAYER_TRANSPARENT)) {
                uint8_t mods    = get_mods();
                uint8_t weak    = get_weak_mods();
                uint8_t oneshot = get_oneshot_mods();

                if ((mods | weak | oneshot) & MOD_MASK_GUI) {
                    // GUI is already held; just tap N so the host sees GUI+N.
                    tap_code(KC_N);
                    return false;
                }
            }
            break;
    }

    return true;
}

bool caps_word_press_user(uint16_t keycode) {
    switch (keycode) {
        // Keycodes that continue Caps Word, with shift applied.
        case KC_A ... KC_Z:
        case TD(TD_UNDO): // Treat tap dance U like a letter
            add_weak_mods(MOD_BIT(KC_LSFT));
            return true;

        // Keycodes that continue Caps Word, without shifting.
        case KC_1 ... KC_0:
        case KC_BSPC:
        case KC_DEL:
        case KC_UNDS:
        case KC_MINS:
            return true;

        default:
            return false; // Deactivate Caps Word.
    }
}

#ifdef POINTING_DEVICE_ENABLE
report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
#    ifdef CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_ENABLE
    if (abs(mouse_report.x) > CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_THRESHOLD || abs(mouse_report.y) > CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_THRESHOLD) {
        if (auto_pointer_layer_timer == 0) {
            layer_on(LAYER_SETTINGS);
#        ifdef RGB_MATRIX_ENABLE
            rgb_matrix_mode_noeeprom(RGB_MATRIX_NONE);
            rgb_matrix_sethsv_noeeprom(HSV_GREEN);
#        endif // RGB_MATRIX_ENABLE
        }
        auto_pointer_layer_timer = timer_read();
    }
#    endif // CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_ENABLE

    mouse_report.v = -mouse_report.v;
    return mouse_report;
}

#    ifdef CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_ENABLE
void matrix_scan_user(void) {
    if (auto_pointer_layer_timer != 0 && TIMER_DIFF_16(timer_read(), auto_pointer_layer_timer) >= CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_TIMEOUT_MS) {
        auto_pointer_layer_timer = 0;
        layer_off(LAYER_SETTINGS);
#        ifdef RGB_MATRIX_ENABLE
        rgb_matrix_mode_noeeprom(RGB_MATRIX_DEFAULT_MODE);
#        endif // RGB_MATRIX_ENABLE
    }
}
#    endif // CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_ENABLE

#    ifdef CHARYBDIS_AUTO_SNIPING_ON_LAYER
layer_state_t layer_state_set_user(layer_state_t state) {
    charybdis_set_pointer_sniping_enabled(layer_state_cmp(state, CHARYBDIS_AUTO_SNIPING_ON_LAYER));
    return state;
}
#    endif // CHARYBDIS_AUTO_SNIPING_ON_LAYER
#endif     // POINTING_DEVICE_ENABLE

#ifdef RGB_MATRIX_ENABLE
// Forward-declare this helper function since it is defined in rgb_matrix.c.
void rgb_matrix_update_pwm_buffers(void);
#endif

A keyboards/bastardkb/charybdis/4x6/keymaps/init/readme.md => keyboards/bastardkb/charybdis/4x6/keymaps/init/readme.md +61 -0
@@ 0,0 1,61 @@
# Charybdis (4x6) `init` keymap

The Charydbis (4x6) `init` keymap is inspired from the original [Dactyl Manuform](../../../../../handwired/dactyl_manuform) default keymap, with some features and changes specific to the Charybdis.

This layout supports RGB matrix. However, due to space constraints on the MCU, only a limited number of effect can be enabled at once. Look at the `config.h` file and enable your favorite effect.

## Customizing the keymap

### Dynamic DPI scaling

Use the following keycodes to change the default DPI:

-   `POINTER_DEFAULT_DPI_FORWARD`: increases the DPI; decreases when shifted;
-   `POINTER_DEFAULT_DPI_REVERSE`: decreases the DPI; increases when shifted.

There's a maximum of 16 possible values for the sniping mode DPI. See the [Charybdis documentation](../../README.md) for more information.

Use the following keycodes to change the sniping mode DPI:

-   `POINTER_SNIPING_DPI_FORWARD`: increases the DPI; decreases when shifted;
-   `POINTER_SNIPING_DPI_REVERSE`: decreases the DPI; increases when shifted.

There's a maximum of 4 possible values for the sniping mode DPI. See the [Charybdis documentation](../../README.md) for more information.

### Drag-scroll

Use the `DRAGSCROLL_MODE` keycode to enable drag-scroll on hold. Use the `DRAGSCROLL_TOGGLE` keycode to enable/disable drag-scroll on key press.

### Sniping

Use the `SNIPING_MODE` keycode to enable sniping mode on hold. Use the `SNIPING_MODE_TOGGLE` (aliased as `SNP_TOG`) keycode to enable/disable sniping mode on key press.

Change the value of `CHARYBDIS_AUTO_SNIPING_ON_LAYER` to automatically enable sniping mode on layer change. By default, sniping mode is enabled on the pointer layer:

```c
#define CHARYBDIS_AUTO_SNIPING_ON_LAYER LAYER_POINTER
```

### Auto pointer layer

The pointer layer can be automatically enabled when moving the trackball. To enable or disable this behavior, add or remove the following define:

```c
#define CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_ENABLE
```

By default, the layer is turned off 1 second after the last registered trackball movement:

```c
#define CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_TIMEOUT_MS 1000
```

The trigger sensibility can also be tuned. The lower the value, the more sensible the trigger:

```c
#define CHARYBDIS_AUTO_POINTER_LAYER_TRIGGER_THRESHOLD 8
```

## Layout

![Keymap layout (generated with keyboard-layout-editor.com)](https://i.imgur.com/qI7phR7.png)

A keyboards/bastardkb/charybdis/4x6/keymaps/init/rules.mk => keyboards/bastardkb/charybdis/4x6/keymaps/init/rules.mk +3 -0
@@ 0,0 1,3 @@
COMBO_ENABLE = yes
TAP_DANCE_ENABLE = yes
CAPS_WORD_ENABLE = yes

M keyboards/keyball/keyball39/keymaps/init/keymap.c => keyboards/keyball/keyball39/keymaps/init/keymap.c +5 -5
@@ 61,7 61,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
        KC_Q     , KC_W     , KC_E     , KC_R     , KC_T     ,                            KC_Y     , TD(TD_UNDO), KC_I   , KC_O     , KC_P     ,
        HR_A     , HR_S     , HR_D     , HR_F     , KC_G     ,                            KC_H     , HR_J     , HR_K     , HR_L     , HR_SCLN  ,
        KC_Z     , KC_X     , KC_C     , KC_V     , KC_B     ,                            KC_N     , KC_M     , KC_COMM  , KC_DOT   , KC_SLSH  ,
        KC_ESC   , KC_TAB   , MO(5)    , LT(3,KC_TAB), LT(4,KC_BSPC), KC_LGUI,      MT(MOD_RGUI, KC_ENT), LT(4,KC_SPC), _______,  _______,  _______, KC_QUOT
        MO(5)    , KC_TAB   , KC_ESC   , LT(3,KC_TAB), LT(4,KC_BSPC), KC_LGUI,      MT(MOD_RGUI, KC_ENT), LT(4,KC_SPC), _______,  _______,  _______, KC_QUOT
    ),

    // Transparent layer for HR_L GUI+N behavior


@@ 98,10 98,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

    // Nav/Settings layer
    [5] = LAYOUT_universal(
        RGB_TOG  , AML_TO   , AML_I50  , AML_D50  , TG(1)   ,                            _______ , SSNP_VRT , SSNP_HOR , SSNP_FRE ,  QK_BOOT  ,
        WAYHALF  , WAYFULL  , KC_CAD   , KC_AENTER, SCRL_DVI,                            CPI_I100, KC_HOME  , KC_UP    , KC_END   , _______ ,
        RGB_MOD  , RGB_RMOD  , RGB_VAI  , RGB_VAD  , SCRL_DVD,                            CPI_D100, KC_LEFT  , KC_DOWN  , KC_RGHT  , _______ ,
        QK_BOOT  , KBC_RST  , _______ , _______ , _______ , _______ ,          _______ , C(S(KC_TAB)), C(KC_TAB), KC_PGUP , KC_PGDN , KBC_SAVE
        RGB_TOG  , AML_TO   , AML_I50  , AML_D50  , TG(1)   ,                            _______ , SSNP_VRT , KC_UP    , SSNP_FRE ,  QK_BOOT  ,
        WAYHALF  , WAYFULL  , KC_CAD   , KC_AENTER, SCRL_DVI,                            CPI_I100, KC_LEFT  , KC_DOWN  , KC_RGHT  , _______ ,
        RGB_MOD  , RGB_RMOD  , RGB_VAI  , RGB_VAD , SCRL_DVD,                            CPI_D100, _______  , _______  , _______  , _______ ,
        QK_BOOT  , KBC_RST  , _______ , _______ , _______ , _______ ,          _______ , SSNP_VRT, SSNP_HOR , SSNP_FRE , KC_PGDN , KBC_SAVE
    ),
};
// clang-format on