A compilation of information about the layout formats usable in this app.
There are two distinct formats:
- the simple format is a text file with one key label per line, and two consecutive line breaks indicating a switch to the next row, example
- the json format taken from FlorisBoard, but only "normal" keys are supported (i.e. no action keys and similar), example
Adding too many keys or too long texts will make the keyboard look awkward or broken, and even crash the app under some specific conditions (popup keys are especially prone for this). There are some sanity checks when adding a layout to avoid such issues, but they do not cover all possible cases. Further there is no check whether the layout actually contains characters of the selected language.
If you use an external glide typing library, you likely will have issues if your layout contains duplicate keys, or keys with text longer than a single character.
If the layout has exactly 2 keys in the bottom row, these keys will replace comma and period keys. More exactly: the first key will replace the first functional key with "groupId": 1
in the bottom row, and the second key with replace the first key with "groupId": 2
.
- One key per line
- Key format: [label] [popup keys], all separated by space, e.g.
a 0 + *
will create a key with texta
, and the keys0
,+
, and*
on long press - see below for information about special labels
- Key format: [label] [popup keys], all separated by space, e.g.
- Two consecutive newlines mark beginning of a new row
- Normal json layout with lenient parsing, and ignoring lines starting with
//
.- For anything else than small changes and copy/pasting text the in-app editor is unsuitable. A proper text editor (e.g. Kate or Notepad++) can significantly simplify work on json files.
- Allows more flexibility than the simple format, e.g. changing keys depending on input type, shift state or layout direction
- You can use character layouts from FlorisBoard
- Support is not 100% there yet, notably
kana_selector
andchar_width_selector
do not work.
- Support is not 100% there yet, notably
- There is no need for specifying a
code
, it will be determined from the label automatically- You can still specify it, but it's only necessary if you want key label and code to be different (please avoid contributing layout with unnecessary codes to HeliBoard)
- Note that not all special codes (negative numbers) from FlorisBoard are supported
- Key classes: specified with
$
, usually you can omit them in HeliBoardtext_key
: normal key, defaultauto_text_key
: used in FlorisBoard for a key that changes text case when shift is enabled, HeliBoard does that anyway unless disabled with a labelFlagmulti_text_key
: key with an array of code points, e.g.{ "$": "multi_text_key", "codePoints": [2509, 2480], "label": "্র" }
- there are also selector classes, which allow to change keys conditionally, see the dvorak layout for an example:
case_selector
: keys forlower
andupper
(both mandatory), similar toshift_state_selector
shift_state_selector
: keys forunshifted
,shifted
,shiftedManual
,shiftedAutomatic
,capsLock
,manualOrLocked
,default
(all optional)variation_selector
: keys for input typesdatetime
,time
,date
,password
,normal
,uri
,email
,default
(all optional)keyboard_state_selector
: keys foremojiKeyEnabled
,languageKeyEnabled
,symbols
,moreSymbols
,alphabet
,default
(all optional)- the
keyEnabled
keys will be used if the corresponding setting is enabled,symbols
,moreSymbols
,alphabet
will be used when the said keyboard view is active
- the
layout_direction_selector
: keys forltr
andrtl
(both mandatory)
- A (non-selector) key can have the following properties:
type
: only specific values, HeliBoard mostly uses this to determine background color and type, determined automatically by defaultnormal
: normal key colorfunction
: functional key colorspace
: space bar coloraction
: action key colorunspecified
: no background colorplaceholder
: no background color, no label, and pressing the key does nothingnumeric
: normal key color, only in number layouts: sets default width to-1
and sets default label flags if none specified- There are some more values, but they do nothing
code
: code point that is entered when the key is pressed, determined from the label by default, not available formulti_text_key
- There are special negative values available, e.g. the ones used by functional keys, see KeyCode.kt. There are several not yet supported key codes in there, you can see in the function
checkAndConvertCode
which ones are working. - Special notes for the modifier keys
CTRL
,ALT
,FN
,META
- Currently there is no special lock-treatment, so you need to hold the key and press another key at the same time (like on a hardware keyboard)
- this means you should avoid putting popups on modifier keys (or press the other key quickly)
- There are special negative values available, e.g. the ones used by functional keys, see KeyCode.kt. There are several not yet supported key codes in there, you can see in the function
codePoints
: when multiple code points should be entered, only available formulti_text_key
label
: text to display on the key, determined from code if empty- There are some special values, see the label section
groupId
: which additional popup keys to show,0
is default and does not add anything,1
adds the comma popup keys,2
adds the period popup keys,3
adds the action key popup keys (looks awkward though)popup
: list of keys to add in the popup, e.g."label": ")", "popup": {"relevant": [{ "label": "." }]}
is a)
key with a.
popup- Note that in popup keys, properties are ignored with the exception of
$
,code
,codePoints
, andlabel
- When specifying a selector key class in a popup key, it will be evaluated correctly (e.g. for changing popups dependent on shift state)
- If popups are added to repeating keys (e.g. delete, arrow keys), repetition will be disabled.
- Note that in popup keys, properties are ignored with the exception of
width
: width of the key in units of screen width, e.g. a key with"width": 0.1
has a width of 10% of the screen, defaults to0
- A special value is
-1
, which means the key expands to the available space not already used by other keys (e.g. the space bar) 0
is interpreted as follows-1
on thespace
key in alphabet or symbols layouts, and for keys with"type": numeric
in number layouts0.17
for number layouts0.1
for phones0.09
for tablets
- If the sum of widths in a row is greater than 1, keys are rescaled to fit on the screen
- A special value is
labelFlags
: allows specific effects, see here in the section keyLabelFlags for names and numeric values
In the simple format you only specify labels, in json layouts you do it explicitly via the label
property.
Usually the label is what is displayed on the key. However, there are some special labels:
- Currency keys
$$$
will be replaced by the local currency, depending on your current layout language. If you define a key with$$$
without defining popup keys, it will get the first 4 additional currencies (see below) as popup$$$1
-$$$5
will be replaced by currencies available on long-pressing the currency key
- Functional keys (incomplete list)
- alpha: switch to alphabet keyboard (or main phone keyboard in case of phone layout)
- symbol: switch to symbol keyboard (or phone symbols keyboard in case of phone layout)
- symbol_alpha: toggle alpha / symbol keyboard
- numpad: toggle numpad layout
- emoji: switch to emoji view
- com: display common TLDs (.com and similar, currently not localized)
- language_switch: language switch key
- action: the action (enter) key
- delete: delete key
- shift: shift key, will change label when in symbols layout
- period:
.
key with punctuation popups, will adapt to language-specific period - comma:
,
key with special popups, will adapt to language-specific comma, or display/
in URL fields and@
in email fields - space: space key, with icon when using a number layout
- zwnj: Zero-width non-joiner (automatically added next to space in alphabet layout for some languages)
- You can also use toolbar keys, e.g. undo.
- See KeyLabel.kt for more available labels that are parsed to the corresponding key.
- In case a label clashes with text you want to add, put a
\
in front of the text you want, e.g.\space
will write the labelspace
instead of adding a space bar.- Note that you need to escape the
\
in json files by adding a second\
.
- Note that you need to escape the
- If you want different key label and input text, set the label to [label]|[text], e.g.
aa|bb
will showaa
, but pressing the key will inputbb
. You can also specify special key codes likea|!code/key_action_previous
, but it's cleaner to use a json layout and specify the code explicitly. Note that when specifying a code in the label, and a code in a json layout, the code in the label will be ignored. - It's also possible to specify an icon, like
!icon/previous_key|!code/key_action_previous
.- You can find available icon names in KeyboardIconsSet. You can also use toolbar key icons using the uppercase name of the toolbar key, e.g.
!icon/redo
- You can find available icon names in KeyboardIconsSet. You can also use toolbar key icons using the uppercase name of the toolbar key, e.g.
- You need a layout file in one of the formats above, and add it to layouts
- Popup keys in the layout will be in the "Layout" popup key group.
- If you add a json layout, only add key type (
$
) andcode
if necessary
- Add a layout entry to
method.xml
KeyboardLayoutSet
inandroid:imeSubtypeExtraValue
must be set to the name of your layout file (without file ending)android:subtypeId
must be set to a value that is unique in this file (please use the same length as for other layouts)- If you add a layout to an existing language, add a string with the layout name to use instead of
subtype_generic
. The new string should be added to defaultstrings.xml
, and optionally to other languages.%s
will be replaced with the language.
- If you add a new language, you might want to provide a locale_key_texts file
[popup_keys]
section contains popup keys that are similar to the letter (likea
andä
orय
andय़
)- Such forms should not be in the layout. They will apply to all layouts of that language, even custom ones.
- The popup keys will be added to the "Language" popup key group (relevant for setting popup key order).
- Use
%
to mark all preceding keys as "Language (important)" instead. Keys after%
will still be in the "Language" group.
- Use
- The
punctuation
key is typically the period key.popup_keys
set here override the default.
[labels]
may contain non-default labels for the following keyssymbol
,alphabet
,shift_symbol
,shift_symbol_tablet
,comma
,period
,question
[number_row]
may contain a custom number row (1-9 and 0 separated by space). You should also add the language tonumberRowLocales
inPreferencesSettingsFragment
so the user can opt into having a localized number row.[extra_keys]
are typically keys shown in the default layout of the language. This is currently only used for latin layouts to avoid duplicating layouts for just adding few keys on the right side. The layout name need to end with+
, but the+
is removed when looking up the actual layout.
- If you add a new language for which Android does not have a display name, it will be displayed using the language tag
- Avoiding this currently is more complicated than necessary: add the language tag to LocaleUtils.getLocaleDisplayNameInSystemLocale to have an exception, and add a string named
subtype_<langage tag, but with _ instead of ->
tostrings.xml
. Further you may need to add asubtype_in_root_locale_<language tag>
to donottranslate.xml, and add the language tag tosubtype_locale_exception_keys
andsubtype_locale_displayed_in_root_locale
.
- Avoiding this currently is more complicated than necessary: add the language tag to LocaleUtils.getLocaleDisplayNameInSystemLocale to have an exception, and add a string named
- If a newly added language does not use latin script, please update the default scripts method
Locale.script
in ScriptUtils
Customizing functional keys mostly works like other layouts, with some specific adjustments:
- When using the default functional layout, emoji, language switch and numpad keys are actually always in the layout, but get removed depending on settings and the main layout (alphabet, symbols or more symbols). This removal is disabled when you customize any functional layout, so to not block you from adding e.g. a numpad key in alphabet layout.
- When you use a language that has a ZWNJ key, the key will automatically be added to the right of the (first) space bar in the bottom row
- Adding popups to keys that switch layout does not work properly, as usually the layout is switched as soon as the key gets pressed.
- use keys with
"type": "placeholder"
for- separating left and right functional keys (e.g. shift and delete in default layout)
- separating top and bottom rows in case you want to have functional key rows aligned to the top of the keyboard (add a row with the placeholder as the only key)
- if the last row in functional keys does not contain a placeholder, it is used as bottom row (like in the default functional layout)
- When you functional keys only for some of alphabet, symbols and more symbols, behavior is as follows
- more symbols will fall back to symbols, then normal
- symbols will fall back to normal, then default (if you only customized more symbols functional layout)
- normal will fall back to default (if you only customized symbols and/or more symbols functional layout)