A modern Vietnamese Input Method Engine (IME) for Linux with direct Unicode input—no pre-edit buffer, no underlines.
Find a file
2026-07-04 18:20:53 +07:00
.github/workflows production: download prebuilt binaries instead of building from source 2026-07-04 18:20:53 +07:00
cli release: v0.1.7 — password detection, Telex enabled, GNOME Wayland support 2026-07-01 11:00:11 +07:00
daemon fix: remove MSC_SCAN fallback, deduplicate multi-device events in non-grabbed mode 2026-07-04 18:20:53 +07:00
engine v0.1.19 2026-07-04 18:20:53 +07:00
NOTES feat: terminal VNI input — force VNI in terminals, remove from bypass_apps 2026-07-02 08:57:17 +07:00
packaging add installation and packaging scripts 2026-06-29 20:45:48 +07:00
protocol fix: X11 injector sends 'u' instead of backspace in paste_via_clipboard 2026-07-04 18:20:53 +07:00
scripts feat: add test VM setup script for Linux Mint/Ubuntu 2026-07-02 11:56:01 +07:00
ui v0.1.19 2026-07-04 18:20:53 +07:00
uinputd release: v0.1.7 — password detection, Telex enabled, GNOME Wayland support 2026-07-01 11:00:11 +07:00
web feat: add website as web/ subfolder 2026-07-04 17:18:22 +07:00
.gitignore release: v0.1.5 — Event Sourcing, Flatpak build fixes, icons 2026-06-28 21:20:19 +07:00
Cargo.toml fix: X11 key lookup, bamboo engine port, uinput injection overhaul 2026-06-26 15:20:03 +07:00
CHANGELOG.md docs: update changelog for distro support, roadmap, deps fixes 2026-07-01 17:07:40 +07:00
install.sh fix(installer): support CachyOS and use usermod for group setup 2026-07-04 18:20:53 +07:00
LICENSE Viet+ v0.1.0 - Vietnamese Input Method for Linux 2026-06-24 10:13:10 +07:00
Makefile release: v0.1.6 — uinput-first injection, window-switch fix, Telex disabled 2026-06-29 16:07:15 +07:00
README.md docs: announce terminal support in Features table + Configuration 2026-07-02 16:25:42 +07:00
uninstall.sh production: download prebuilt binaries instead of building from source 2026-07-04 18:20:53 +07:00
vietc.service Viet+ v0.1.1 2026-06-24 17:29:12 +07:00
vietc.toml fix: start_enabled=true by default, log daemon to file instead of /dev/null 2026-06-26 09:09:04 +07:00

Platform Rust License Version Tests Event Sourcing


Viet+

Vietnamese Input Method for Linux
Zero underline • No pre-edit buffer • Backspace-Replay sync • Built in Rust


What is Viet+?

Viet+ is a Vietnamese input method for Linux that takes a fundamentally different approach from every other IME: Direct Input.

Most Vietnamese IMEs use a pre-edit buffer — you type into a temporary buffer with an ugly underline, and the text only becomes real Vietnamese when you commit it. This causes duplicate text, underline distraction, broken copy/paste, and desync between the engine state and what's on screen.

Viet+ eliminates all of this. Keystrokes are instantly converted to Unicode — what you type is what you see. No buffer. No underline. No duplication.


Features

Feature How It Works
Direct Input No pre-edit buffer. Keystrokes instantly become text via uinput injection
VNI & Telex Both input methods fully supported, switchable at runtime via Ctrl+Shift
Bamboo Engine Transformation model — composition, marks, tones, flexible backtracking
Smart Clusters uo→ươ with backtrack, ua→ưa horn placement
Macro Expansion ko → không, dc → được, add your own
Casing Preservation Tieengs → Tiếng, TIEENGS → TIẾNG
App Memory Per-app Vietnamese/English state, saved to overrides.toml
Hot Reload Config changes apply without restart
Window-Switch Reset Engine clears automatically on Alt+Tab
CPU Priority Pinned to P-cores (0-3) + nice(-10) for low-latency input
Uinput Injection /dev/uinput for reliable injection on X11 and Wayland
Terminal Support Works in all major terminals: kitty, alacritty, gnome-terminal, konsole, foot, wezterm, st, urxvt, xterm
Password Auto-Detection 4 layers: AT-SPI2 → sudo process → window-title → window-class
Tray Icon Shows current mode: Red VN / Blue TLX / Gray EN
GNOME/Wayland Native GNOME Shell D-Bus integration

Input Methods

Both VNI and Telex are fully supported. Switch via Ctrl+LeftShift or the tray menu.

VNI

Key Result Example
1 á (sắc) a1á
2 à (huyền) a2à
3 ả (hỏi) a3
4 ã (ngã) a4ã
5 ạ (nặng) a5
6 â/ê/ô a6→â, e6→ê, o6→ô
7 ơ/ư o7→ơ, u7→ư
8 ă a8→ă
9 đ d9→đ

Telex

Key Result Example
s á (sắc) as→á
f à (huyền) af→à
r ả (hỏi) ar→ả
x ã (ngã) ax→ã
j ạ (nặng) aj→ạ
aa â aa→â
ee ê ee→ê
oo ô oo→ô
ow ơ ow→ơ
aw ă aw→ă
uw ư uw→ư
dd đ dd→đ
w ươ chuongw→chương

Key Bindings

Combo Action
Ctrl+Space Toggle Vietnamese ON/OFF
Ctrl+LeftShift Toggle VNI ↔ Telex

Password Detection

4-layer automatic detection. When a password field is detected, Vietnamese is automatically disabled:

Layer Method Detects
1 AT-SPI2 D-Bus (a11y role check) Password fields in accessible apps
2 Process tree (pstree) sudo / passwd in terminal
3 Window title keywords password, sudo in title
4 Window class matching pinentry, polkit, kwallet dialogs

Distro Support

Tier Distro Install Method Status
Supported Ubuntu, Debian, Linux Mint, Pop!_OS, elementary OS, Zorin, Neon apt (auto-detected) Tested, one-command install
Supported Fedora, RHEL, CentOS dnf (auto-detected) Tested, one-command install
Supported Arch, Manjaro pacman (auto-detected) Tested, one-command install
⚠️ Might support openSUSE, Solus, Void zypper/eopkg/xbps (manual) Package names may differ; run install.sh and install missing deps manually if it fails
Not supported NixOS, Alpine, Gentoo, others N/A No package manager entry — install deps manually, then cargo build --release

⚠️ Tray icon note: GNOME (Ubuntu) and Cinnamon (Mint) need a StatusNotifier watcher for the tray to appear:

  • Ubuntu: sudo apt install gnome-shell-extension-appindicator
  • Mint: pre-installed; works out of the box

Installation

One-Command Install

Works on all Supported distros above. The script auto-detects your package manager:

From GitHub (recommended):

git clone https://github.com/vndangkhoa/vietc.git /tmp/vietc \
  && cd /tmp/vietc && sudo ./install.sh

From Forgejo (self-hosted):

git clone https://git.khoavo.myds.me/vndangkhoa/vietc.git /tmp/vietc \
  && cd /tmp/vietc && sudo ./install.sh

The script installs dependencies, compiles, installs to /usr/bin/, sets up uinput udev rules, and adds your user to the input group.

After install: Log out and log back in, then launch vietc-tray from your application menu.

One-Command Uninstall

From GitHub:

curl -sSL https://raw.githubusercontent.com/vndangkhoa/vietc/main/uninstall.sh | sudo bash

From Forgejo:

curl -sSL https://git.khoavo.myds.me/vndangkhoa/vietc/raw/branch/main/uninstall.sh | sudo bash

Manual Build & Run

# Install dependencies
sudo apt install git curl build-essential pkg-config \
  libx11-dev libxtst-dev libevdev-dev libdbus-1-dev libwayland-dev wl-clipboard

# Enable accessibility (Ubuntu Wayland — for password detection)
gsettings set org.gnome.desktop.a11y.applications screen-reader-enabled true

# Build
git clone https://github.com/vndangkhoa/vietc.git
cd vietc
cargo build --release

# Run (Mint — no sudo needed for uinput)
./target/release/vietc

# Run (Ubuntu — needs sudo for keyboard grab)
sudo ./target/release/vietc

Configuration

Config file: ~/.config/vietc/config.toml or ./vietc.toml

input_method = "vni"            # "vni" or "telex"
toggle_key = "space"            # Ctrl+Space to toggle VN/EN
toggle_method_key = "shift"     # Ctrl+Shift to toggle VNI/Telex
start_enabled = true            # Vietnamese by default
grab = true                     # grab keyboard (evdev)

[password_detection]
enabled = true
check_atspi2 = true
check_window_title = true
title_keywords = ["password", "passphrase", "secret", "mật khẩu", "sudo"]
password_apps = ["pinentry", "pinentry-gtk-2", "pinentry-qt",
  "lxqt-sudo", "kdesudo", "gksudo",
  "polkit-gnome-authentication-agent-1",
  "kwallet", "gnome-keyring", "ssh-askpass"]

[app_state]
enabled = true
english_apps = ["code", "vim"]
vietnamese_apps = ["telegram", "discord", "firefox"]
bypass_apps = ["steam"]

### Terminal Usage

Viet+ works perfectly in terminals. When running inside a terminal (e.g., gnome-terminal, kitty), Vietnamese input is automatically enabled:

```toml
terminal_input_method = "vni"    # Automatically switch to VNI when running in a terminal app

Supported terminals: kitty, alacritty, gnome-terminal, konsole, foot, wezterm, st, urxvt, xterm

Type Vietnamese directly — no pre-edit buffer, no underline, no duplication. Just type VNI or Telex digits and see Unicode characters instantly! terminal_apps = ["kitty", "alacritty", "gnome-terminal", "konsole", "foot", "wezterm", "st", "urxvt", "xterm"] terminal_input_method = "vni"

[macros] ko = "không" dc = "được" vs = "với"


---

## Architecture

vietc/ ├── engine/ # Vietnamese composition engine (bamboo-core port) ├── protocol/ # Keyboard capture & injection │ ├── uinput_monitor.rs # /dev/uinput injection (primary) │ ├── x11_inject.rs # XTest injection (fallback) │ ├── x11_capture.rs # XRecord key capture │ └── wayland_im.rs # Wayland IM protocol (stub) ├── daemon/ # Main daemon process │ ├── main.rs # Event loops, grab, signal handling │ ├── config.rs # TOML config loader + hot reload │ ├── app_state.rs # Per-app VN/EN memory + password detection │ ├── password_detector.rs # AT-SPI2 D-Bus password field detection │ └── display.rs # X11/Wayland/compositor detection ├── ui/ # System tray icon (ksni) │ └── tray.rs # Tray with VN/TLX/EN mode display ├── cli/ # Interactive test harness └── uinputd/ # Privileged uinput socket daemon


---

## Roadmap

### v0.1.8
- Wayland input method protocol (`zwp_input_method_v2`) — eliminates clipboard + backspace race, fixes missing spaces permanently
- Event-based AT-SPI2 focus monitoring (subscribe to a11y focus events, no polling)

### v0.1.9
- GitHub Actions CI for automated .deb builds
- Flatpak re-add for immutable distros

---

## License

MIT License — see [LICENSE](LICENSE) for details.

---

<p align="center">
  <sub>Made with love for the Vietnamese Linux community</sub>
</p>