Add readme and claude.me
This commit is contained in:
60
CLAUDE.md
Normal file
60
CLAUDE.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
Custom QMK firmware for a System76 Launch 3 keyboard (RP2040, 84-key). The custom keymap adds OS-aware shortcut translation (Linux/Mac/Windows) with automatic OS detection.
|
||||||
|
|
||||||
|
## Build Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Development (uses symlink to custom keymap)
|
||||||
|
nix develop
|
||||||
|
qmk compile -kb system76/launch_3 -km custom
|
||||||
|
|
||||||
|
# Production build (sandboxed, outputs result/system76_launch_3_custom.uf2)
|
||||||
|
nix build
|
||||||
|
```
|
||||||
|
|
||||||
|
New files in `keymaps/custom/` must be `git add`ed before `nix build` — flakes only see git-tracked files.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Repository Layout
|
||||||
|
|
||||||
|
- `qmk_firmware/` — System76's QMK fork (git submodule, do not modify)
|
||||||
|
- `keymaps/custom/` — Custom keymap, kept separate from the submodule
|
||||||
|
- `flake.nix` — Dev shell and sandboxed firmware build; uses `self.submodules = true`
|
||||||
|
|
||||||
|
### Custom Keymap Files (`keymaps/custom/`)
|
||||||
|
|
||||||
|
- `keymap.c` — Keymaps, layer override, modifier rewriting, process_record_user
|
||||||
|
- `os_detect.c` — OS auto-detection polling, os_mode/os_mode_manual definitions, RGB flash
|
||||||
|
- `os_mode.h` — Shared `os_mode_t` enum and extern declarations
|
||||||
|
- `rules.mk` — Enables OS_DETECTION and adds `SRC += os_detect.c`
|
||||||
|
|
||||||
|
### Key Constraints
|
||||||
|
|
||||||
|
**keymap_introspection.c textually `#include`s keymap.c** — this means:
|
||||||
|
- Headers in `keymaps/custom/` can't be `#include`d from `keymap.c` (the compiler resolves includes relative to `quantum/keymap_introspection.c`, not the included file)
|
||||||
|
- Variables shared between `keymap.c` and other files must be non-static with `extern` declarations
|
||||||
|
- Guard OS-specific code with `#ifdef OS_DETECTION_ENABLE` if it uses types from guarded headers, or put it in a separate `.c` file (preferred)
|
||||||
|
|
||||||
|
**keyboard_post_init_user is taken** by `launch_3.c` — use `matrix_init_user` instead.
|
||||||
|
|
||||||
|
**DYNAMIC_KEYMAP_ENABLE** causes EEPROM to override PROGMEM keymaps — `dynamic_keymap_reset()` in `matrix_init_user` forces PROGMEM back.
|
||||||
|
|
||||||
|
### Modifier Rewriting System
|
||||||
|
|
||||||
|
`mod_rewrite_t` structs define from→to modifier translations. `normalize_mods()` collapses left/right modifier variants into a single nibble for comparison. `mods_match()` does exact mod matching and skips rewrites when FN layer is active.
|
||||||
|
|
||||||
|
### OS Mode
|
||||||
|
|
||||||
|
`os_mode_t` enum (NONE/LINUX/MAC/WINDOWS). Auto-detected via USB enumeration polling after 2s. Manual cycling via FN+Del (`CK_OSMODE`). Once manually set, `os_mode_manual` prevents auto-detection override. RGB indicator: red=none, green=linux, yellow=mac, blue=windows.
|
||||||
|
|
||||||
|
OS detection on System76's QMK fork often misidentifies Linux as Windows — both currently map to `OS_MODE_LINUX`.
|
||||||
|
|
||||||
|
### Nix Build
|
||||||
|
|
||||||
|
The flake copies `keymaps/custom/` into the QMK tree during `postUnpack`. `patchShebangs` is needed for `uf2conv.py` in the sandbox. `python3` and `python3Packages.appdirs` are required nativeBuildInputs.
|
||||||
88
README.md
Normal file
88
README.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# System76 Launch 3 Custom Firmware
|
||||||
|
|
||||||
|
Custom QMK firmware for the [System76 Launch 3](https://system76.com/accessories/launch) keyboard, built with Nix.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### OS Mode
|
||||||
|
|
||||||
|
The keyboard auto-detects the host OS on plug-in and rewrites shortcuts so that muscle memory from Linux (Ctrl-based shortcuts) works on macOS. Mode can also be cycled manually with **FN+Del**.
|
||||||
|
|
||||||
|
Four modes, indicated by RGB flash color:
|
||||||
|
|
||||||
|
| Mode | Color | Behavior |
|
||||||
|
|---------|--------|----------|
|
||||||
|
| None | Red | No rewrites, all keys pass through |
|
||||||
|
| Linux | Green | Super+Up → Super+W (KDE overview) |
|
||||||
|
| Mac | Yellow | Full Ctrl→Cmd rewrite (see table below) |
|
||||||
|
| Windows | Blue | Super+Up → Super+Tab (Task View) |
|
||||||
|
|
||||||
|
#### Mac Mode Shortcut Rewrites
|
||||||
|
|
||||||
|
| Input (Linux muscle memory) | Output (macOS) | Action |
|
||||||
|
|---|---|---|
|
||||||
|
| Ctrl+C/V | Cmd+C/V | Copy/Paste |
|
||||||
|
| Ctrl+Shift+C/V | Cmd+C/V | Terminal copy/paste |
|
||||||
|
| Ctrl+X/A/S/F | Cmd+X/A/S/F | Cut, Select All, Save, Find |
|
||||||
|
| Ctrl+W/L/R | Cmd+W/L/R | Close tab, Address bar, Reload |
|
||||||
|
| Ctrl+Z/T/N | Cmd+Z/T/N | Undo, New tab, New window |
|
||||||
|
| Ctrl+Shift+Z/T/N | Cmd+Shift+Z/T/N | Redo, Reopen tab, Incognito |
|
||||||
|
| Ctrl+Left/Right | Alt+Left/Right | Word navigation |
|
||||||
|
| Ctrl+Alt+Left/Right | Ctrl+Left/Right | Switch workspace |
|
||||||
|
| Ctrl+Backspace | Alt+Backspace | Delete word |
|
||||||
|
| Home/End | Cmd+Left/Right | Line start/end |
|
||||||
|
| Alt+F4 | Cmd+Q | Quit app |
|
||||||
|
| Alt+Tab | Cmd+Tab | App switcher |
|
||||||
|
| Super tap | Cmd+Space | Spotlight |
|
||||||
|
| Super+Up | Ctrl+Up | Mission Control |
|
||||||
|
|
||||||
|
#### Layer Override
|
||||||
|
|
||||||
|
When any modifier is held (in any mode except None), the FN layer is bypassed — keys always resolve from Layer 0. This allows bypassing shortcut rewrites when wanted. For example, if you want to send Ctrl+c on mac (which is normally rewritten to cmd+c), simply use fn+Ctrl+c instead.
|
||||||
|
|
||||||
|
### Layer 1 (FN Layer)
|
||||||
|
|
||||||
|
| Key | FN+ |
|
||||||
|
|-----|-----|
|
||||||
|
| ESC | Print Screen |
|
||||||
|
| F1/F2/F3 | Mute / Vol Down / Vol Up |
|
||||||
|
| 1/2/3 | Play-Pause / Prev / Next |
|
||||||
|
| 0/-/= | LED Toggle / LED Down / LED Up |
|
||||||
|
| Del | Cycle OS Mode |
|
||||||
|
| Arrows | Home / PgDn / PgUp / End |
|
||||||
|
|
||||||
|
Modifier keys (Shift, Ctrl, GUI, Alt) cannot be rebound on Layer 1 due to the layer override behavior.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
Requires [Nix](https://nixos.org/) with flakes enabled.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nix build
|
||||||
|
```
|
||||||
|
|
||||||
|
The `.uf2` firmware file is output to `./result/`.
|
||||||
|
|
||||||
|
### Flashing
|
||||||
|
|
||||||
|
1. Put the keyboard into bootloader mode (press the reset button on the bottom)
|
||||||
|
2. Copy the `.uf2` file to the mounted USB drive
|
||||||
|
|
||||||
|
### Development Shell
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nix develop
|
||||||
|
qmk compile -kb system76/launch_3 -km custom
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
keymaps/custom/
|
||||||
|
├── keymap.c # Keymaps, shortcut rewrites, layer override
|
||||||
|
├── os_detect.c # OS auto-detection, RGB flash indicator
|
||||||
|
├── os_mode.h # OS mode enum and shared state
|
||||||
|
└── rules.mk # QMK build flags
|
||||||
|
qmk_firmware/ # System76 QMK fork (git submodule)
|
||||||
|
flake.nix # Nix build system
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user