Skip to content

About

Fix text typed in the wrong keyboard layout on macOS — `ghbdtn` → `привет` with a hotkey. Punto Switcher alternative, works with any installed language pair.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

Bilingual Switcher

CI Download Platform License

Fix text typed in the wrong keyboard layout — for any two keyboard layouts
installed on your Mac, not just English and Russian.


Ever type a whole sentence only to realize your keyboard was in the wrong language?

Ghbdtn vbh! instead of Привет мир! — or Руддщ Цщкдв! instead of Hello World!

Select the text, press ⌥⌘S, and it's fixed in place.

The app reads the character map of every layout macOS has installed, so it works for pairs that hardcoded English↔Russian tools can't reach: Greek, Hebrew, Armenian, Georgian — and same-script pairs like QWERTY↔AZERTY or QWERTY↔QWERTZ.

Русский: Bilingual Switcher исправляет текст, набранный не в той раскладке: выделил, нажал хоткей — готово (ghbdtn → привет). Работает с любой парой раскладок, установленных в системе, а не только с русской и английской. Установка через Homebrew или DMG — см. раздел Install.

Demo: typing in the wrong layout in Slack, then fixing it with one hotkey

Features

  • Any pair of keyboard layouts — reads them through the macOS UCKeyTranslate API at runtime. No hardcoded mappings, no built-in language list (layouts, not CJK input methods — what that means)
  • Never watches you type — no event tap, no keystroke buffer. macOS wakes the app on your hotkey and at no other moment
  • Deterministic — converts exactly what you selected, key by key, from the system's own layout tables. No word lists, no language model, no guessing
  • Nothing happens on its own — it fires when you press the hotkey. Your text is never rewritten while you type
  • Works everywhere — GUI apps, terminals (iTerm, Terminal.app, Claude Code), text editors
  • Configurable hotkey — any key combination, or a modifier-only tap like ⌥⌘ (default: ⌥⌘S)
  • Auto-switch keyboard layout — optionally switch to the target language after conversion
  • Launch at Login — start automatically with macOS
  • Auto-updates — built-in update checking via Sparkle
  • Small enough to read — native Swift, no Electron, no bundled runtime or downloaded models

What it doesn't do

These are design choices, and they are the reason the app is worth trusting with an Accessibility grant:

  • No keylogger. The app installs no CGEventTap. In the default mode it registers your shortcut with the system, which then delivers that one combination and nothing else. If you bind a modifier-only combo, the app adds a single passive monitor that can see key events — it reads only that a key was pressed, to cancel the gesture, never which key (ModifierOnlyHotkeyMonitor.swift).
  • No Input Monitoring permission. That grant exists to gate event taps. The app doesn't use one, so macOS never asks.
  • No dictionaries, no autocorrect. Nothing is guessed from your vocabulary, so code, transliteration, brand names and mixed technical text convert as reliably as prose.
  • No telemetry. No analytics, no crash reporting, no accounts. The only network access is the optional Sparkle update check.

Your clipboard is used: the app copies the selection with ⌘C, then puts the clipboard back exactly as it was — every item, every data type, in the original order. See How it works.

Verifying the above is meant to be practical rather than aspirational: the source is small enough to read end to end, and every commit runs the test suite in CI — plus the same suite again under AddressSanitizer, and a static analysis pass.

Supported layouts

A keyboard layout is the kind of input source where one physical key produces one character. The app converts between any two of them you have installed, in either direction — that is what "any two" above means, and it covers most of the world's languages.

Tested: English, Russian, Ukrainian, French, German, Spanish, Portuguese, Italian

Same-script pairs work too: QWERTY↔AZERTY, QWERTY↔QWERTZ, Dvorak, Colemak — the app compares layouts, not alphabets

Should work (same mechanism): Greek, Hebrew, Armenian, Georgian, Polish, Czech, Turkish, Swedish, Norwegian, Danish, Dutch, Romanian, Hungarian, and any other standard keyboard layout

