Importing from other keyboards
Bring layouts, themes, dictionaries, input methods and whole settings backups over from FlorisBoard, HeliBoard, LeanType, FUTO, CleverKeys, Unexpected Keyboard, AnySoftKeyboard, Samsung Keyboard (Keys Cafe), Multiling O, Gboard, gcin, OpenVanilla, Rime and m17n, plus layouts made for Windows, macOS and Linux: what converts, what doesn't, and why.
Switching keyboards usually means leaving your layouts, themes and dictionaries behind. WM Keyboard reads FlorisBoard, HeliBoard, LeanType, FUTO, Unexpected Keyboard, CleverKeys, Samsung Keyboard (Keys Cafe) and Multiling O files directly and converts them into its own, so the grid you built, the theme you picked and the word list you collected come with you. It also reads the layout files people make for computers (Windows .klc, macOS .keylayout and Linux XKB), which is where a lot of layouts for smaller languages live.
Conversion is honest about being lossy. A layout import always ends on a confirm dialog that lists what changed and what could not be carried, and nothing is written until you accept it. A .flex theme opened from a file manager gets the same treatment. The FlorisBoard button inside Settings is the one route without a confirm step: it saves the theme straight away and then tells you what it saved. Saved is not switched on, so you still get to look first.
What can be imported
Section titled “What can be imported”| File | From | Opens as |
|---|---|---|
.json layout | FlorisBoard, HeliBoard | A custom layout |
.txt layout | HeliBoard | A custom layout |
.yaml layout | FUTO Keyboard | A custom layout |
.kcf layout | Samsung Keyboard, shared from Keys Cafe | A custom layout, kept exactly as it was laid out |
| DIY or DIY+ layout text, or a settings export | Multiling O Keyboard | A custom layout with its symbols and AltGr pages, or every layout in the export |
.xml layout | Unexpected Keyboard, CleverKeys | A custom layout that keeps the swipes to each key’s corners |
.klc layout | Windows, made in Microsoft Keyboard Layout Creator | A custom layout, with AltGr and dead-key letters on press and hold |
.keylayout layout | macOS, made in Ukelele | A custom layout, with Option and dead-key letters on press and hold |
XKB symbols file | Linux | A custom layout for each variant in the file |
.flex theme | FlorisBoard 0.4 and later | One theme, one look per theme in the file |
.zip theme | FUTO Keyboard | One theme, with its background picture and font |
.flex language pack | FlorisBoard | A Cangjie or stroke table for Chinese |
.cin table | gcin, hime, OpenVanilla, xcin, and the shared Cangjie, Array, Boshiamy, Dayi and Wubi tables | A layout that types the table: see Input methods |
.schema.yaml with its .dict.yaml files | Rime (Weasel, Squirrel, Trime, fcitx5-rime) | A layout that types the schema |
.mim | m17n (ibus-m17n, fcitx5-m17n): ITRANS, InScript, Tamil99 and the other Indic methods | A layout whose rules write the text as you type |
| Colour theme text | HeliBoard, LeanType | One theme, from a file or from the clipboard |
OK_Settings_Begin theme text or a theme link | Multiling O Keyboard | One theme, from a file or from the clipboard |
.zip theme | Gboard, the Rboard community | One theme, with a look each for key borders on and off |
.zip or .pack theme pack | Rboard | Any or all of the themes inside, each its own theme |
.keyman-touch-layout | Keyman | A custom layout, without the keyboard’s rules |
.kmp package | Keyman | A custom layout and its typing rules |
.combined word list | HeliBoard, LeanType, FUTO, any AOSP keyboard | A custom dictionary |
.dict dictionary | HeliBoard, LeanType, FUTO, OpenBoard, GApps | A custom dictionary |
PersonalDictionary.zip, or the dictionary.txt inside it | Gboard | Words in your personal dictionary, and shortcuts as snippets: see Gboard’s personal dictionary |
Backup .zip | HeliBoard, LeanType, FlorisBoard, CleverKeys | A list of everything inside to pick from: see Whole backups |
Backup .backup | FUTO Keyboard | The same list |
AnySoftKeyboardPrefs.xml, or a CleverKeys settings .json | AnySoftKeyboard, CleverKeys | The same list, settings only |
HeliBoard’s JSON layouts use FlorisBoard’s format, so one reader handles both. LeanType is a HeliBoard fork, so its layouts and themes are HeliBoard’s.
Keyman is a different case. 862 Keyman key grids are already built into the app, so for most of them there’s nothing to import. You can still open a .keyman-touch-layout file or a full .kmp package yourself, which is how you’d add a keyboard that isn’t bundled or one you’re writing. A .kmp brings its typing rules with it; a touch layout file does not. See Keyman layouts.
Whole backups
Section titled “Whole backups”Most keyboards can save everything to one file: their settings, your layouts, your themes and the words they learned. WM Keyboard reads that file whole and shows you what is in it, one row per item, before anything is written. Every row starts ticked. Untick what you don’t want, then tap Import.
Open the file from WM Keyboard Data Backup & restore Import from another keyboard, from a file manager, or from Restore a backup on the first page of the setup wizard, where it also skips the rest of the wizard.
To make the file on the other keyboard:
| Keyboard | What to look for |
|---|---|
| HeliBoard, LeanType | Backup and restore in its settings, under Advanced. You get a .zip |
| FUTO Keyboard | Export settings in its settings. You get a .backup file, which is a ZIP |
| FlorisBoard | Backup & Restore in its settings, under Advanced. You get a .zip |
| CleverKeys | Its backup screen. A full backup .zip or a settings .json both work |
| AnySoftKeyboard | Its backup screen. You get AnySoftKeyboardPrefs.xml |
Menu names differ between versions of each keyboard; look for “backup” or “export” in its settings.
What comes across
Section titled “What comes across”| Part | HeliBoard, LeanType | FUTO | FlorisBoard | CleverKeys, AnySoftKeyboard |
|---|---|---|---|---|
| Your own letter layouts | Yes | Yes | Yes | CleverKeys: yes, with the language you set for each. AnySoftKeyboard: no |
| Your colour themes | Yes, and the one in use is switched on | Yes, and the one in use is switched on | Yes, and the one in use is switched on | No |
| Your languages | Yes, each with the closest built-in layout, or with your own layout when it is imported too | Yes | Yes | No |
| Dictionaries you added | Yes | Yes | None in the backup | No |
| Words learned from your typing | Yes, as a word list | Yes, as a word list | None in the backup | No |
| Words you added by hand | None in the backup, see the note below | Yes, as words you added here | None in the backup | No |
| Words never suggested | Yes | Yes | No | No |
| Settings | Yes | Yes | Yes | Yes |
Languages are added in front of the ones you already have, and the first becomes the one you type in. The app downloads each new language’s word list and prediction data in the background, the same way the setup wizard does.
A layout keeps its name. HeliBoard stores the name it was given in its file name, and that is what you see. A layout made for one language is filed under that language; a layout made for a whole script (HeliBoard’s “Latin” layouts) is filed under the language its letters suggest. You can change it later in the layout editor.
Learned words arrive as their own list under Custom dictionaries, not mixed into this keyboard’s learning, so you can switch them off or delete them in one place.
Which settings come across
Section titled “Which settings come across”Only settings that mean exactly the same thing in both keyboards are offered. Each one is a row of its own, with the value it will get here.
| Setting here | What the other keyboard calls it |
|---|---|
| Number row | Number row |
| Key popup | Popup on key press |
| Vibrate on key press, Vibration length | Vibration, and its length in milliseconds |
| Sound on key press, Key sound volume | Sound, and its volume |
| Autocorrect | Autocorrection |
| Automatic capitals | Auto-capitalization |
| Double space types a period | Double-space period |
| Suggestions, Emoji suggestions | Show suggestions, emoji suggestions |
| Glide typing | Gesture or glide input |
| Long press delay | Long press timeout |
| Key height | Keyboard height, from its scale (1.25 times is 60 dp here) |
| Split keyboard | Split keyboard |
| Light or dark | The light, dark or black colour set, or following the system |
| Press and hold on toolbar keys | HeliBoard and LeanType’s toolbar key codes: the long press you set for each toolbar key |
A toolbar key’s long press comes across only where you changed it in HeliBoard. The long presses HeliBoard ships with (Undo to redo, Copy to cut, Clipboard to paste and the rest) are the pairs this app holds to already. A long press set to repeat the key is left out, since here that is the cursor tools’ own setting, and so is one with no tool here, like clearing the clipboard history.
Values are kept inside this app’s own limits: a vibration of 100 ms becomes 60 ms, the most this app allows. A value that only means “use the system’s”, like HeliBoard’s default vibration length, is left out, because this app already does that when nothing is set. Settings that look alike but measure something else, like each keyboard’s autocorrect strength, are left out rather than guessed at.
Settings are written the way a restore of this app’s own backup is: the keyboard reads its settings back afterwards, and puts everything back as it was if they no longer read.
What does not come across
Section titled “What does not come across”The list ends with what the backup holds that has nowhere to go here, so nothing disappears without a word:
- Clipboard history. Never imported. It belongs to the other keyboard and is often private.
- Symbol and number layouts. This app draws those from its own.
- Theme files the app cannot read, such as a damaged one.
- Custom fonts and background pictures from HeliBoard.
- Language models and voice data from FUTO, which are that keyboard’s own engines.
- Shortcuts on FUTO’s added words. The words come across; the shortcuts on them do not.
HeliBoard keeps the words you add by hand in Android’s own personal dictionary, not in its backup. Bring those across from WM Keyboard Typing Suggestions Personal dictionary with its import from Android.
Layouts
Section titled “Layouts”Pick the file. The app reads it, then puts one dialog in front of you before it saves anything. Only one thing on that dialog needs an answer: the language. Everything else tells you what the conversion did, and the Import button is your confirmation.
It asks for the language
Section titled “It asks for the language”The FlorisBoard and HeliBoard formats do not record one. There a layout is a grid and the language comes from the keyboard’s own settings, so the file itself cannot say whether a Cyrillic grid is Russian or Ukrainian. A FUTO layout does state its languages, and the picker starts from that instead of from a guess.
That matters more here than it sounds. The language picks the dictionary, the autocorrect, the script rules, dictation, and how the shift key behaves. The app guesses from the letters on the keys and shows you the guess, and you can change it before you import. There is no silent default.
It adds the shift key and the bottom row
Section titled “It adds the shift key and the bottom row”A foreign layout file carries one grid, and the keyboard that reads it draws the symbols and number layers itself. So the app supplies those, and the imported layout uses WM Keyboard’s built-in symbols and number grids.
The frame around the letters gets the same treatment, so an imported layout ends the way the built-in ones do:
- The last letter row gets ⇧ at the start and ⌫ at the end, both one and a half keys wide.
- Below it goes the usual bottom row: ?123, comma, 🌐, a spacebar four keys wide, full stop and ⏎.
What the file says still wins where it says something:
- A delete key the file placed stays where it is. The layout then gets no shift key added either, because placing the delete key yourself is how a FUTO layout says it wants no automatic shift key.
- A bottom row the file wrote is read, not thrown away. Its comma and full stop keep their own characters and press-and-hold letters, so a Bengali
।, an Urdu۔or an Arabic،comes across. A key the usual row has no place for, such as a tab key, keeps a place next to the spacebar. A letter on that row, such as an apostrophe or a ZWNJ key, moves up to the end of the last letter row. - A key the letter rows already have is not added twice. A PC-style grid with its enter key on the home row, or its comma and full stop beside the letters, gets no second one.
HeliBoard’s text format and FlorisBoard’s character grids have no way to write any of these keys, so those layouts always get the whole frame. A Keys Cafe layout is the opposite case and gets none of it; see below. A layout with a key taller than one row keeps the shape its author gave it, because moving keys would slide them under the tall one. It still gets a delete, space and enter key if it has none, and the dialog names the ones it added.
Keys that cannot come across
Section titled “Keys that cannot come across”Some keys in those formats do things WM Keyboard reaches another way: voice input, the clipboard panel, the settings screen, the suggestion-bar toggles. Those are tools here rather than keys, so they are removed and the dialog names the codes it removed. A key that looked right and quietly did nothing would be worse.
A handful of keys convert to the closest match rather than an exact one, and the dialog counts those too. Delete-word becomes a plain delete; the second symbols page folds onto the symbols key.
Keys named by a word
Section titled “Keys named by a word”HeliBoard’s text format has one field per key, so it spells everything in the label. A key that says delete is the delete key, $$$ is the local currency, aa|bb shows aa and types bb, and abc|!code/-7 names a code outright. The app reads all of it:
| In the file | Becomes |
|---|---|
delete, shift, space, action, zwnj | That key |
alpha, symbol, numpad, emoji, language_switch | The matching layer or switch key |
period, comma | The punctuation slots, with this keyboard’s own popups and its email and URI behaviour |
ctrl, alt, meta, fn | The modifier keys |
com | A .com key. The other keyboard localises this one, so it is counted as approximated |
$$$, $$$1 to $$$5 | Currency signs. Also localised there, also counted |
aa|bb | A key drawn aa that types bb |
x|!code/-7 | Whatever that code means, here delete |
\space | A key that draws the word “space”. A backslash escapes the whole label |
A name this keyboard has nothing for, such as dpad, is removed and named on the dialog. An icon name (!icon/previous_key) refers to the other keyboard’s own drawable, so the key keeps whatever its action draws here and the dialog counts the loss.
Keys that change with the shift key or the field
Section titled “Keys that change with the shift key or the field”A JSON layout can make one key conditional: case_selector for the shift state, variation_selector for the field, keyboard_state_selector, layout_direction_selector. HeliBoard’s own Dvorak layout is written this way.
One slot here holds one key, so the app keeps the resting branch: unshifted, an ordinary text field, left to right. The dialog counts the keys that lost a branch.
case_selector is the exception and loses nothing. Its two branches are exactly this keyboard’s key and shift-label pair, so both cases come across, and a shifted letter that is only the plain uppercase is left for the keyboard to produce on its own.
An auto_text_key changes case with the shift key over there, whatever case its code is written in. The app takes the lowercase as the key’s own and leaves the capital to the shift key. Some published grids write a lowercase label on the code of the capital letter (FlorisBoard’s Rusyn grid does this for ї, ы and ё), and those keys would otherwise type the capital with no shift.
Press-and-hold options
Section titled “Press-and-hold options”The other keyboard writes a popup’s options inside the popup list, wrapped in exclamation marks. !fixedColumnOrder!4 and !autoColumnOrder!4 become that key’s Alternate columns, which you can change afterwards in the layout editor. !hasLabels!, !needsDividers! and !noPanelAutoPopupKey! ask for drawings this keyboard decides for itself and are dropped. None of them is a letter, so none ends up as a key you can type.
Label flags become label sizes
Section titled “Label flags become label sizes”HeliBoard keys can carry a labelFlags number, which is how a layout says that one key’s label is a word rather than a letter and should be drawn at a different size. Layouts with unusual key captions need it to look right.
The app reads it. Four of those flags set a size, and each one becomes that key’s Label size in the layout editor, so you can see it and change it afterwards:
| Flag in the file | Label size here |
|---|---|
followKeyLargeLetterRatio | ×1.15 |
followKeyLetterRatio | ×1 |
followKeyLabelRatio | ×0.68 |
followKeyHintLabelRatio | ×0.44 |
Two more need no size at all. disableKeyHintLabel turns on Hide the corner hint for that key, which means the same thing. autoScale and autoXScale ask for a label that shrinks to fit its key, and WM Keyboard already does that to every label on every layout.
Write the number in decimal or in hex ("labelFlags": 320 and "labelFlags": "0x140" are the same key). An exported file uses decimal.
The rest of the flags ask for a text style this keyboard has no form of, such as a monospaced or an off-centre label. Those keys keep their size and lose the style, and the dialog counts them.
FUTO layouts
Section titled “FUTO layouts”FUTO Keyboard writes its layouts in YAML, and publishes its own as a repository of them. Pick one with the same Import from another keyboard button; the app tells a YAML layout from a JSON one by the document itself, not by the file name. Tapping one in a file manager works too. .yaml is not claimed by name, because that would offer WM Keyboard for every YAML file on your phone, but the YAML content types are, and the same name:-and-rows: test recognizes the file. Either way the language is confirmed before the layout is saved.
Most of that format reads straight across, because FUTO’s keyboard descends from AOSP’s and so its key specs are the ones already read here: a|b, !code/, !icon/ and the same !autoColumnOrder!4 popup markers. A row written as q w e r t, as [[a, ą], b], or as a list of {type: base, spec: …} objects all work, and so does type: case, which keeps both cases the way a FlorisBoard case selector does. When the key has no shifted branch, its shiftedManually one is the shifted letter. That is how a script with no capital letters writes its second layer: Korean ㅂ over ㅃ, and the Khmer, Myanmar and Bengali layouts.
Four differences:
- It is the one format that states its language.
languages: [lt]seeds the language picker with a fact rather than a guess from the letters. A language this app does not have falls back to the guess. - The number row is dropped, because this app adds one from a setting and keeping the file’s would give the layout two. A layout that sets
numberRowMode: AlwaysEnabled, which is how the PC-style arrangements carry their backtick and bracket keys, keeps its own. - Its bottom row becomes this app’s, as above, keeping the file’s own comma and full stop. The
$actionkey, which the user sets in FUTO’s own settings, is dropped and named. - The alternate pages are dropped and named.
$alt0and its siblings switch to a whole second grid, which has no slot here, and a key that switched to nothing would strand you on it. The symbols and number layers are this app’s own for the same reason, andlayoutSetOverridesnames layouts by ids that mean nothing here.
$contextual becomes the comma slot, which does the same job from the same signal: / in a web address, @ in an email field.
Samsung Keyboard (Keys Cafe) layouts
Section titled “Samsung Keyboard (Keys Cafe) layouts”Keys Cafe is Samsung’s Good Lock module for Samsung Keyboard, and its Make your own keyboard screen is a key-by-key editor for the whole grid. A keyboard made there is saved and shared as a .kcf file, which is what people trade on the Samsung community forums. Pick one with the same Import from another keyboard button, or tap it in a file manager: WM Keyboard claims the .kcf extension, and it also recognizes the file by its contents, so a renamed one still works.
A .kcf is a layout and only a layout. Keys Cafe’s Style your own keyboard colours and effects are a Samsung theme, not part of this file, and nothing of them comes across.
This is the one format that carries the whole frame. Keys Cafe writes the shift and delete keys, the symbols key, the space bar, enter and the bottom row exactly where you put them, and a bottom row with a letter or two beside the space bar is often the point of the file. So the import adds nothing and moves nothing: the grid lands as laid out, and the layer is marked to keep its bottom row as drawn, so the Bottom row settings (the 🌐 key’s place, comma and 🌐 swapped, the emoji key) leave it alone. Only a file whose author removed the space bar or the delete key gets WM Keyboard’s frame put round what is left.
- The number row is kept as this layout’s own number row, digits and their fraction popups included. It shows while the number row is on under Layout & size, the same as any layout’s.
- The corner symbol is the first press-and-hold entry, so it stays the corner hint and a long press still types it, as it did on Samsung Keyboard. The key’s other press-and-hold letters follow it. Samsung Keyboard keeps a second list for the shifted state; where that list is more than the capitals of the first, the dialog counts the key.
- The language is a fact, not a guess. The file states a language and a country, and the picker starts from it.
- Widths follow the file. A plain key is one unit, a wider shift or space bar keeps its proportion.
- A function key this app does not know is removed and named by its code, the same as a HeliBoard key would be. One real export has been read, so the known codes are the delete, shift and symbols keys, space and enter. If the dialog names a code and you know what that key was, say so in an issue and it is one line to add.
Multiling O Keyboard layouts
Section titled “Multiling O Keyboard layouts”Multiling O builds its layouts out of text, and its users share them as text: in forum posts, gists and READMEs, for scripts few other keyboards ship. Copy the text into a .txt file and pick it with the same Import from another keyboard button, or open the file from a file manager. Three forms are read:
- A DIY layout, a JSON object with a
titleand anonScreenobject holding the rows of each page (main,sym,altGrand the rest). It is the whole keyboard, bottom row included, so it is kept as laid out, the way a Keys Cafe layout is. A layout copied out of a share link, with%0Aand%22in it, reads the same. - A DIY+ layout, the block from
OK_Layout_BegintoOK_Layout_End. Its rows come in blocks of four: the letters with a row of digits on top, the same rows shifted, then the symbols, the AltGr page, the shifted AltGr page and the shifted symbols. It has no shift, delete or bottom row of its own, so it gets this app’s, as above. The row of digits becomes this layout’s number row. - A settings export, the block from
OK_Settings_BegintoOK_Settings_Endthat Multiling writes under Misc → Import | Export. It holds every layout you made, each filed under the language it was made for. The dialog lists them all and adds them all in one step, each with that language, or with the one its letters suggest where this app does not have the language. The colours in the export are saved as a theme beside them. Landscape copies of a layout are skipped: this app sizes one grid for both.
A row is a string of keys, and each part comes across like this:
- A character is a key, and a space is a gap.
[]straight after a key makes it one key wider, as[SPACE][][]does. - Named keys (
[SHIFT],[DEL],[ENTER], the arrows, copy and paste, F1 to F12 and the rest) become the same keys here.[WDEL]is a plain delete key, because swiping left on delete removes whole words here. [4D:…],[1+4:…]and[3+2:…], the swipe keys, keep their swipes. The first character is the tap and the rest are the eight directions, the way a MessagEase pad has them. A swipe that runs a key (a cursor move, copy, a page switch) keeps doing that. A swipe on a key whose own swipe is already taken here, such as the delete key or the space bar, is removed and counted.[XK:…]types its first character, with the rest on its press and hold.[MT:…]cycles through its characters on repeated taps.[MC:…]types more than one character, under its own label when it gives one. A shortcut such as[MC:[CTRL]z:undo]becomes that key press. Multiling’s date and time macros are removed and named.[U+0915]is the character with that code.[SYM:.],[ALTGR:,]and[123:…]type their character on a tap and open their page when you swipe from them in any direction. The page is on their press and hold too.
The pages come across with the layout. sym and symShifted become this layout’s two symbols pages. AltGr, 123 and Edit become pages of the layout, opened from the same keys as before; on a DIY+ layout, swipe from the comma key or hold it to open AltGr. A shifted page laid out key for key like the page it shifts becomes the shifted forms of those keys. Multiling’s tool key opens a menu that this app keeps on its toolbar, so it becomes ?123 on a letters page that has no other way to the symbols, and ABC on a page that has no other way back. A key this app has nothing for, such as [INFO] or [PREDICT], is removed and named in the dialog.
Unexpected Keyboard and CleverKeys layouts
Section titled “Unexpected Keyboard and CleverKeys layouts”Unexpected Keyboard has no layout editor of its own: a custom layout is a block of XML pasted into its settings, and people share them that way, in the project’s community layouts repository, in gists and in issue threads. CleverKeys reads and shares the same XML. Save the XML as a .xml or .txt file and pick it with the same Import from another keyboard button, or open the file from a file manager. A CleverKeys backup brings its custom layouts with it; see Whole backups.
- The swipes stay swipes. Each key’s tap (
c, orkey0in older files) is the key, and the eight corner and edge swipes (nw,ne,sw,se,n,s,e,w, orkey1tokey8) become the key’s flick arms, drawn on its face as they were. A swipe that types text is on the key’s press and hold too. A swipe that runs a key, such as a cursor move or copy, keeps doing that. A swipe on a key whose own swipe is already taken here, such as delete’sne="delete"or a space bar’s cursor swipes, is removed and counted. - Swipe typing still works on the letters. A short swipe that stays on the key is the flick; once your finger leaves the key for the next letter, the stroke is a glided word. A key with a cursor or delete swipe keeps its whole stroke, so swipe typing never starts on it. A letter reachable only through a dead key, such as â behind the French AZERTY’s circumflex, isn’t on the glide grid, so a word with one in it has to be tapped. The rest of the language still glides (see when a layout can’t spell the language).
- Named keys (
shift,backspace,enter, the arrows,copy,paste,undo, F1 to F12 and the rest) become the same keys here.switch_numericopens the ?123 page andswitch_forwardchanges language. The accent keys (accent_aigu,accent_graveand the rest) become dead keys.legend:'text'types the text under that label,legend:keyevent:85sends that key code, and a macro of modifiers and one letter, such asCz:ctrl,z, becomes that key press. A key this app has nothing for, such ascomposeorswitch_greekmath, is removed and named in the dialog. - A
lockey is skipped. Unexpected Keyboard shows those only when a setting adds them, so nothing is said about them. - The bottom row is this app’s, as above, unless the file says
bottom_row="false"and has its own space bar and delete key. Such a grid is kept as laid out, the way a Keys Cafe layout is. - The number row is this app’s, unless the file says
embedded_number_row="true". Then its row of digits becomes this layout’s own number row. - Gaps and widths follow the file. A key’s
shiftbecomes a gap to its left, and a row that starts with one stays aligned to the left, as it was. Row heights come across too. <shift a="i" b="İ"/>in themodmapbecomes that key’s shifted form. The Fn and Ctrl mappings have no place here and are left out.- The language is the one a CleverKeys layout names in its
languageattribute, or in a backup the one you set for it there. Otherwise the picker starts from the letters on the keys.
Layouts made for a computer (Windows, macOS, Linux)
Section titled “Layouts made for a computer (Windows, macOS, Linux)”Plenty of keyboard layouts for smaller languages were only ever made for a computer. Someone built one in Microsoft’s Keyboard Layout Creator or in Ukelele, or wrote an XKB file for Linux, and put it on a university page or a forum. WM Keyboard reads all three. Pick the file with the same Import from another keyboard button, or open it from a file manager.
| File | Made with | How the app knows it |
|---|---|---|
.klc | Microsoft Keyboard Layout Creator (MSKLC), Windows | The extension, and its KBD, SHIFTSTATE and LAYOUT sections. MSKLC saves these files as UTF-16, and the app reads them that way |
.keylayout | Ukelele, or by hand, macOS | The extension, and its <keyMapSet> |
XKB symbols file | Linux, the files under /usr/share/X11/xkb/symbols/ | Its xkb_symbols "name" { blocks. These files have no extension, so only the contents count |
A computer keyboard has about 48 keys that type something, with four levels on each: plain, Shift, AltGr (Option on a Mac), and Shift with AltGr. A phone grid has room for about 30 keys and two levels, so the layout gets folded down:
- The 26 letter keys stay where they are, whatever they type. The keys around them come across too when they type a letter, at the end of their row: Danish æ ø å, a Dvorak s where QWERTY has its semicolon. Keys that type only punctuation are left to this app’s symbol pages.
- The number row becomes a row of the grid only when five or more of its keys type letters, the way the Czech, Slovak and Lithuanian layouts are built. With fewer, each letter goes on press and hold of the letter it is built on (é on e, which is where AZERTY users reach it on a phone anyway), or onto the end of the shortest row when it is not built on one (German ß).
- Shift comes across as each key’s shifted form, where that is more than the capital letter.
- AltGr goes on press and hold of the same key, first, so the corner hint shows what the key’s AltGr level was.
- Dead keys go on press and hold too. Every letter on the grid gets the accented letters the file’s dead keys make of it, so a dead acute puts á on a and é on e. A dead key that sits on one of the letter keys keeps its place and works as a dead key here.
- Nothing is dropped without a word. Characters on the left-out keys that are not plain ASCII or digits, such as Armenian ՝ or Ethiopic ።, go on press and hold of the full stop. The dialog says how many.
- Shift, delete and the bottom row are this app’s, as above.
A .klc names its language (LOCALENAME), and the picker starts from it. The other two do not, so the app guesses from the letters as usual.
An XKB file usually holds several variants. The import offers each one that is a whole layout, the default first, and adds them all at once; parts that only set up modifier keys are skipped. A variant often builds on another with include "us(basic)". An include of a variant in the same file is followed, and so are the plain US and Latin bases, which are built in. An include of any other file cannot be, since you opened only the one file, so the dialog names it and you know which keys may be missing. Includes that only set up modifiers, such as level3(ralt_switch), carry no characters and are not mentioned. An XKB dead key (dead_acute) puts its accent on a letter the way Unicode composes them, because the real tables live in your Linux system’s Compose file, not in the layout.
Letters are rewritten to one spelling
Section titled “Letters are rewritten to one spelling”Some letters can be written two ways in Unicode: a base letter plus a mark, or a single character that means the same thing. Bengali, Devanagari, Gurmukhi and Oriya all have letters like this. WM Keyboard’s cluster shaping and its backspace rules use the single-character spelling, so the app rewrites the other one on the way in. Without it a key looks correct and then deletes half a letter at a time.
Dictionaries
Section titled “Dictionaries”Every AOSP-derived keyboard shares one dictionary ecosystem, and for most languages a compiled .dict is the only form the word list exists in. All of it imports here as it is: the .combined source lists a dictionary repository publishes, the compiled .dict files HeliBoard, LeanType and FUTO download (including the ones pulled out of a GApps package), and the version 4 dictionaries those keyboards write on the device.
What each part becomes
Section titled “What each part becomes”An AOSP dictionary holds three things, and each goes where this app keeps that kind of thing:
| In the dictionary | Here |
|---|---|
| Words and their frequencies | An ordinary text word list |
| Word pairs (bigrams), and word triples in a version 4 file | Next-word predictions, like a downloaded Word pairs pack |
Shortcuts, such as omw for “on my way” | The first suggestion when you type the short form in full, and a trigger for glide typing |
When the file has more than words, a dialog asks which of the three to import. The pairs and shortcuts are stored beside the word list and follow it: switch the list off and they stop, delete it and they go. A list imported for its pairs alone still shows on the Custom dictionaries screen, with no words in it, so there is something to switch and delete.
A .dict is unpacked into an ordinary text list at import, so everything the Custom dictionaries screen does to a list you wrote yourself works on it too: the word count, the switch, the trash icon, and taking a single word out from the suggestion strip.
Frequencies are 0 to 255 over there and 0 to 10000 here, so they are scaled rather than copied. Copying them would drop every imported word below every bundled one. A pair’s strength is scaled onto the counts of a downloaded pack, where the strongest pairs weigh about as much as a pair you typed a few dozen times yourself.
A shortcut the source keyboard applied on its own (a “whitelist” shortcut) is offered here, never applied. A file built with a codePointTable, which spells the most common letters of a language in one byte each, is read through that table.
Your learned words from HeliBoard or LeanType
Section titled “Your learned words from HeliBoard or LeanType”Those keyboards keep what they learned from your typing in a user history dictionary, in the version 4 format. That format is a folder of two files, NAME.header and NAME.body, so there are two ways in:
- Make a backup in HeliBoard or LeanType and import the
.zip. The app takes out every dictionary in it, one list each, and ignores the layouts, blacklists and images a backup also holds. Each dictionary shows the language code it was written for, so you can leave out the ones for another language. - Or select the
.headerand the.bodytogether in the file picker.
A user history keeps counts rather than frequencies, so a word you typed often there arrives ranked higher, and a pair you typed twelve times weighs twelve times the pair typed once. Words that keyboard had blacklisted do not come across.
Only one shape is refused: revision 402 of version 4, which no current keyboard writes.
See Dictionaries & words for the screen itself.
Gboard’s personal dictionary
Section titled “Gboard’s personal dictionary”In Gboard, open Settings, then Dictionary, then Personal dictionary, and choose Export from the menu. You get a PersonalDictionary.zip. Open it from the row above, from a file manager, or share it to WM Keyboard. The file can also be the dictionary.txt inside the zip, which is the shape community packs of LaTeX symbols and emoji codes ship in.
Each entry in the file is a word, a shortcut for it, or both, and the two go to different places:
- A word with no shortcut goes into your personal dictionary as a word you added by hand, capitals kept. A phrase such as “New York City” comes in as its separate words, the way an entry from Android’s dictionary does.
- A shortcut becomes a snippet in a folder called Gboard, so you can switch the whole set off at once. Gboard never types a shortcut out by itself: it shows the word as a suggestion. The snippet does the same, because each one is set to ask first. A shortcut Gboard maps to several words becomes one snippet that offers all of them.
The dialog counts both halves before anything is written. The locale Gboard saved with each entry is not used, since the personal dictionary here is shared by every language. Picking the same file from the Text expansion import adds the shortcuts only, and says how many words it left for this screen.
Chinese code tables
Section titled “Chinese code tables”FlorisBoard’s other kind of .flex is a language pack: an SQLite database of the shape-based Chinese tables, where a code spells a character by how it looks rather than how it sounds. Those are the same tables this app’s own Cangjie and Stroke packs hold, so a pack you already have fills one without a download.
The rows are written exactly where a download would have put them, so everything else on that screen keeps working on it: the row says Downloaded, the keyboard picks the table up at the next field you tap, and the trash icon removes it.
Three things to know:
- Only Cangjie and stroke land. A pack often holds Wubi, Zhengma, Boshiamy and others as well, and this keyboard has no way to type those, so a table for one would be a large file that changed nothing. The app names the tables it found back to you instead. Cangjie Quick needs no table of its own: it is the same codes queried differently.
- How common each character is survives the import. The pack FlorisBoard ships stores that as a fraction between 0 and 1, in a column its own converter labels as a whole number, so it is read by what the file actually holds rather than by what the column claims. Without that every character imported as equally common, and which one a code offers first is decided by exactly this number.
- A stroke table is rewritten as it is read. Those tables spell the five strokes as the letters
h s p n z; a stored code here is always 1 to 5. Without that translation every row would be dropped for having a code no key can produce.
Pick the wrong .flex and the app says so rather than failing: a theme file is named as a theme, with Themes as the place to take it.
Input methods: .cin, Rime and m17n
Section titled “Input methods: .cin, Rime and m17n”Many input methods are shared as data files rather than as apps: a .cin table for gcin or OpenVanilla, a Rime schema and its dictionaries, an m17n .mim file for ibus. WM Keyboard reads all three and makes each one a keyboard layout of its own. The method’s data is kept with the app, and the layout types through it.
Pick every file the method needs at the same time. The picker takes several files at once, and the app works out which file is which from what is inside them, so the order does not matter.
- A
.cintable is one file. Each code types the entries listed for it, and the suggestion strip offers them as you type, an exact code first and then the codes that start with what you typed. The keys show the caps the table names in%keyname, so a Cangjie table puts 日月金 on the keys and an Array table its 1- 2⇡ positions. Keys the table uses besides letters, such as Array’s, . / ;or Boshiamy’s[ ] ', get a key each. - A Rime schema needs the
.schema.yaml, the.dict.yamlit names, every table that dictionary imports, any shared file its rules come from, such aspinyin.yamlorzhuyin.yaml, and the word list the dictionary ranks by:essay.txtfrom rime-essay, or the file itsvocabulary:line names (essay-cantonese.txtfor rime-cantonese). Without the word list the import still works, but most dictionaries state no counts of their own, so every character ranks the same, and a pinyin dictionary has few phrases: Rime builds them from that list, and so does this app. The confirm dialog names any of these files that were not picked. A schema that converts syllables (Rime’sscript_translator: pinyin, Jyutping, Wugniu, Zhuyin on terra_pinyin) converts whole phrases with the same decoder as the built-in Chinese layouts, prefix commit and learned picks included. A code schema (table_translator: Cangjie 5, Array 30, Wubi 86) works like a.cintable. The schema’s spelling rules (speller/algebra) are applied when you import, so tone-free and abbreviated spellings and the schema’s own keys for Zhuyin work as they do in Rime. A dictionary picked without a schema works too, with no spelling rules. - An m17n
.mimis a program of rules, not a table. The app runs those rules itself, so a key can change the letter before it the way it does in ibus: in Hindi ITRANSkshows क्,kagives क, and a space afterkleaves क. The keys are the ordinary QWERTY keys, with Shift where the method uses capitals, and the corner of each key shows what it will write next. Turn the hints on under WM Keyboard Languages & layouts Hindi Key hints Show the letter each key types (or the same row on your method’s language) to see them. A method thatincludes another needs that file picked too.
The import ends on a confirm dialog that says what was read, how many entries or rules came across, and what was left out. It has a Language row: an m17n file names its language, and for the others the app guesses from the text the table writes (Chinese for Han characters, Cantonese for a table whose name says Jyutping). Set it before you import. The dialog offers Import and Import and turn on.
What does not come across:
- The space bar as a key. Some Zhuyin schemas type the first tone with the space bar. Here the space bar always types a space; leave the tone out, as the schema’s own toneless spellings allow.
- m17n plug-ins. A method that calls a compiled module (Anthy, ispell) or hands keys to another input method keeps the rest of its rules, and those keys do nothing. The confirm dialog says so.
- m17n candidate lists. Where a method offers a list of choices for a key, the first choice is taken.
- Text before the word. An m17n rule can look at, and delete, text you typed earlier in the same word. It cannot reach text from before the word started.
Deleting the layout deletes the method’s data with it, unless a copy of the layout still uses it. An exported layout file names the method but does not carry its data, so on another phone it types its own key caps until you import the method there too.
Themes
Section titled “Themes”A .flex file is FlorisBoard’s theme package. Pick one and the app converts every theme inside it. You can also open a .flex straight from a file manager.
A FlorisBoard extension that holds both a day and a night version becomes one theme with two looks, not two separate entries, and an extension with more themes than that becomes one theme with that many looks. The first look heads the family and the rest become variants of it. The family takes the title the extension declares for itself, or the first look’s own name when it declares none. Auto theme addresses the looks individually, so you can still put the day one in one slot and the night one in the other under WM Keyboard Appearance Keyboard themes Auto theme. The result message says so too: “The app saved name with 2 looks.”
Converted themes are saved but not turned on. They go into your themes list for you to look at first, and the theme editor is where you finish the parts that did not carry over.
How much comes across
Section titled “How much comes across”Open the .flex from a file manager and the dialog puts a number on it: “The app can use 34 of the 52 style rules in this file.” That number counts the rules that changed something the app draws, not the rules it merely recognised. A rule that only sets text wrapping names a part this app has and still changes nothing, so it does not count. That dialog is also where the list below shows up, one line per thing that had nowhere to go.
Colours mostly land. These all have somewhere to go:
- The board, the keys, the pressed key, the enter key, the function keys, borders and per-key colours.
- The key popup and its border, and the corner hint. A theme that styles only the emoji popup gets that bubble for both.
- The toolbar: the tool icons, the circle behind them, the active toggle and the glyph on it.
- The suggestion strip: the suggestion text, the quieter second line, the dividers, the clip chip, and a chip’s selected colours.
- The panel cards, the bottom sheets, the navigation bar band and the glide trail.
- Key and hint text sizes, bold labels, and the corner shape of keys, popups, chips, cards and menus.
- The shape of a single key. A theme that makes only the enter key round keeps it round here.
- Shadows. The lift under the keys, the popup, the panel cards and the toolbar tools. Nearly every bordered theme raises its keys 2 dp, and without this they came across flat. The keys’
shadow-colorcomes across too, as Key shadow colour. - The selected highlight in a popup: the colour behind the letter your finger is on when you hold a key, and behind the selected row of the language list.
- The one-handed rail beside the keyboard, which had no way to differ from the board before.
- The floating keyboard’s handle, which takes the toolbar’s own colours here.
- The panels. A clipboard notice’s heading and body, the buttons inside a panel, the icon buttons on a panel’s header, the rows of the language list, the emoji keys, and the clipboard’s dialogs. None of these is a separate colour here, so each lands on the one the keyboard already draws it with.
- A board background image and a key texture, and how the texture is told to fit its key.
- Keys named the 0.5 way. A newer stylesheet names a key by what it types (
key[output=\@k3:action/enter`]`) rather than by its key code, and FlorisBoard’s own themes write both. A theme written only the newer way used to come across with no enter key colour at all. - A font the theme ships with itself. A
.flexcan carry its own typeface, declared as@font \ndot`and pointed at withfont-family`. Two of the six themes on the FlorisBoard addon store do exactly that, and for one of them the dot-matrix face is the theme. The file is installed as a font add-on of its own, under the name the stylesheet gave it, and the converted theme is set to use it. It then appears in WM Keyboard Appearance Keyboard font like any other installed font, and other themes can use it too.
Colours that follow the wallpaper are read too. A FlorisBoard theme may name a Material You role, such as dynamic-dark-color(surfaceContainerLow), instead of a fixed colour. On Android 12 and later the app resolves those against the same system palette FlorisBoard reads, so a theme written that way arrives with its colours rather than empty. Two of the most-used theme packs are written entirely this way.
On a phone below Android 12 there is no such palette, so those colours resolve against stock Material instead and the dialog says that rather than claiming your wallpaper was read.
And they keep following it. The converted theme remembers which Material You colour each part came from, so when you change your wallpaper the keyboard moves those parts onto the new colours, the same as FlorisBoard does. The theme’s Follow wallpaper colors switch in the theme editor is on after the import; turn it off to keep the colours you have today. A colour you change in the editor stays as you set it. A theme imported before version 0.5.13 has no such record: import it again to get this.
Themes from other keyboards, and FlorisBoard themes written in fixed colours, can follow the wallpaper as well. They start with the switch off, and when you turn it on each colour keeps its lightness and takes your wallpaper’s hue.
FlorisBoard styles a much larger set of keyboard parts than this app draws, so the rest is reported rather than approximated:
- Per-corner radii. Keys here have a single corner size.
- Spacing on single elements. The key gap is set for the whole keyboard.
- A font the theme only names. Some themes name a font family without shipping it. There is nothing to install in that case, so install the font yourself and pick it in the theme editor. A theme that sets
font-family: inherit, which is what both of the big theme packs do on every rule, is asking for no font change at all, so nothing is reported for it. - Text wrapping and alignment. How many lines a label may take, where it is cut and how it is aligned are set by this app, not by the theme.
- The landscape text editor. When a field fills the screen in landscape, Android draws that editor, not this app, so a theme cannot colour it here. The dialog names the parts it could not use rather than saying only that there were some, and for the usual theme packs this editor is most of that list.
If a key’s text colour would be unreadable on what sits behind it, the app drops the imported colour and picks a readable one, and says so. The test is made against what you see: a borderless theme’s keys are transparent, so its labels are judged against the board showing through rather than against the empty key.
HeliBoard and LeanType themes
Section titled “HeliBoard and LeanType themes”Those keyboards have no theme file. A theme is a line of JSON that you copy out of the menu at the top of their colour screen, which is why their theme collections and their whole sharing culture live in forum posts rather than in downloads. So the HeliBoard button asks where the theme is: Paste takes it off the clipboard, Open a file takes a .json somebody saved it into. LeanType is a HeliBoard fork whose colour screen is unchanged, so its themes are the same thing.
Both of that keyboard’s export shapes are read:
- The ten named colours, which is what its few colours and more colours modes export. The board, keys, functional keys, spacebar, key text, hint text, suggestion text, spacebar text, accent and glide trail.
- Every internal colour role, which is what its all colours mode exports: forty-odd values covering the popups, the suggestion strip, the toolbar, the emoji board, the clipboard chips and the navigation bar. This is the richer of the two and is what a carefully built theme is usually in.
A colour that keyboard worked out for itself stays worked out. Its export marks each of the ten as chosen or derived, and a derived one is left unset here so this app derives it in turn. Freezing it in would leave you unable to tell a colour you picked from one that was guessed.
Two colours land on single keys rather than on the board: the spacebar’s own background and label, and the shift key’s icon colour, all of which become per-key styles you can see and change in the theme editor.
The emoji board’s own colours land too. That keyboard’s all colours mode states seven values this app used to read and then drop: the emoji search field’s fill and text, the emoji glyphs, the category tabs, the remove-suggestion icon, the second row of suggestions and the enter key’s long-press sheet. Each of them now reaches the surface this keyboard draws the same thing with.
The result message counts what landed: “The app saved Midnight and used 19 of its 19 colours.” That count is the roles that actually reached a field, not the roles the app recognises. Two of its roles may answer the same question here, and only the first one present is read. Under the count is the same list of what did not come across that the other two imports show: colours the file left for the keyboard to work out, colours stated for parts this keyboard has not got, and text that had to be replaced to stay readable.
A theme is saved rather than switched on, the same as a FlorisBoard one, so you get to look at it first. Day or night is decided from the board colour, since neither shape records it.
Multiling O themes
Section titled “Multiling O themes”Multiling O has no theme file either. A theme is the colours part of its settings export, a block of lines from OK_Settings_Begin to OK_Settings_End, and themes are shared as that block or as a link to a page with the block in it. The Multiling O button asks where yours is: Paste takes the block or the link off the clipboard, Open a file reads a text file you saved it in. A whole settings export works too, and so does opening it from a file manager.
The nineteen colours on Multiling’s Color screen land like this:
| Multiling | Here |
|---|---|
| Background | The board |
| Key1, Text1 | The letter keys and their labels |
| Key2, Text2 | The other keys (punctuation, shift, delete) and enter |
| Highlight | A pressed key |
| Key1 shadow | The key shadow colour, with a small lift |
| Popup, Popup text | The key popup |
| Suggestion bar, Suggestion bar text | The suggestion strip |
| Sub-text1 (or Sub-text2) | The corner hint |
| Space bar, Space bar text | The space bar’s own style |
| Suggestion highlight | The accent |
A colour of 0 is how that screen says “none”, so it stays unset here and this app works it out. The key corner radius, the label size and bold labels come across too. A shadow behind the key labels has no place here, and a wallpaper is only a switch in the text, never the picture; the result message says so when a theme has either.
FUTO Keyboard themes
Section titled “FUTO Keyboard themes”A FUTO theme is a .zip: a settings file and the pictures it names. Pick one with the FUTO button, open it from a file manager, or bring all of them at once with a FUTO backup (see Whole backups). Both of FUTO’s settings files are read: theme.txt, the hand-written format themes are shared in, and config.json, what FUTO’s own theme editor saves.
FUTO paints its keyboard from a handful of its colour roles, and those are the ones that come across:
| FUTO role | Here |
|---|---|
keyboard_surface | The board, and the suggestion strip |
keyboard_container, on_keyboard_container | The letter keys and their labels |
keyboard_container_variant | The other keys (shift, delete, symbols) |
keyboard_container_pressed | A pressed key |
primary, on_primary | The enter key, the accent and the swipe trail |
keyboard_press | The long-press popup |
on_background | The suggestion text |
hintColor (editor themes only) | The corner hint; otherwise the label colour at half strength, as FUTO draws it |
navigationBarColor (editor themes only) | The navigation bar |
The other thirty-odd roles colour FUTO’s own menus and have nothing to fill here. Key borders off becomes the None key shape, labels on the bare board. The key roundness becomes the corner radius (FUTO’s 9 dp a step), and the label size and a heavy label weight come across from a theme.txt. A background picture comes across with its opacity, and a font in the file is installed and used.
What does not come across, and the dialog lists whichever applies:
- Pictures drawn per key, FUTO’s
matchruleskey borders and icons. Those keys are drawn in the theme’s colours instead. - Colours from the wallpaper, written as
system_…. This app works out its own colours for those parts. - An animated background shader.
Like the other converted themes, a FUTO theme is saved but not turned on.
FlorisBoard 0.4 themes
Section titled “FlorisBoard 0.4 themes”Both style formats are read. FlorisBoard renamed several parts in 0.5 (the board went from keyboard to window, the popup from key-popup to key-popup-box), but the colours and the way they are written did not change, so a 0.4 theme converts as well as a 0.5 one. Most themes still in circulation are the older format.
Gboard themes and Rboard packs
Section titled “Gboard themes and Rboard packs”A Gboard theme is a .zip holding a metadata.json, one or more .css style sheets in Gboard’s own dialect, and the pictures they name. It is what Gboard exports and imports, and the format the Rboard community has shared several hundred themes in. An Rboard pack is a ZIP of those ZIPs, with a picture of each theme beside it.
The Gboard button offers two ways in:
- Open a file reads a theme or a pack you already have. A pack lists its themes first: press one to see it, or Add all to save every theme in it as its own entry.
- Browse Rboard opens a list of the packs in the Rboard repository (
GboardThemes/PackRepoBetaon GitHub). The app asks GitHub for the list only when you open that screen, and for a pack only when you press it. Each pack is checked against the SHA-256 the list gives for it before it is opened, and kept in the cache so a second look costs nothing. While Data saver is on, the screen asks before its first request, and the answer covers the packs you open from it. If the Rboard list ever changes shape, the screen says it cannot read it rather than showing a half list; a theme ZIP from anywhere still imports through Open a file. The Google Play build leaves Browse Rboard out, and its Gboard button goes straight to Open a file; the GitHub and F-Droid builds have both.
Either way, each theme ends on a dialog with a preview of it, a count (“The app can use 29 of the 139 style rules in this theme”), and a line for each loss below. Import saves it; nothing is switched on.
Key borders become two looks. Gboard draws a theme with or without key borders by a setting of its own, and a theme ships a separate style sheet for the bordered version. Both come across, as two looks of one theme, the one the theme prefers first. A theme whose border sheet changes nothing this app draws comes across with one look.
What lands:
- The board colour, the bar above the keys, and the navigation bar band.
- The keys, the pressed key, the function keys and the enter key, including the round badge Gboard draws behind the enter icon in a borderless theme. The space bar’s own colour and label become a per-key style.
- Key outlines and their width, the corner size (a large one becomes a pill, and an empty shape means no key face at all), and the lift under the keys with the colour of its shadow.
- Key text, the corner hint, the suggestion text and its dividers, the toolbar icons, the popup and its selected highlight, the glide trail and the accent. The face Gboard draws behind a suggestion becomes a chip colour here.
- The background photo, and a separate landscape photo when the theme has one. A picture on the keys becomes a key texture.
- The theme’s own key glyphs. More than half the themes in the Rboard repository replace the delete, shift and enter pictures with PNGs of their own, and for those themes the glyphs are the theme. They arrive as part of the theme and draw on the keys the moment you wear it: delete, shift in each of its three states, the emoji key, the globe, and enter in each of its wordings. A glyph drawn in a single colour on a transparent background (three quarters of them are) follows your theme’s colour the way a built-in icon does; one with real artwork in it draws as its author painted it. Each glyph is trimmed to what it actually draws and sized like the built-in icons, so a picture cropped tight to its edges no longer comes out bigger than the icon it replaces. See the note on icon packs below.
- How faded a part is. Gboard sets an element’s opacity separately from its colour, and nearly every theme uses it to quiet the function keys’ glyphs. Read without it they came across at full strength, which was the most visible difference between a converted theme and the original.
- Light or dark, from the theme’s own flag.
Gboard styles far more than this app has, so most of a theme’s rules name things with nowhere to go here: GIF and sticker search, the translate bar, Gboard’s access points. Those are counted, not listed. What a person would notice is named on the dialog instead:
- Compiled or missing style sheets. Gboard can compile a sheet to a binary form (
.binarypb) whose format is not published. The readable sheets are used; a theme that is compiled through and through is refused with a message that says so. Gboard’s own stock themes are all of this kind. - A glyph for a key this keyboard has not got. The space bar’s branding and Gboard’s own logo key are the two of these; the rest of a theme’s glyphs now come across. A theme whose glyphs all land is not told anything was dropped.
- The space inside each key. Gboard pads each key separately; here one gap is set for the whole keyboard.
- Fonts. A Gboard theme names a font and never carries the file.
- Corners rounded one at a time, usually the top of the keyboard.
- Pictures on other parts of the keyboard, such as the bar’s tabs.
- Unreadable text. A key, function-key or popup text colour too close to what sits behind it is replaced with a readable one, and the dialog says so. The enter icon and the space bar label are exempt from the line: most community themes draw the first as a picture and hide the second on purpose, so a colour there is often the key’s own and was never meant to be read.
A sheet that breaks the rules is read as far as it goes. A stray ;, a nine-digit colour, a comment that never closes, a variable used before it is defined, a picture named without its extension, and a metadata.json with junk after it all happen in real themes, and none of them stops the import. Eight hex digits are read as Gboard writes them, alpha last (#FFFFFF33 is a faint white).
Theme glyphs and icon packs
Section titled “Theme glyphs and icon packs”A theme’s own key glyphs sit underneath your icon pack and underneath any single icon you picked by hand. That ordering is deliberate: an icon pack is a standing choice about the whole keyboard, and a theme should not quietly undo one. So with no pack installed a Gboard theme’s glyphs show straight away; with a pack installed the pack keeps the slots it fills, and the theme dresses nothing.
They also travel with the theme rather than with the keyboard. Switch theme and the glyphs switch with it; export the theme and they go in the file. This is why importing a twenty-theme Rboard pack gives you twenty themes and not twenty icon packs.
Details & edge cases
Section titled “Details & edge cases”- Almost nothing is decided by the file extension. A file is read and then judged by the format tag inside it. The one exception is this app’s own theme file, which carries no tag, so a
.wmtheme.jsonname is the only evidence a file was meant to be a theme. Tagged formats are checked first, so a layout from another keyboard renamed.wmtheme.jsonis still refused rather than imported as an empty theme. - Opening a
.flexfrom a file manager works because the app registers that extension. If FlorisBoard is installed too, Android asks which app should open it. - A Gboard
.zipopens from a file manager by what is inside it..zipis far too common to claim by name, but the app is offered for ZIP files by type, and one with a Gboardmetadata.jsonor an Rboardpack.metaat its root is recognised. A pack opened that way has no list to pick from, so Import adds every theme in it. - Size caps. A theme or pack is read up to 48 MB inflated, 4 MB per picture, 128 themes per pack; a downloaded Rboard pack is refused past 32 MB. Entry names are only ever looked up, never used as paths.
- A whole backup opens from a file manager by what is inside it. HeliBoard, LeanType, FlorisBoard and CleverKeys backups are
.zipfiles and FUTO’s is a ZIP named.backup. Neither extension is claimed, but a ZIP holding one of their settings files is recognised however it is named. Each part is read up to 32 MB, and a backup is refused past 128 MB of the parts the app keeps; FUTO’s language models are counted and skipped, never read into memory. - Foreign layout files are not auto-detected from a file manager. They carry no marker that identifies them, so they go through WM Keyboard Layout & size Key layouts Import from another keyboard, where you have already said what the file is. This app’s own
.wmlayout.jsonfiles do open from a file manager, because they carry a format tag. - A foreign layout over 4 MB is refused. The whole file is decoded as one string, so there is a cap, and the cap is 4 MB. Past it you get the same “The app cannot read that file as a layout” message an unreadable file gets, with nothing to say the size was the problem. No real grid is anywhere near it, so in practice this only catches a file that is not a layout at all.
- Input method files are capped at 48 MB each and 128 MB together, and a table is cut at 500,000 rows for a
.cinand 1,500,000 across a Rime dictionary and its imports. The confirm dialog says when a table was cut..cinfiles in Big5 or GB18030 are read as well as UTF-8. - Add-on repositories stay native. Repository payloads are always WM Keyboard’s own formats; conversion applies to files you pick yourself.
- Nothing is sent anywhere. Conversion runs on the phone. There is no upload and no server. Browse Rboard is the exception to “no server”: it downloads from GitHub, and sends nothing about you.
Licences
Section titled “Licences”WM Keyboard reads these formats from their published descriptions. No code from either project is used: FlorisBoard is Apache-2.0 and HeliBoard is GPL-3.0, while WM Keyboard is MIT.
The .cin, Rime and m17n readers, and the m17n rule engine, were written from those formats’ documentation and from what their published files do. No code from gcin, OpenVanilla, librime or m17n-lib is used, and no table or rule file ships with the app. A table you import keeps its own licence: many .cin and Rime tables are free to share, and some, such as Boshiamy’s, are for personal use only.
Gboard’s theme format has no published description, so its reader was written from the themes in the Rboard repository rather than from any Gboard or Rboard code. Rboard themes state no licence. A theme you import stays the work of whoever made it, and a pack’s author is named on the dialog; ask before you publish one.
A .flex records its author and its licence, and the confirm dialog reads both out when you open one from a file manager. A theme here has no field to hold them in, so that dialog is where they stop. Write them down while they are in front of you. If you publish a converted theme in an add-on repository, keep them with it.
