github DevEmperor/DictateKeyboard v6.3.0
Dictate 6.3.0

4 hours ago

Dictate 6.3.0 is a release about reaching more of the keyboard without leaving it. It can read printed text off a photo — an IBAN, a serial number, the Wi-Fi password on the back of a router — and it does that without ever asking for the camera permission. The cursor, the selection and the clipboard finally share one editing panel instead of eleven keys you had to know about, the number pad can be asked for by name, and any Smartbar button can carry a second action under a long press, paired by you rather than by us. The floating button gets a hold menu and a list of the apps it is welcome in. Offline dictation gets models that actually fit on a phone, forty more Eastern languages, and a picker that is ten rows instead of twenty-four. Updating shows a new What's-new tour for 6.3, eight pages with live artwork; every tour stays re-viewable under Settings › About.

📷 Scan text (#390)

  • Point the camera at printed text and it lands in the field you were typing in. An IBAN off a letter, a serial number off a box, an address off a parcel — the cases where retyping is the whole cost. Every recognised line comes back as a tappable region: take the ones you want, approve, done.
  • No new permission, and that is the design rather than a happy accident. An app that does not declare CAMERA may still fire ACTION_IMAGE_CAPTURE — the system camera takes the picture and hands back the file. Declaring the permission would have broken that route, not enabled it.
  • Recognition happens on the device. Nothing is uploaded, no provider is involved, and the photo is deleted as soon as it has been read.

✍️ The editing panel and the number pad (#386, #388)

  • Every piece of this already existed and none of it was together: the arrows and the clipboard actions as Smartbar slots you had to spend, the precise selection and the cursor walks as gestures you had to bind and then remember. The audit in #382 checked eleven keyboards; this was the one feature all of them had and we did not — not because the work was missing, but because there was no surface.
  • So this adds a surface and nothing else. Every key on the panel sends a key code the keyboard has handled for years, which is what buys hold-to-repeat for free instead of asking for eleven taps.
  • The number pad has been finished for a long time and had no way to ask for it. A numeric field decided for you, the keyboard-mode cycle had to be bound to a gesture by hand, and the one real key was a 2×2 digit block on the symbol layer that only people who already knew it was there ever found.

👆 A second action under a long press (#385)

  • Pair a second action to a Smartbar button yourself, and holding it runs that one. Only about five buttons are visible before the overflow, so this is the difference between having a feature and having room for it.
  • The pairing is yours, not a table we ship. #382 proposed a fixed list of obvious pairs; that works for a keyboard whose toolbar is fixed, and ours is arranged by the user — a curated pair would be a guess about ten of thirty-odd actions, and would serve someone who has cut visible and copy hidden exactly not at all. A pairing you set yourself also needs no explaining.
  • A small badge marks the buttons that carry one, sized against the icon it sits on.

🫧 The floating button (#408, #392, #399)

  • Hold it for a short menu, starting with transcribing an audio file — the thing that already happens when a voice note is shared to Dictate. No gesture is remapped: the button is draggable, so hold-and-drag already means two things, and a double tap cannot exist on a control where a quick start-then-stop is one.
  • Tell it which apps it is welcome in. It used to appear over anything with a text field, which is two problems in one: banking and payment apps object to anything drawn on top of them, and apps with a microphone of their own were handed a second one for nothing. Three modes over one shared list — everywhere, only these, everywhere except these.
  • Stop stays exactly where start was (#399). The tap target never actually moved — the pill toggles and the edge it grew from stays under the finger — but the glyph walked off with the pill, so the hand and the eye had to meet somewhere else. Now the glyph is read from the side the button is on.
  • The pill opens smoothly on either wall. A frame-by-frame recording showed the window manager moving the window every frame while the app's buffer for that width arrived only every 7–13 frames; on a stale buffer the whole pill slid inwards and then jumped back out. Two windows now, one of which never changes size.

🔌 Offline dictation (#406)

  • English, German and Russian in sizes that fit a phone, instead of only the 670 MB ones. The catalog had a shape problem rather than a gap — English existed only through Whisper, German only as a 670 MB fine-tune, Russian only without punctuation — so every language with a specialised model had to pay for it in storage, and the wizard kept recommending the general one.
  • Dolphin closes everything east of Europe, about forty languages the catalog could previously only reach through Whisper. The measurement was not close: given natural Hindi, the Whisper Base most people install answers in Urdu script and stops halfway, while Dolphin returns correct Devanagari with the punctuation in place.
  • Fun-ASR-Nano was measured against it and rejected, and Snapdragon NPU support was closed as wontfix (#404) — QNN would mean going back to older models and a fixed input window, which is a step backwards wearing the word "faster".
  • The picker is ten rows instead of twenty-four. Sixteen of the twenty-four models were not twenty-four decisions; they were Whisper in six sizes and Kroko in ten languages, and listing them flat made the provider editor four screens of scrolling. The order is by what most people will actually download, not by architecture, and the details sit behind an ⓘ.
  • Each model is cut at the length it actually handles, not at Whisper's. Everything was segmented at 28 seconds because that is Whisper's ceiling; it was wrong in both directions for everyone else.

🎨 High contrast that is a number, not a name (#387)

  • Two themes carried "(High Contrast)" in their label for a year without anyone measuring them. They were the E-Ink ones, monochrome because an e-ink panel smears when it redraws colour — a display problem, not a vision one. Someone who needs a readable keyboard had no reason to open an entry that says E-Ink.
  • dictate_contrast and dictate_contrast_night are new, and the numbers are the feature: every label is measured against its own background rather than named after an intention.

🗂️ Your own vocabulary as a file (#389, #129)

  • Custom words had exactly one way in: typing them one at a time into a dialog. Anyone with a real vocabulary — patient names, part numbers, a team's jargon — was stuck, and this is the list every dictation rides on, since it is appended to the transcription prompt on every single request.
  • There is now an importer (merge, never replace) and an exporter, and the same pair for the find-and-replace rules. Importing and exporting live inside the word list, where the list is.
  • What the list costs is said out loud, in one line, where the list is — because that prompt has a hard ceiling and a vocabulary that overruns it silently stops working.

🌍 Data residency (#403)

  • A provider account can choose the region its data stays in, and the streaming host moves with it. Soniox sets residency per project and a regional project mints its own key, valid inside that region only — so a perfectly good EU key entered against a hard-pinned api.soniox.com came back as an invalid key, with no way around it.

🎙️ Dictation and providers

  • The recording bar can draw a waveform (#371), so it answers the question people hold a thumb over the stop button for: has it gone quiet yet. The dot only ever showed the current instant; a scrolling history is the only shape that shows silence, which is why silence is drawn as flat dots rather than as a gap — a gap reads as a broken indicator.
  • The provider's own key page is one tap from the field where the key goes (#410). Someone picked OpenAI, left the field empty, tapped Test connection, got OpenAI's verbatim "Missing bearer authentication in header", read it as a broken app and asked for a refund. Nothing was broken — the dialog simply never said a key has to be fetched first.
  • Test connection can fail again (#384). It called listModels() and treated any number it got back as a pass — but for Azure, ElevenLabs and AssemblyAI that list is compiled into the app, so the test could not fail: not with a wrong key, not with a hostname that does not resolve, not in airplane mode. It now makes an authenticated request per provider.
  • OpenRouter's transcribeStyle: "clean" was built and then taken back out (#400). Building it was easy; measuring it ended the feature. On the same recording the option changed nothing on either route, and shipping a switch that does nothing is worse than not having it.

🧭 Finding things

  • A fresh install opens on what this keyboard is for (#402). The default Smartbar arrangement had grown by appending each action as it shipped, so it read as a changelog: text editing, select all, undo, redo, cut and copy were what a new user met, and the transcription history — the second half of what this keyboard does — sat at position 32 of 34.
  • The classic layout's action buttons wrap onto a second row (#226) instead of making people give up features to fit. Ten buttons against twenty available actions meant choosing which ones to do without, and that ceiling had already been raised once.
  • Providers and transcription languages sit above the dictation layout in the settings hub. Provider and language are what you set once and return to when something is wrong; the layout is a matter of taste most people never open, and it had top billing only for having arrived as its own category.

🔧 Fixed

  • A dictation survives the microphone it was recording from going away (#411). The microphone was asked for exactly once, and the audio service hands it over rather than sharing it — so for a few hundred milliseconds after anything else let go, the recorder came back uninitialised as a red "recording failed". A route that dies mid-dictation is now handled too; both were found by reading the code, and both were measured on an A55 before and after.
  • Keyboard actions no longer die silently on a dead surface (#409). The output target was latched by every start and never reset, so after a single floating-button or system-voice-input dictation, every later keyboard action aimed at a surface that was already gone. Every action now names the field it writes to, and the voice-input view has a way out of a failure.
  • The space a picked suggestion promises is written straight away (#393). Nothing about the resulting text was ever wrong, but the decision was invisible: pick a word off the strip and the cursor sat against its last letter, while every mainstream keyboard shows it one space further on.
  • A silent recording no longer comes back as invented Croatian (#407), and a red error is told apart from a white one.
  • The floating button's × has a round shadow instead of a square of one.

Distribution: Dictate ships through Google Play. This release has no APK attached on purpose — see the README for why, and for how to build it yourself from source.

Don't miss a new DictateKeyboard release

NewReleases is sending notifications on new releases.