Skip to content

Commit 05dc88d

Browse files
committed
Rebuild keyboard
Drive all keyboard activity from a KLE layout files.
1 parent 73d78ef commit 05dc88d

82 files changed

Lines changed: 11115 additions & 3918 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Keyboard Layout
2+
type: 'Feature'
3+
description: Submit a new keyboard layout or fix an existing one.
4+
labels:
5+
- 'type: keyboard-layout'
6+
body:
7+
- type: markdown
8+
attributes:
9+
value: |
10+
Thanks for contributing a keyboard layout! The virtual keyboard and paste-text system use [KLE (keyboard-layout-editor.com)](https://keyboard-layout-editor.com) JSON files.
11+
12+
**How to create a layout:**
13+
1. Go to [keyboard-layout-editor.com](https://www.keyboard-layout-editor.com)
14+
2. Design your layout (or start from a preset and modify it)
15+
3. Copy the JSON from the **Raw data** tab
16+
4. Paste it below
17+
18+
**Before submitting**, validate your layout locally if you can:
19+
```bash
20+
go run scripts/validate_layout.go your-layout.kle.json
21+
```
22+
23+
- type: input
24+
id: locale
25+
attributes:
26+
label: Locale code
27+
description: |
28+
The ISO locale code for this layout (e.g. `ko-KR`, `tr-TR`, `pt-BR`).
29+
Use the format `language-COUNTRY` with a hyphen.
30+
placeholder: "e.g. ko-KR"
31+
validations:
32+
required: true
33+
34+
- type: input
35+
id: layout-name
36+
attributes:
37+
label: Layout name
38+
description: Human-readable name for the layout (e.g. "Korean", "Turkish Q", "Portuguese (Brazil)").
39+
placeholder: "e.g. Korean"
40+
validations:
41+
required: true
42+
43+
- type: dropdown
44+
id: layout-type
45+
attributes:
46+
label: Physical layout type
47+
description: What type of physical keyboard does this layout use?
48+
options:
49+
- ISO 105-key (most European/international keyboards)
50+
- ANSI 104-key (US standard)
51+
- JIS 109-key (Japanese)
52+
- Other (describe below)
53+
validations:
54+
required: true
55+
56+
- type: textarea
57+
id: kle-json
58+
attributes:
59+
label: KLE JSON
60+
description: |
61+
Paste the raw KLE JSON here. You can get this from the **Raw data** tab on keyboard-layout-editor.com.
62+
Alternatively, attach a `.json` file to this issue.
63+
render: json
64+
validations:
65+
required: true
66+
67+
- type: textarea
68+
id: notes
69+
attributes:
70+
label: Additional notes
71+
description: |
72+
Any special notes about this layout — dead key behavior, AltGr layer details,
73+
regional variants, or differences from standard layouts.
74+
validations:
75+
required: false
76+
77+
- type: checkboxes
78+
attributes:
79+
label: Checklist
80+
options:
81+
- label: I have verified the layout matches a real physical keyboard for this locale
82+
required: true
83+
- label: The legends include all layers (normal, shift, and AltGr where applicable)
84+
required: true
85+
- label: I have tested the layout with `go run scripts/validate_layout.go` (optional but appreciated)

DEVELOPMENT.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ tail -f /userdata/jetkvm/last.log
106106
├── internal/ # Internal Go packages
107107
│ ├── confparser/ # Configuration file implementation
108108
│ ├── hidrpc/ # HIDRPC implementation for HID devices (keyboard, mouse, etc.)
109+
│ ├── keyboard/ # KLE keyboard layout parser, built-in layouts, RPC handlers
110+
│ │ └── layouts/ # Built-in KLE JSON files (ANSI/ISO/JIS)
109111
│ ├── logging/ # Logging implementation
110112
│ ├── mdns/ # mDNS implementation
111113
│ ├── native/ # CGO / Native code glue layer (on-device hardware)
@@ -134,7 +136,6 @@ tail -f /userdata/jetkvm/last.log
134136
├── assets/ # UI in-page images
135137
├── components/ # UI components
136138
├── hooks/ # Hooks (stores, RPC handling, virtual devices)
137-
├── keyboardLayouts/ # Keyboard layout definitions
138139
├── paraglide/ # (localization compiled messages output)
139140
├── providers/ # Feature flags
140141
└── routes/ # Pages (login, settings, etc.)
@@ -590,6 +591,39 @@ If you enable the [Sherlock](https://inlang.com/m/r7kp499g/app-inlang-ideExtensi
590591
- Using [inlang CLI](https://inlang.com/m/2qj2w8pu/app-inlang-cli) to support the npm commands.
591592
- You can install the [Sherlock VS Code extension](https://marketplace.visualstudio.com/items?itemName=inlang.vs-code-extension) in your devcontainer.
592593

594+
### Keyboard Layouts
595+
596+
The virtual keyboard and paste-text system are driven by [KLE](https://keyboard-layout-editor.com) JSON files parsed on the Go backend. Built-in layouts live in `internal/keyboard/layouts/` and are embedded into the binary via `go:embed`.
597+
598+
#### How it works
599+
600+
1. Each `.kle.json` file describes a physical keyboard layout (key positions, sizes, legends per layer)
601+
2. The Go parser (`internal/keyboard/keyboard.go`) processes KLE JSON into a `KeyboardLayout` struct:
602+
- Infers USB HID scancodes from key positions
603+
- Builds a `charMap` mapping characters to scancode + modifier combinations
604+
- Auto-generates uppercase shift legends for single-letter keys (e.g. `q``Q`, `ö``Ö`)
605+
- Builds dead key compositions automatically using Unicode NFC normalization (e.g. `^` + `a``â`)
606+
3. The frontend receives the processed layout via JSON-RPC and uses it for rendering, paste, and macro display
607+
608+
#### Adding a new built-in layout
609+
610+
1. Create a KLE JSON file at `internal/keyboard/layouts/<locale>.kle.json` (e.g. `ko_KR.kle.json`)
611+
- Use [keyboard-layout-editor.com](https://www.keyboard-layout-editor.com) to design the layout, then export the JSON
612+
- Key legends use `\n` to separate layers: `"normal\nshift\naltgr\nshift+altgr"`
613+
- Use Unicode symbols for special keys: `` (Backspace), `` (Enter), `` (Tab), `` (Caps Lock), `↑↓←→` (arrows)
614+
2. Add the hyphenated ID to the `builtinLayouts` map in `internal/keyboard/handler.go` (e.g. `"ko-KR": {}`)
615+
- IDs use hyphens (`ko-KR`) to match the format stored in device configs
616+
- The file lookup converts hyphens to underscores automatically (`ko-KR``ko_KR.kle.json`)
617+
3. Run the tests to validate: `go test ./internal/keyboard/...`
618+
- `TestAllBuiltinLayoutsParse` verifies every registered layout loads and parses
619+
- `TestAllLayoutFilesRegistered` verifies every file in `layouts/` is registered
620+
621+
#### User-uploaded layouts
622+
623+
Users can also upload custom KLE JSON files via the settings UI or the HTTP endpoint (`POST /keyboard/upload`). These are stored on the device at `/userdata/kvm_layouts/` and appear alongside built-in layouts in the settings dropdown.
624+
625+
For more details on the KLE format and transport schema, see [docs/keyboard/DESIGN.md](docs/keyboard/DESIGN.md) and [docs/keyboard/TRANSPORT.md](docs/keyboard/TRANSPORT.md).
626+
593627
---
594628

595629
**Happy coding!**

0 commit comments

Comments
 (0)