Input methods are a different thing, and out of scope. Chinese, Japanese and Korean don't map a key to a character — you type a sequence and choose from candidates. Text typed with the wrong one isn't mis-mapped characters that can be translated back; recovering it means re-running the composing engine. That is a different problem, and this app does not solve it.

Install

Homebrew (recommended)

brew tap komandakycto/bilingual-switcher https://github.com/komandakycto/bilingual-switcher.git
brew install --cask bilingual-switcher

Homebrew strips the macOS quarantine flag for you, so the app opens without Gatekeeper prompts — and brew upgrade keeps it current.

Manual download

Download the latest .dmg from Releases, open it, and drag the app to Applications.

Gatekeeper notice: releases are signed with a stable identity but are not notarized with Apple, so Gatekeeper blocks the first launch. Before opening:

xattr -cr /Applications/BilingualSwitcher.app

Or: try to open the app, get blocked, then go to System Settings → Privacy & Security → scroll down → Open Anyway.

You can verify the download integrity with SHA256 checksums from the release page.

Build from source

Requires Xcode Command Line Tools (xcode-select --install).

git clone https://github.com/komandakycto/bilingual-switcher.git
cd bilingual-switcher
make setup     # downloads Sparkle framework
make
make install   # copies to /Applications

Usage

  1. Launch the app — it appears as an icon in the menu bar
  2. Grant Accessibility permission when asked — System Settings → Privacy & Security → Accessibility (required to read/replace selected text). The app picks it up as soon as you turn it on; no restart needed.
  3. Select the wrongly-typed text in any app
  4. Press the hotkey (default: ⌥⌘S — Option + Command + S)
  5. The text is converted in place

Selecting text inside terminal TUIs (Claude Code, vim, htop, lazygit): full-screen terminal apps capture the mouse, so a plain click-drag is sent to the app instead of creating a selection — leaving nothing for the hotkey to copy. Hold Shift while dragging in kitty, or Option in iTerm2, to force a real terminal selection (other terminals have a similar modifier to bypass mouse reporting), then press the hotkey. If you press the hotkey with nothing selected, the app beeps.

Changing the hotkey

Menu bar icon → Preferences → click the shortcut field → press your desired combination → Save.

You can also bind a modifier-only combo like ⌥⌘ — press and release the modifiers together with no other key. Two or more modifiers are required, and it fires only on a clean release, so ⌥⌘C and other real shortcuts still work as usual.

Examples

You typed You get
Ghbdtn vbh! Привет мир!
Руддщ Цщкдв! Hello World!
Dctv ghbdtn Всем привет
Рфззн Ишкесфн Happy Birthday

How it works

The app uses the macOS UCKeyTranslate API to read the character map of every keyboard layout installed on your system. When triggered:

  1. Copies the selected text (simulates ⌘C)
  2. Scores the text against each installed layout to detect which one produced it
  3. Converts each character via physical key codes: source layout char → key code → target layout char
  4. Deletes the original and pastes the result
  5. Restores your original clipboard — every item and data type, in the order it had

With 3+ layouts installed, the app tracks the two you most recently switched between and converts within that pair.

Requirements

  • macOS 13.0 (Ventura) or later
  • Accessibility permission (the app asks on first launch)

Upgrading from 1.2.0 or earlier

Those builds were ad-hoc signed, so macOS tied your Accessibility grant to that exact binary. Updating past them invalidates it: the app still shows in System Settings → Privacy & Security → Accessibility with the toggle on, but macOS no longer honours it. Toggling it off and on does not help.

Remove Bilingual Switcher from that list with −, then add it back with +. The app offers to do this for you when it detects the situation. This is a one-time step — releases are now signed with a stable identity, so the permission survives future updates.

Contributing

See CONTRIBUTING.md for build instructions and guidelines.

License

MIT

About

Fix text typed in the wrong keyboard layout on macOS — `ghbdtn` → `привет` with a hotkey. Punto Switcher alternative, works with any installed language pair.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages