Duncan Sutherland 2 weeks ago
committed by GitHub
parent
commit
f93e9c2476
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
1 changed files with 97 additions and 81 deletions
  1. +97
    -81
      docs/feature_layouts.md

+ 97
- 81
docs/feature_layouts.md View File

@ -1,109 +1,125 @@
# Layouts: Using a Keymap with Multiple Keyboards
# Community Layouts
The `layouts/` folder contains different physical key layouts that can apply to different keyboards.
This feature allows a keymap to be defined outside of the `keyboards/` directory, that can be compiled for keyboards with a common, community-established physical layout.
```
layouts/
+ default/
| + 60_ansi/
| | + readme.md
| | + layout.json
| | + a_good_keymap/
| | | + keymap.c
| | | + readme.md
| | | + config.h
| | | + rules.mk
| | + <keymap folder>/
| | + ...
| + <layout folder>/
+ community/
| + <layout folder>/
| + ...
```
#### Example
You have a QMK powered, TKL ANSI physical layout keyboard with a keymap configured to your new experimental functional layout. Your friend/"partner in keyboard layout crime" also has a QMK powered, TKL ANSI physical layout keyboard but it's a different model to yours and therefore it would require your friend to redefine your keymap exclusively for their keyboard.
In this example, although the keyboards both have an identical physical layout, this same keymap has been defined twice; once for each keyboard. By placing this experimental keymap under the respective `tkl_ansi` Community Layout directory, the keymap in question has been defined once and then can be compiled for every QMK compatible keyboard with `tkl_ansi` Community Layout support.
The `layouts/default/` and `layouts/community/` are two examples of layout "repositories" - currently `default` will contain all of the information concerning the layout, and one default keymap named `default_<layout>`, for users to use as a reference. `community` contains all of the community keymaps, with the eventual goal of being split-off into a separate repo for users to clone into `layouts/`. QMK searches through all folders in `layouts/`, so it's possible to have multiple repositories here.
[Miryoku](https://github.com/manna-harbour/miryoku) functional layout is a prominent utiliser of this feature.
Each layout folder is named (`[a-z0-9_]`) after the physical aspects of the layout, in the most generic way possible, and contains a `readme.md` with the layout to be defined by the keyboard:
?> Community Layouts also function in conjunction with the [Userspace](./feature_userspace.md) feature.
```markdown
# 60_ansi
## Directory Structure
The `layouts/` directory acts as the parent directory for this feature.
The `layouts/default/` and `layouts/community/` sub-directories are two examples of Community Layout "repositories":
- `default/` contains all information regarding each Community Layout, which includes a default keymap named `default_<community_layout>`, and is used for reference.
- `community/` is where local (GitHub Repository) keymaps and community/user shared keymaps (e.g. Miryoku) for each Community Layout are located.
LAYOUT_60_ansi
```
QMK searches through all sub-directories in `layouts/`, so it's possible to have multiple repositories.
New names should try to stick to the standards set by existing layouts, and can be discussed in the PR/Issue.
## Supporting a Layout
To assist explanation, terms encapsulated in angled brackets are used throughout this page.
```
layouts/
├── default/
│ └── <community_layout>/
│ └── <community_layout_keymap>/
│ └── keymap.c
└── community/
└── <community_layout>/
└── <community_layout_keymap>/
└── keymap.c
```
**<community_layout>**: As well as sub-directory name, this serves as Community Layout name
**<community_layout_keymap>**: As well as sub-directory name, this serves as keymap name of *<community_layout>*
For a keyboard to support a layout, the variable must be defined in it's `<keyboard>.h`, and match the number of arguments/keys (and preferably the physical layout):
## Add Community Layout support to keyboard
#define LAYOUT_60_ansi KEYMAP_ANSI
For a keyboard to support one or more Community Layouts, the keyboard's `info.json`/`keyboard.json` file must include:
1. A `"community_layouts"` array containing the name(s) of the respective Community Layout(s) the keyboard in question supports. Name(s) must be identical to *<community_layout>*.
#### `layouts/` directory example:
```
layouts/
└── default/
├── 60_ansi/
│ └── <...>
└── 60_iso/
└── <...>
```
#### keyboard's `info.json`/`keyboard.json`:
```json
"community_layouts": ["60_ansi", "60_iso"]
```
2. Within `"layouts"` object literal, for each Community Layout supported, add layout information with macro name that is identical to the respective Community Layout's macro name; macro name is specified in keymap file (`keymap.c`/`keymap.json`) of *<community_layout_keymap>*.
The name of the layout must match this regex: `[a-z0-9_]+`
#### Macro name example
`layouts/default/60_ansi/default_60_ansi/keymap.c`:
```c
[0] = LAYOUT_60_ansi(
...
)
```
The folder name must be added to the keyboard's `rules.mk`:
#### Keyboard's `info.json`/`keyboard.json`:
```json
"layouts": {
"LAYOUT_60_ansi": {
"layout": [
{...}
]
},
"LAYOUT_60_iso": {
"layout": [
{...}
]
}
}
```
LAYOUTS = 60_ansi
For each Community Layout being added to `"layouts"`:
- Array length of `"layout"` **must** match array length of respective Community Layout
- key sequence (e.g. ANSI Enter vs ISO Enter) and graphical properties of each key (i.e. `"x":`, `"y":`, `"w":`, `"h":`) should be identical to respective Community Layout
`LAYOUTS` can be set in any keyboard folder level's `rules.mk`:
Array length and key information of each Community Layout can be found in `layouts/default/`*<community_layout>*`/info.json`.
LAYOUTS = 60_iso
## Compiling Community Layout keymap
Compiling a keyboard with keymap from a supported Community Layout is identical to regular keymap compilation, with the difference being the keymap argument is *<community_layout_keymap>*:
but the `LAYOUT_<layout>` variable must be defined in `<folder>.h` as well.
qmk compile -kb <keyboard> -km <community_layout_keymap>
## Building a Keymap
Examples:
You should be able to build the keyboard keymap with a command in this format:
qmk compile -kb dztech/pluto -km default_tkl_nofrow_ansi
qmk compile -kb dz60 -km default_60_iso
make <keyboard>:<layout>
### Conflicting Keymaps
When compiling a <community_layout_keymap> that has the same name in two or more <community_layouts> the target keyboard supports, this can result in the undesired keymap being compiled.
### Conflicting layouts
When a keyboard supports multiple layout options,
#### Example Scenario:
Using the `contra` keyboard in this scenario, as it supports `ortho_4x12` and `planck_mit` Community Layouts.
LAYOUTS = ortho_4x4 ortho_4x12
**keyboard's `info.json`/`keyboard.json`**
```json
"community_layouts": ["ortho_4x12", "planck_mit"]
```
And a layout exists for both options,
**layouts/ directory example**
```
layouts/
+ community/
| + ortho_4x4/
| | + <layout>/
| | | + ...
| + ortho_4x12/
| | + <layout>/
| | | + ...
| + ...
└── community/
├── ortho_4x12/
│ └── jondough/
│ └── keymap.c
└── planck_mit/
└── jondough/
└── keymap.c
```
Running `qmk compile -kb contra -km jondough` without additional context doesn't determine which `jondough` keymap is being specified for compilation.
The FORCE_LAYOUT argument can be used to specify which layout to build
make <keyboard>:<layout> FORCE_LAYOUT=ortho_4x4
make <keyboard>:<layout> FORCE_LAYOUT=ortho_4x12
## Tips for Making Layouts Keyboard-Agnostic
### Includes
Instead of using `#include "planck.h"`, you can use this line to include whatever `<keyboard>.h` (`<folder>.h` should not be included here) file that is being compiled:
#include QMK_KEYBOARD_H
If you want to keep some keyboard-specific code, you can use these variables to escape it with an `#ifdef` statement:
* `KEYBOARD_<folder1>_<folder2>`
For example:
```c
#ifdef KEYBOARD_planck
#ifdef KEYBOARD_planck_rev4
planck_rev4_function();
#endif
#endif
```
In this scenario the `FORCE_LAYOUT` argument is included, to specify from which <community_layout> the specified keymap is used:
Note that the names are lowercase and match the folder/file names for the keyboard/revision exactly.
qmk compile -kb <keyboard> -km <community_layout_keymap> -e FORCE_LAYOUT=<community_layout>
### Keymaps
Example:
In order to support both split and non-split keyboards with the same layout, you need to use the keyboard agnostic `LAYOUT_<layout name>` macro in your keymap. For instance, in order for a Let's Split and Planck to share the same layout file, you need to use `LAYOUT_ortho_4x12` instead of `LAYOUT_planck_grid` or just `{}` for a C array.
qmk compile -kb contra -km jondough -e FORCE_LAYOUT=planck_mit

Loading…
Cancel
Save