Skip to content

FEATURE: Instant recording: only start after the user switches to Dictate, not on every field focus #224

Description

@george1612

Hi again, and thanks for Dictate - I use it every day.

This one is a follow-up to an older request. I'd asked whether "Instant recording" could start only when I deliberately switch to Dictate from another keyboard, rather than firing on every text-field focus while Dictate is my default IME. Your answer at the time was that the Android keyboard API doesn't let you tell how the keyboard was opened - so there's no reliable signal for "the user just switched to me" - and I think that's completely right as stated.

I've since been running a workaround in a personal fork that sidesteps that exact problem, and it's turned out to work really well in practice, so I wanted to share the idea in case it's useful upstream.

The problem

As a default keyboard, "Instant recording" means every tap into any text field immediately starts recording. For the "quickly dictate one thing, then switch back" workflow that's too aggressive - most field focuses aren't a dictation intent. What I actually want is: recording auto-starts only when I actively came to Dictate from another keyboard.

The idea (why it dodges the "can't detect how the keyboard opened" limitation)

Instead of trying to detect the open event (which the API doesn't expose), I detect the switch-away on our own side, where we do have a signal, and let the next open consume it:

  1. Every deliberate keyboard switch goes through our own switch actions (switchToPreviousInputMethod / switchToNextInputMethod in the IME service). When one of those succeeds, I set a small persisted "armed" flag. In other words: I don't ask "how was I opened?", I remember "the user just used my switch key to leave."
  2. The next time the input view opens, if that flag is set, it counts as a switch-in -> instant recording fires, and the flag is consumed. A plain field focus (no preceding switch) never has the flag set, so it does nothing.
  3. The flag is persisted, because the process can be torn down when you switch away and rebuilt when you come back - an in-memory boolean would be lost across that.
  4. Fail-safe direction: on a fresh install / reboot the flag is unset, so the worst case is a missed auto-start (harmless), never a surprising one. I also only consume the flag when the dictation controller is idle, and every idle open clears a stale flag, so it can't "fire late" much later.

Known limitation I accept: if you leave Dictate via the system IME picker instead of our switch key, the return isn't recognized (we never saw the switch-away). That's rarer, and it's a deliberate trade for a race-free gate that never fires unexpectedly. Upstream might prefer to offer this as an option (Instant recording: "always" vs. "only after switching to Dictate") rather than a behavior change - the gate logic is identical either way, it just adds one pref check.

Caveat / offer

I prototyped this with heavy AI assistance, so please treat it as a direction rather than a production-ready patch - it's probably not as robust as you'd write it yourself, and the edge-case handling (persistence, idle-gating, stale-flag cleanup) is where the subtlety lives. If you're curious, I'm very happy to invite you to the fork so you can see the actual code and tests. Happy to test any build too. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions