strans
strans is a small, single-user input method for Korean, Japanese, English, and emoji on X11 and Wayland. It provides one engine shared by XIM, GTK 3, IBus, and Wayland input-method-v2 frontends. The existing Vietnamese Telex mode remains available for compatibility, but is not an actively developed language mode.
Input behavior
English is direct passthrough. Korean uses 2-beolsik composition. Japanese
Hiragana keeps the complete kana reading until it is committed, so kanji
forms かんじ and offers whole-reading candidates such as 漢字 and 幹事.
An apostrophe resolves an ambiguous n without forwarding the apostrophe:
for example, n'ya forms んや. Katakana is direct Katakana composition
and does not perform Kanji dictionary conversion.
A Japanese composition is committed by Enter, candidate selection, a real
input boundary, or an explicit mode change. Backspace first removes pending
romaji, then accumulated kana. The Japanese modes support doubled consonants
and combinations such as nya, nnya, and matcha.
Modes and temporary searches use Ctrl and one letter:
Ctrl+N Japanese Hiragana and Kanji conversion
Ctrl+K Japanese Katakana
Ctrl+S Korean Hangul
Ctrl+T English passthrough
Ctrl+V Vietnamese Telex compatibility mode
Ctrl+E Emoji and symbol search
Ctrl+H One-shot Hanja search (from Korean mode)
Ctrl+P Toggle popup preedit
While candidates are visible, Up and Down move the selection, Enter accepts
the selected candidate, and an unmodified 1-9 selects the corresponding
visible row. Tab cycles temporary search results. 0 commits an unconverted
language reading. Escape cancels the current composition. Ctrl, Alt, or
Super combined with a number does not select a candidate.
Emoji search is temporary and returns to the previous mode. Queries may use
English aliases or the active language's input rules, including Japanese
egao becoming えがお or エガオ:
Ctrl+E → smile → Enter → 😀
Hanja search is available only from Korean mode and returns to Korean mode
after one conversion. Press Ctrl+H, type exactly one Hangul syllable with
the normal 2-beolsik Shift and Caps Lock behavior, then select with Up, Down,
Tab, Enter, or 1-9. Escape cancels the search; when there is no match,
Enter commits the Hangul reading. It does not convert words or text already
surrounding the cursor.
Build and test
The supported build uses Docker so host and container toolchains are not mixed. Only Docker and Make are needed on the host:
git submodule update --init
make docker-image
make docker-build
make docker-check
docker-image creates the Arch Linux dependency image, docker-build
compiles the runtime components, and docker-check runs the map verifiers and
test suites. Docker targets force their own compilation, so newer host
objects cannot be reused. docker is a convenience alias for the image and
build steps.
The resulting runtime artifacts are:
strans daemon, IBus and Wayland frontends
xim/strans-xim XIM frontend
gtk/im-strans.so GTK 3 frontend
Use make docker-check TESTARGS=hangul to filter the C unit tests. A native
build is still possible with the dependencies and Plan 9 setup recorded in
Dockerfile; use make all, make check, and make bench inside that
environment.
After editing an input source, regenerate and verify its dictionary with:
map/mkemoji >map/emoji.dict
map/mkhanja >map/hanja.dict
make verify-map
Hanja import and Japanese dictionary regeneration are documented in
map/README. The converter output is deterministic UTF-8,
tab-separated data consumable by the runtime dictionary reader.
Run and install
Start the daemon with the installed map and font directories:
./strans map font &
The IPC socket is placed at $XDG_RUNTIME_DIR/strans.sock when
XDG_RUNTIME_DIR is an absolute path. Otherwise strans uses the per-user
fallback /tmp/strans.<uid>. A second daemon will not replace a live
daemon's socket.
For XIM applications:
./xim/strans-xim &
export XMODIFIERS=@im=strans
xterm
For GTK 3 applications, install the module built by Docker. Installation needs the GTK 3 runtime, but not its development package:
doas make -C gtk install
LIBDIR defaults to /usr/lib and may be overridden for another system.
Normal DESTDIR semantics are supported, and a staged install does not update
the host GTK module cache:
make -C gtk install DESTDIR="$pkgdir"
For IBus clients such as kitty:
GLFW_IM_MODULE=ibus kitty
Wayland needs no environment variable. Start strans after a compositor
that supports input-method-v2. Neither ibus-daemon nor fcitx is required.
Starting without DISPLAY is supported: the optional X popup is disabled,
while input processing and non-X frontends continue to run.
Ownership and rendering constraints
There is one global composition, not one independent engine per frontend context. The first meaningful key from a new context resets the previous composition and transfers ownership. Reset, focus loss, context destruction, and disconnect affect the engine only when they come from its active owner; stale events cannot clear a newer owner's preedit.
The popup is an optional X window, including when the active frontend is Wayland. It uses deterministic font fallback and fixed-width rune cells; U+FE0E and U+FE0F variation selectors use zero cells. It does not perform OpenType shaping, color-emoji rendering, or general grapheme clustering, and there is no native Wayland popup renderer. Multi-rune emoji are committed intact but are drawn as their constituent rune cells under this boundary. A supplied caret rectangle is used when available, with the pointer as fallback. The X renderer accepts only a 24-depth, 32-bpp TrueColor root format and disables itself cleanly on other visuals.
Data, third-party code, and licensing
Data and third-party provenance is recorded in
docs/PROVENANCE.md, with font-specific details in
font/PROVENANCE. The historical SKK-derived Kanji
dictionary is distributed under GPL version 2 or later; its license text is
in LICENSES/GPL-2.0-or-later.txt.
The single-character Hanja data derived from libhangul is distributed under
the BSD 3-Clause license in
LICENSES/BSD-3-Clause-libhangul-hanja.txt.
The repository does not currently declare a license for the strans project source as a whole. The licenses of bundled data, fonts, generated protocol code, and third-party components do not by themselves license the original strans source.