Skip to content

Offer the letter keyboards in alphabetical order - #10

Merged
oroderico merged 1 commit into
mainfrom
keyboard-layout-setting
Aug 15, 2026
Merged

oroderico merged 1 commit into
mainfrom
keyboard-layout-setting

Conversation

@oroderico

Copy link
Copy Markdown
Owner

Closes #9.

Summary

QWERTY is a poor default for someone who does not touch-type: on a ring of keys walked with two buttons, a scattered alphabet means hunting for every letter. Settings now chooses, beside Flip Orientation and Brightness — Keyboard: QWERTY or Keyboard: ABC.

The layouts were already strings, and seedtool_app.c already said why: every key is found by its character rather than by where it sits. Nothing depends on position — the cursor walks a flat ring, the renderer centres each row from the string itself, and layout_key_index searches by character. The alphabetical word layout is 10/9/8 like the QWERTY one, so it fits the three rows the keyboard is drawn in without the renderer knowing them apart.

Covers the word keyboard and the passphrase letter pages. The number keyboard has no alphabetical form. The passphrase digit and symbol pages are shared between the two arrays rather than duplicated — punctuation has no alphabetical order, and a second copy would be a second place for a character to go missing.

It cannot change mid-session

Settings is reachable only from the Origo menu, and the wallet has no row that returns there, so no session can have half a passphrase typed on one arrangement and half on the other. The presses would spell the same string anyway — keys are found by character — but the menu tree makes that structural rather than something the reader has to be careful about.

The checks matter more than the feature

A layout typed out by hand is exactly where a missing letter comes from, and a missing letter makes some BIP39 words impossible to enter: the reader reaches for a key that is not there and has no way to finish a restore.

  • layouts_are_complete now takes a layout rather than naming one, and runs over both word arrangements and both passphrase arrays. Each array is checked for full printable-ASCII coverage on its own, not pooled — a character present in only one arrangement is as unusable as a missing one for whoever picked the other.
  • The Python source-parse test does the same from the source text, and a new test pins both word layouts to exactly the 26 letters.
  • Both were proved by deleting the s from the alphabetical layouts and confirming the self-test and two Python tests fail, naming the letter.

Size

+336 bytes, taking the image to 99.6% of the ceiling with 1184 free. More than the ~63 bytes the strings alone suggested — the rest is the second passphrase array, the two accessors and the extra Settings row. Flagging it rather than burying it: the ceiling is close enough that the next change of any size needs the budget looked at first.

Verified

  • Host self-test, 50 Python tests, sanitized build.
  • Firmware build against the pinned IDF 5.5.4, ELF audit passing at 300896 bytes.
  • Hardware: flashed and walked after merge.

QWERTY is a poor default for someone who does not touch-type: on a ring of
keys walked with two buttons, a scattered alphabet means hunting for every
letter. Settings now chooses, beside Flip Orientation and Brightness -
"Keyboard: QWERTY" or "Keyboard: ABC".

The layouts were already strings, and seedtool_app.c already said why: every
key is found by its character rather than by where it sits, so an arrangement
is just a different string. Nothing depends on position - the cursor walks a
flat ring, the renderer centres each row from the string itself, and
layout_key_index searches by character. The alphabetical word layout is 10/9/8
like the QWERTY one, so it fits the three rows the keyboard is drawn in without
the renderer knowing them apart.

Covers the word keyboard and the passphrase letter pages. The number keyboard
has no alphabetical form. The passphrase digit and symbol pages are shared
between the two arrays rather than duplicated: punctuation has no alphabetical
order, and a second copy would be a second place for a character to go missing.

It cannot change mid-session. Settings is reachable only from the Origo menu
and the wallet has no row that returns there, so no session can have half a
passphrase typed on one arrangement and half on the other. The presses would
spell the same string anyway - keys are found by character - but the menu tree
makes that structural rather than something the reader has to be careful about.

The checks matter more than the feature here, because a layout typed out by
hand is exactly where a missing letter comes from, and a missing letter makes
some BIP39 words impossible to enter - a reader would reach for a key that is
not there and have no way to finish a restore.

- layouts_are_complete now takes a layout rather than naming one, and runs over
  both word arrangements and both passphrase arrays. Each array is checked for
  full printable-ASCII coverage on its own, not pooled: a character present in
  only one arrangement is as unusable as a missing one for whoever picked the
  other.
- The Python source-parse test does the same from the source text, and a new
  one pins both word layouts to exactly the 26 letters.
- Both were proved by deleting the "s" from the alphabetical layouts and
  confirming the self-test and two Python tests fail, naming the letter.

Costs 336 bytes, which takes the image to 99.6% of its ceiling with 1184 free -
more than the 63 bytes the strings alone suggested, the rest being the second
passphrase array, the two accessors and the extra row. The ceiling is close
enough now that this is worth saying out loud rather than noting in passing.

Verified with the host self-test, 50 Python tests, and a firmware build the
audit passes at 300896 bytes. Not yet walked on hardware.
@oroderico
oroderico merged commit 2167f9d into main Aug 15, 2026
3 checks passed
@oroderico
oroderico deleted the keyboard-layout-setting branch August 15, 2026 19:41
oroderico added a commit that referenced this pull request Aug 15, 2026
@oroderico

Copy link
Copy Markdown
Owner Author

Reverted in 99c2dad — not wanted yet. Diff stays here if it is picked up later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant