A modern Vietnamese Input Method Engine (IME) for Linux with direct Unicode input—no pre-edit buffer, no underlines.
Find a file
vndangkhoa 42595d4bae Fix backspace in grab mode: inject KEY_BACKSPACE via uinput
When grab is enabled, the physical key is intercepted by evdev grab.
The engine's pop() updates the buffer but the KEY_BACKSPACE was never
injected — send_char('\x08') can't emit a keycode and fell through to
paste_string. Now backspace injects KEY_BACKSPACE press+release via
uinput directly.
2026-06-24 18:04:09 +07:00
cli Viet+ v0.1.0 - Vietnamese Input Method for Linux 2026-06-24 10:13:10 +07:00
daemon Fix backspace in grab mode: inject KEY_BACKSPACE via uinput 2026-06-24 18:04:09 +07:00
engine Improve engine: tone placement, backtrack limit, grab default 2026-06-24 17:57:24 +07:00
packaging/appimage Fix garbled text: correct AppRun Wayland detection + atomic injection 2026-06-24 17:33:13 +07:00
protocol Fix injection: skip ydotool for Unicode, use xdotool/xclip 2026-06-24 17:47:09 +07:00
ui Viet+ v0.1.1 2026-06-24 17:29:12 +07:00
.gitignore Gitignore runtime status file 2026-06-24 17:33:39 +07:00
Cargo.toml Viet+ v0.1.0 - Vietnamese Input Method for Linux 2026-06-24 10:13:10 +07:00
LICENSE Viet+ v0.1.0 - Vietnamese Input Method for Linux 2026-06-24 10:13:10 +07:00
Makefile Viet+ v0.1.1 2026-06-24 17:29:12 +07:00
README.md Viet+ v0.1.1 2026-06-24 17:29:12 +07:00
vietc.service Viet+ v0.1.1 2026-06-24 17:29:12 +07:00
vietc.toml Improve engine: tone placement, backtrack limit, grab default 2026-06-24 17:57:24 +07:00

Platform Rust License Version


Viet+

Vietnamese Input Method for Linux
Zero underline • Native Wayland/X11 • Built in Rust

FeaturesQuick StartInput MethodsConfigurationInstallationBuilding


Why Viet+?

Most Vietnamese input methods on Linux suffer from underline hell — pre-edit buffers that duplicate text, show ugly underlines, and break your flow. Viet+ takes a different approach:

Direct Input — keystrokes are instantly converted to Unicode. No pre-edit buffer. No underline. No text duplication. Just pure Vietnamese.


Features

Feature Description
Direct Input Engine No pre-edit buffer, no underline, no text duplication
Telex & VNI Both input methods fully supported
Flexible Diacritic Placement Type modifiers/tone marks at end of syllable (e.g., tranaftrần)
Auto-Restore English Hit space/ESC to undo accidental Vietnamese conversion
ESC Undo Strip all tones from the current word instantly
Smart App Memory Remembers Vietnamese/English per application
Macro Expansion Custom shortcuts (e.g., kokhông)
Uinput Injection Direct uinput keystroke injection (no display server needed)
Hot Reload Config changes apply without restart
Zero Telemetry No keylogging, no disk writes, fully FOSS

Quick Start

# Clone and build
git clone https://git.khoavo.myds.me/vndangkhoa/vietc.git
cd vietc
make build

# Test the engine interactively
cargo run --bin vietc-cli

# Run the daemon (requires root for keyboard grab + uinput)
sudo make run

# Or use the AppImage
sudo ./Viet+-0.1.0-x86_64.AppImage

Input Methods

Telex (Default)

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

VNI

Key Result
a1 á
a2 à
a3
a4 ã
a5
a6 â
a8 ă
e6 ê
o6 ô
o7 ơ
u7 ư

Configuration

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

input_method = "telex"
toggle_key = "space"
start_enabled = true

[auto_restore]
enabled = true

[app_state]
enabled = true
english_apps = ["code", "vim", "kitty", "foot"]
vietnamese_apps = ["telegram", "discord", "firefox"]

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

Architecture

┌──────────────┐     ┌──────────────┐     ┌────────────────┐
│  evdev       │────▶│  Viet+       │────▶│  uinput/X11    │
│  keyboard    │     │  Engine      │     │  injection     │
│  monitor     │     │  (Telex/VNI) │     │                │
└──────────────┘     └──────────────┘     └────────────────┘
                           │
                     ┌─────┴─────┐
                     │  App State │
                     │  Manager   │
                     └───────────┘

Installation

System Dependencies

Component Ubuntu/Debian Fedora Arch
Core daemon (none) (none) (none)
Settings UI libgtk-4-dev libadwaita-1-dev gtk4-devel libadwaita-devel gtk4 libadwaita
Tray icon libdbus-1-dev pkg-config dbus-devel pkgconf dbus pkgconf
make appimage
# Requires appimagetool

The AppImage bundles all dependencies. Run with sudo for keyboard grab:

sudo ./Viet+-0.1.0-x86_64.AppImage

Manual Install

sudo make install
sudo make install-ui    # optional
sudo make install-tray  # optional

Building

# Build all backends (uinput + X11 + Wayland)
make build-all

# Run tests (162+ engine tests)
make test

# Run interactive test harness
cargo run --bin vietc-cli

# Build AppImage
make appimage

Make Targets

Target Description
make build-all Build all backends (uinput + X11 + Wayland)
make test Run all tests
make run Run daemon (debug, requires root)
make appimage Build AppImage package
make clean Clean build artifacts
make fmt Format code
make lint Run clippy

Project Structure

viet+/
├── engine/          # Core IME engine (Telex + VNI)
│   ├── src/
│   │   ├── engine.rs      # Main engine orchestrator
│   │   ├── telex.rs       # Telex state machine
│   │   ├── vni.rs         # VNI engine
│   │   ├── english.rs     # English auto-restore dictionary
│   │   └── tests.rs       # 162+ unit tests
│   └── Cargo.toml
├── protocol/        # Injection backends
│   ├── src/
│   │   ├── inject.rs              # KeyInjector trait
│   │   ├── uinput_monitor.rs      # Universal uinput+ydotool backend
│   │   ├── x11_inject.rs          # X11 XTEST fallback
│   │   └── wayland_im.rs          # Wayland IM context
│   └── Cargo.toml
├── daemon/          # Background daemon
│   ├── src/
│   │   ├── main.rs        # Evdev loop, hot-reload
│   │   ├── config.rs      # TOML config loader
│   │   ├── app_state.rs   # Per-app state manager
│   │   └── display.rs     # Display server detection
│   └── Cargo.toml
├── cli/             # Interactive test harness
├── ui/              # Settings UI + tray (GTK4/Libadwaita)
│   ├── src/
│   │   ├── main.rs        # Settings app
│   │   ├── window.rs      # Settings window
│   │   ├── tray.rs        # System tray icon
│   │   └── config.rs      # UI config reader
│   └── Cargo.toml
├── packaging/       # Distribution packages
│   └── appimage/    # AppImage build scripts
├── vietc.toml       # Default configuration
├── vietc.service    # Systemd user service
├── Makefile         # Build targets
└── README.md

License

MIT License - see LICENSE for details.


Made with ❤️ for the Vietnamese Linux community