mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
132 lines
6.1 KiB
Markdown
132 lines
6.1 KiB
Markdown
## Keycode Generator
|
|
|
|
This directory contains a keycode generator that can generate Dart code for
|
|
the `LogicalKeyboardKey` and `PhysicalKeyboardKey` classes.
|
|
|
|
It generates multiple files across Flutter. For framework, it generates
|
|
|
|
* [`keyboard_key.g.dart`](../../../packages/flutter/lib/src/services/keyboard_key.g.dart), which contains the definition and list of logical keys and physical keys; and
|
|
* [`keyboard_maps.g.dart`](../../../packages/flutter/lib/src/services/keyboard_maps.g.dart), which contains platform-specific immutable maps used for the `RawKeyboard` API.
|
|
|
|
For engine, it generates one key mapping file for each platform, as well as some
|
|
files for testing purposes.
|
|
|
|
It draws information from various source bases, including online
|
|
repositories, and manual mapping in the `data` subdirectory. It incorporates
|
|
this information into a giant list of physical keys
|
|
([`physical_key_data.g.json`](data/physical_key_data.g.json)),
|
|
and another for logical keys
|
|
([`logical_key_data.g.json`](data/logical_key_data.g.json)).
|
|
The two files are checked in, and can be used as the data source next time so that
|
|
output files can be generated without the Internet.
|
|
|
|
## Running the tool
|
|
|
|
The tool can be run based on the existing database. To do this, run:
|
|
|
|
```bash
|
|
/PATH/TO/ROOT/bin/gen_keycodes
|
|
```
|
|
|
|
The tool can also be run by rebuilding the database by drawing online information
|
|
anew before generating the files. To do this, run:
|
|
|
|
```bash
|
|
/PATH/TO/ROOT/bin/gen_keycodes --collect
|
|
```
|
|
|
|
This will generate `physical_key_data.g.json` and `logical_key_data.g.json`. These
|
|
files should be checked in.
|
|
|
|
By default this tool assumes that the gclient directory for flutter/engine
|
|
and the root for the flutter/flutter are placed at the same folder. If not,
|
|
use `--engine-root=/ENGINE/GCLIENT/ROOT` to specify the engine root.
|
|
|
|
Other options can be found using `--help`.
|
|
|
|
## Key ID Scheme
|
|
|
|
To provide keys with unique ID codes, Flutter uses a scheme to assign keycodes
|
|
which keeps us out of the business of minting new codes ourselves. This applies
|
|
both logical keys and physical keys.
|
|
|
|
The codes are meant to be opaque to the user, and should never be unpacked for
|
|
meaning, since the coding scheme could change at any time and the meaning is
|
|
likely to be retrievable more reliably and correctly from the API.
|
|
|
|
However, if you are porting Flutter to a new platform, you should follow the
|
|
following guidelines for specifying key codes.
|
|
|
|
The key code is a 52-bit integer (due to the limitation of JavaScript). The
|
|
entire namespace is divided into 32-bit *planes*. The upper 20 bits of the ID
|
|
represent the plane ID, while the lower 32 bits represent values in the plane.
|
|
For example, plane 0x1 refers to the range 0x1 0000 0000 - 0x1 FFFF FFFF. Each
|
|
plane manages how the values within the range are assigned.
|
|
|
|
The planes are planned as follows:
|
|
|
|
- **Plane 0x00**: The Unicode plane. For logical keys, this plane contains keys
|
|
that generate Unicode characters when pressed (this includes dead keys, but
|
|
not e.g. function keys or shift keys). The value is defined as the Unicode
|
|
code point corresponding to the character, lower case and without modifier
|
|
keys if possible. Examples are Key A (0x61), Digit 1 (0x31), Colon (0x3A),
|
|
and Key Ù (0xD9). (The "Colon" key represents a keyboard key that prints the
|
|
":" character without modifiers, which can be found on the French layout. On
|
|
the US layout, the key that prints ":" is the Semicolon key.) For physical
|
|
keys, this plane contains keys from USB HID usages.
|
|
|
|
- **Plane 0x01**: The unprintable plane. This plane contains logical keys that
|
|
are defined by the [Chromium key
|
|
list](https://chromium.googlesource.com/codesearch/chromium/src/+/refs/heads/master/ui/events/keycodes/dom/dom_key_data.inc)
|
|
and do not generate Unicode characters. The value is defined as the macro
|
|
value defined by the Chromium key list. Examples are CapsLock (0x105),
|
|
ArrowUp (0x304), F1 (0x801), Hiragata (0x716), and TVPower (0xD4B).
|
|
Some keys that exist in the Chromium key list are not present in Flutter in this plane, most notably
|
|
modifiers keys (such as Shift). See the Flutter plane below for more
|
|
information.
|
|
|
|
- **Plane 0x02**: The Flutter plane. This plane contains keys that are
|
|
defined by Flutter. Modifier keys are placed in this plane, because Flutter
|
|
distinguishes between sided modifier keys (for example "ShiftLeft" and
|
|
"ShiftRight"), while the web doesn't (only has "Shift"). Other examples are
|
|
numpad keys and gamepad keys.
|
|
|
|
- **Plane 0x03-0x0F**: Reserved.
|
|
|
|
- **Plane 0x10-0x1F**: Platform planes managed by Flutter. Each platform plane
|
|
corresponds to a Flutter embedding officially supported by Flutter. The
|
|
platforms are listed as follows:
|
|
|
|
| Code | Platform |
|
|
| ---- | -------- |
|
|
| 0x11 | Android |
|
|
| 0x12 | Fuchsia |
|
|
| 0x13 | iOS |
|
|
| 0x14 | macOS |
|
|
| 0x15 | Gtk |
|
|
| 0x16 | Windows |
|
|
| 0x17 | Web |
|
|
| 0x18 | GLFW |
|
|
|
|
Platform planes store keys that are private to the Flutter embedding of this
|
|
platform. This most likely means that these keys have not been officially
|
|
recognized by Flutter.
|
|
|
|
The value scheme within a platform plane is decided by the platform,
|
|
typically using the other fields from the platform's native key event.
|
|
|
|
In time, keys that originally belong to a platform plane might be added to
|
|
Flutter, especially if a key is found shared by multiple platforms. The values
|
|
of that key will be changed to a new value within the Flutter plane, and all
|
|
platforms managed by Flutter will start to send the new value, making it a
|
|
breaking change. Therefore, when handling an unrecognized key on a platform
|
|
managed by Flutter, it is recommended to file a new issue to add this value
|
|
to `keyboard_key.g.dart` instead of using the platform-plane value. However,
|
|
for a custom platform (see below), since the platform author has full control
|
|
over key mapping, such change will not cause breakage and it is recommended
|
|
to use the platform-plane value to avoid adding platform-exclusive values
|
|
to the framework.
|
|
|
|
- **Plane 0x20-0x2F**: Custom platform planes. Similar to Flutter's platform
|
|
planes, but for private use by custom platforms.
|