Boppo — fixing wrong input language on macOS, before you even notice

August 11, 2026 (1d ago)

Boppo — wrong input language, repaired in place

There is a very specific moment almost every bilingual Mac user knows well.

You start typing before noticing the input language is wrong. By the time your brain catches up, an entire half-line of Zhuyin has landed in an English document — or vice versa. You stop, sigh, delete the whole thing, switch the input source, and retype it.

I built Boppo so that moment stops happening.

Boppo is a tiny macOS menu-bar app. It watches for the physical pattern that means "I just started typing under the wrong input source" and, if it is safe to do so, replaces the wrong-language characters with the right ones — in place, before you even notice the mistake.

What it actually does

The narrow problem Boppo solves is: detect the switch-and-type transition on the wrong input language, and rewrite the affected chunk in place when the rewrite is unambiguous.

It does not try to translate anything. It does not touch your clipboard. It does not learn from your typing. It does not even know what you typed in the long run — the detection buffer is short, the repair happens within the same physical gesture, and the original characters are not logged anywhere.

When the situation is ambiguous — say the typed characters happen to be valid in both languages, or the surrounding context could mean two different things — Boppo does nothing. It would rather miss one repair than delete one real character.

That "fail closed" decision is the whole product in one sentence.

Why a menu-bar app, and why macOS-native

The simplest version of this idea could have been a Swift script, an osascript, or a small Apple Shortcut. I tried those first. They all hit one of the same walls:

  • Shortcuts and AppleScript can read the keyboard, but they cannot reliably inject a corrective backspace-and-replace at the right time without breaking focus on the active app
  • A pure CLI tool cannot read keyboard events at all on macOS without elevated privileges
  • A browser extension only sees browser text

Boppo sits one layer below the OS, in the same place Spotlight lives, and uses the public accessibility APIs every menu-bar utility uses. That is the only level where the app can:

  1. Tap the physical key stream in a way the user never has to grant permission for twice
  2. Read enough surrounding text to disambiguate the repair
  3. Inject the corrected characters back into the same app's focused field

Stack

Boppo is my first macOS-native app — a separate ship from the sz.ws catalogue — so a few choices got made deliberately:

  • Swift 5 + SwiftUI for UI, with AppKit where SwiftUI is still too high-level (status bar item, menu construction)
  • CGEvent tap for the keyboard stream — the standard system-wide hook, scoped to the active app's focused field
  • Accessibility API to read the focused text context just deep enough to confirm a repair is safe
  • XcodeGen so the project file is a plain YAML that humans can read
  • macOS 14+ minimum — older macOS versions are missing the keyboard / accessibility hooks Boppo relies on

The interesting build problem was that the detection buffer has to be tight. If it is too long, Boppo will repair things you did not intend to repair. If it is too short, it misses the moment entirely. The current buffer sits in the few-physical-keystrokes range, and the entire repair happens inside that window — so even in the worst case, there is at most one line of text in memory at a time.

What I am not claiming

This is not a general-purpose input method editor. It does not add new keyboard layouts, it does not fight the IME, and it does not change what you typed on purpose.

It is also not a keylogger. The detection buffer is short, scoped to the moment of switch-and-type, and never leaves the device. The only network traffic Boppo ever makes is the Sparkle update check and the license activation against the sz.ws billing API.

You can read the full detection logic in the Boppo website FAQ — I am deliberately writing it down in plain language because the whole point of the product is that you can trust it.

A quick look at the website

The marketing site at boppo.suko.tw is the same architecture as the other sites I run — a small Cloudflare Worker, minimal JS, real screenshots, no "live" badges I cannot back up.

Here is the demo loop from the site, which is the closest thing to a screencast I will record:

0:00/0:00

If you have ever lost five minutes of a sentence to the wrong input source, that video is going to feel familiar in a way I cannot quite put into words.

Why I built it as a paid product

Honestly? I built Boppo for myself first.

The wrong-input-language moment is one I hit almost daily, and after cycling through the usual workarounds — delete-and-retype, mental checkpoints, switching layouts preemptively — I wanted the thing to just not happen. Boppo is what that looks like as a finished product.

It is also a product I can put a price tag on, which is not a big deal either way. Five US dollars is a coffee. The point is to make it easy for anyone who has the same problem to grab a copy without me having to run ads, collect telemetry, or charge a subscription. One-time purchase, one-time build, runs forever.

If you happen to use it daily, the licence pays for the next weekend I spend maintaining it.

Where it sits in the catalogue

Boppo sits outside the sz.ws umbrella — it is its own thing, on boppo.suko.tw, with its own licence and its own download. The sz.ws catalogue is where my web and CLI projects live; Boppo is the first one that left the browser.

If you want to see the sz.ws side of things — an extensible CMS, drop (ephemeral static hosting), Across (real-time voice translation), Cenotaph (browser extension, pre-alpha), Foldio (custom macOS folder icons), and the npx sz.ws CLI calling card — they are all linked from the catalogue page.

Try it

If you want to give Boppo a try, the download is on boppo.suko.tw. It is signed and notarised, the install is the normal drag-to-Applications flow, and there is a short demo video on the front page that shows the repair happening live.

If the wrong-input-language moment is one you have, you should be able to tell within the first sentence whether Boppo is the kind of tool you will leave running.