Ultra-light, Mac-only Vietnamese input for macOS.
SangKey is a native Vietnamese input method designed so the process that handles keystrokes 24/7 stays as small as practical:
- Headless
SangKeyAgent. The always-on input process does not link AppKit, ServiceManagement, Swift, SwiftUI or Combine. - Ephemeral control app.
SangKey.appuses AppKit + ServiceManagement only while you are changing settings or managing the background agent; you can close it and typing continues. - C++14 typing engine with Telex, VNI and Simple Telex.
- Objective-C++
CGEventTapfor low-latency system-wide input. - No XPC service, daemon, telemetry or background network client. The helper
is a user-session LaunchAgent bundled inside the app and registered with Apple's
SMAppServiceAPI. - No embedded auto-updater. Update checks only open GitHub Releases in the browser.
- Universal release (
arm64+x86_64) for macOS 14+. - Hardened release chain with exact-main provenance, protected Git refs, ASan/UBSan gates, immutable action pins, Developer ID signing, Team ID checks, Apple notarization and Gatekeeper assessment.
SangKey.app — opened only when needed
AppKit control menu + ServiceManagement
│
│ CFPreferences + Darwin notification
▼
SangKeyAgent — always running
Foundation + ApplicationServices + Carbon + Security
CGEventTap + Accessibility compatibility paths
│
▼
OpenKey-derived C++ engine
Telex / VNI / English detection
The control app and input agent share an explicit preferences domain. There is no XPC protocol or database between them. CI inspects both final Mach-O binaries; the always-on agent fails the build if it links AppKit, ServiceManagement, SwiftUI, Combine or the Swift runtime.
The v0.4 CI gate runs the actual embedded SangKeyAgent with the production English detector corpora and Vietnamese dictionary loaded, while skipping only the TCC-dependent event tap. Its idle RSS must stay below 30 MiB. The architecture was selected after measurement showed the previous AppKit-resident process dominated idle memory; rewriting the dictionaries would have saved very little by comparison.
All typing conversion happens locally. SangKey has no account system, analytics, telemetry SDK, clipboard client, keychain client, background updater or in-process HTTP client in the input agent.
SangKeyAgent needs System Settings → Privacy & Security → Accessibility
because a system-wide event-tap input method must observe and synthesize keyboard
events. For password/secure-input contexts, macOS Secure Event Input is the
platform boundary; SangKey does not claim a custom password-field detector.
The control app itself does not process keystrokes. It can open the Accessibility and Login Items settings pages so you can approve the agent when macOS requires it.
See SECURITY.md for the full threat model.
Launch SangKey.app when you want to change settings. Its transient menu lets you:
- enable/disable the background input agent;
- select Vietnamese / English mode;
- select Telex, VNI, Simple Telex 1/2;
- toggle automatic English detection;
- toggle Vietnamese spelling + modern orthography;
- toggle Spotlight and browser/Google Docs compatibility paths;
- open Accessibility or Login Items settings;
- open the GitHub Releases page for a manual update check.
The VI/EN hotkey defaults to ⌃⌘Space. Choosing Đóng bảng điều khiển exits
the AppKit control process; the registered SangKeyAgent continues running.
Choosing Tắt bộ gõ nền persists that choice, so reopening the control app does
not silently re-enable it.
Until the planned GitHub repository rename is completed, the live release URL is:
https://github.com/sangtrx/84Key/releases
GitHub keeps redirects when a repository is renamed, so this URL remains a safe
entry point after the repository becomes sangtrx/SangKey.
A release contains:
SangKey-vX.Y.Z.dmgSHA256SUMS
The DMG itself also contains:
LICENSE.txtNOTICE.txtTHIRD_PARTY_DATA.txtwith byte-pinned English detector provenanceSOURCE.txtpointing to the exact corresponding-source commit.
Verify before installation:
shasum -a 256 -c SHA256SUMS
xcrun stapler validate SangKey-vX.Y.Z.dmg
spctl -a -t open --context context:primary-signature SangKey-vX.Y.Z.dmgThen:
- Drag SangKey into
/Applications. - Launch
SangKey.apponce so it can register the bundled background agent. - If macOS asks for background-item approval, use Mở Login Items… and approve it.
- Grant Accessibility to the SangKey input agent when macOS prompts / shows it in Privacy & Security → Accessibility.
- Close the control panel when finished; the headless agent keeps typing.
Avoid running another event-based Vietnamese input utility at the same time.
Requirements:
- macOS 14+
- Xcode 26.6 (build 17F113) for release-reproducible builds
- XcodeGen 2.46.0
Run the engine/sanitizer/security suite:
bash core/tests/run_tests.shBuild the app + agent:
cd platform/macos
xcodegen generate
xcodebuild \
-project SangKey.xcodeproj \
-scheme SangKey \
-configuration Debug \
CODE_SIGNING_ALLOWED=NO \
buildCreate a local package:
bash tools/package.shReproduce the universal release architecture:
SANGKEY_ARCHS="arm64 x86_64" bash tools/package.shcore/engine/— OpenKey-derived C++ typing engine.core/data/— byte-pinned CC0 English detector data, SangKey supplement, and the Vietnamese Telex dictionary.core/tests/— engine, typing simulation, ASan/UBSan and parser tests.platform/macos/Agent/— always-on headlessSangKeyAgent+ bundled LaunchAgent descriptor.platform/macos/App/SangKeyApp.mm— ephemeral AppKit/ServiceManagement control menu.platform/macos/HeadlessCompat/— narrow adapters for three AppKit conveniences inherited by the input bridge.platform/macos/Shared/— explicit shared preferences + Darwin notification contract.platform/macos/Input/— Objective-C++ event-tap/input bridge.platform/macos/tests/— distribution/security/runtime invariants.tools/package.sh— nested-code signing, local/release packaging and notarization..github/workflows/— CI and split-privilege release pipeline.
SangKey is an independently branded macOS distribution derived from:
Automatic English detection uses byte-pinned CC0 data from
dariusk/corpora plus a small
SangKey-maintained CC0 supplement. The historical google-10000-english payload
is not tracked or distributed by SangKey v0.4; see
core/data/ENGLISH_WORDS_PROVENANCE.md.
Upstream attribution is preserved in source files and NOTICE. Because
the typing engine derives from GPLv3-licensed OpenKey, SangKey is distributed
under GNU GPLv3. See LICENSE and NOTICE.