You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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)
@@ -590,6 +591,39 @@ If you enable the [Sherlock](https://inlang.com/m/r7kp499g/app-inlang-ideExtensi
590
591
- Using [inlang CLI](https://inlang.com/m/2qj2w8pu/app-inlang-cli) to support the npm commands.
591
592
- You can install the [Sherlock VS Code extension](https://marketplace.visualstudio.com/items?itemName=inlang.vs-code-extension) in your devcontainer.
592
593
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
- 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).
0 commit comments