Skip to content

ADFA-4057 | Add Custom Keyboard template bundle - #144

Open
jimturner-adfa wants to merge 2 commits into
mainfrom
feature/ADFA-4057-custom-keyboard
Open

jimturner-adfa wants to merge 2 commits into
mainfrom
feature/ADFA-4057-custom-keyboard

Conversation

@jimturner-adfa

@jimturner-adfa jimturner-adfa commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

ADFA-4057

Adds templates/Custom-Keyboard, a template that creates an Android keyboard for a language the shipped keyboards do not cover. Kotlin only. Each language is a JSON layout file; adding one needs no code. Ships English (QWERTY) and Hindi (Devanagari).

Review by commit

  1. 7b54453 - verbatim copy of EmptyActivity from core.cgt. Skim.
  2. 45a710b - the keyboard: KeyboardService, KeyboardView, KeyboardLayout, the setup MainActivity, method.xml, layouts, gallery files.

Design choices

  • Written from scratch. FUTO and HeliBoard informed the UX only. HeliBoard is GPL-3.0, which would carry into every generated app, and needs native dictionary libraries (so the NDK). FUTO's licence is not open source. Nothing from Sriboard was inspected or reused.
  • Custom key view, not android.inputmethodservice.KeyboardView (deprecated since API 29). View-based, not Compose: Compose in an InputMethodService needs hand-wired lifecycle owners.
  • Layouts are data. A key commits a string, so conjuncts (क्ष = 3 code points) and nukta forms need no code. Rejected: Pebble parameters for key rows (one text field cannot express a layout) and hard-coded Kotlin keys (every language becomes a code change).
  • Kotlin only. No optional.language, so app/build.gradle.kts drops the ${% if LANGUAGE == 'kotlin' %} wrapper: the strict renderer fails on an undeclared variable.
  • Out of scope: prediction, dictionaries, swipe typing, direct boot (noted in the README).

Testing

Pixel 6 Pro (arm64, API 37), Code on the Go C-d-1014-1359:

  • Installed the .cgt via Add-ons Manager; New Project shows the template with no language chooser. Generated com.example.my_keyboard, built on device (~50 s), installed, ran.
  • Setup flow as a user: "Open keyboard settings" opens the system list, the privacy and direct-boot dialogs appear, "Choose keyboard" opens the picker, the status line moves Not turned on -> Turned on -> Ready.
  • Typing, checked by code point in the field: sentence auto-caps and one-shot shift, caps lock on double-tap, backspace, long-press alternatives (é, ö), symbols, Enter newline in a multi-line field, Search action label and submit in Settings search, नमस्ते, the क्ष conjunct key, nukta via long-press (क़ = U+0915 U+093C), danda.
  • Every key is exposed to TalkBack with a description (via uiautomator; no live TalkBack session).
  • Font scale 1.0 and 2.0, light and dark: keys grow with the font, stay above the navigation bar, the setup screen scrolls and keeps the try-it field above the keyboard.
  • Host: renders and builds debug and release offline; addons check passes.

Fixed during device testing: keys behind the navigation bar on edge-to-edge (Android 15+) keyboards; the try-it field hidden by the keyboard; no capital after Enter; long-press hints covering labels at 2x; popup selection not matching the finger until it moved.

Not tested: a live TalkBack session, API levels below 37.

🤖 Generated with Claude Code

yaturner and others added 2 commits October 19, 2026 09:56
…emplate

Verbatim copy of EmptyActivity from core.cgt, no changes. The next commit
turns it into the keyboard template, so its diff shows only what it adds.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
A Kotlin project template for an Android keyboard in a language the
shipped keyboards do not cover. Written from scratch; FUTO and HeliBoard
informed the UX only (HeliBoard is GPL-3.0 and needs native dictionaries).

- KeyboardService: an InputMethodService that commits text, handles
  one-shot shift and caps lock, symbols, enter actions, sentence
  auto-capitalisation, and code-point-wise delete.
- KeyboardView: custom-drawn keys (the platform KeyboardView is deprecated
  since API 29) with long-press alternatives, backspace repeat, rollover,
  TalkBack via ExploreByTouchHelper, sp-sized labels, and room for the
  navigation bar on edge-to-edge keyboards.
- Layouts are JSON in assets/layouts; a key may output several code
  points. Ships English (QWERTY) and Hindi (Devanagari).
- MainActivity: setup screen to enable and choose the keyboard, and try it.

The template offers no language choice, so the Kotlin block in
app/build.gradle.kts loses its LANGUAGE conditional: the renderer fails
on an undeclared variable.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
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.

2 participants