UNIM Help v0.4.4 한국어

Linux edition — this page is an offline copy generated automatically from the Markdown in docs/user/. If anything looks out of date or a link is broken, see the latest version in the GitHub docs.

UNIM User Manual (English)

UNIM 0.4.0 — Universal Next-generation Input Method A Rust-based input method engine for fluid Korean/English typing. Goal of this document: get a first-time user to type one Korean syllable within five minutes.


1. What is UNIM (30-second pitch)

Acronyms expanded: IM Module (Input Method Module) — toolkit-specific adapter (one per GTK/Qt/etc) that lets an app delegate keystrokes to the IME. DBus (Desktop Bus) — the Linux desktop's inter-process communication bus; UNIM uses it to talk between the daemon and the frontends. XIM (X Input Method) — the oldest IME protocol, dating back to X11. Wayland — modern display protocol; IM handling differs from X11.


2. Quick Start (5 minutes)

2.1 Install

🐧 Linux — supported: Ubuntu 24.04 (noble) or newer / equivalent Debian, amd64. The release .debs are built on noble.

A single line downloads every UNIM .deb from GitHub Releases and installs them via apt. Every .deb is SHA256-verified, isolated in a mktemp working directory, and external runtime dependencies are resolved automatically. On any checksum mismatch it aborts without installing anything (no partial install).

curl -fsSL https://raw.githubusercontent.com/from104/unim/main/install.sh | bash

To pin a specific version:

UNIM_VERSION=v0.4.0 curl -fsSL https://raw.githubusercontent.com/from104/unim/main/install.sh | bash

If you don't trust curl | bash, download the script first, read it, then run it:

curl -fsSL https://raw.githubusercontent.com/from104/unim/main/install.sh -o install.sh
less install.sh && bash install.sh
Method 2 — manual download from Releases

Grab every unim*_<version>-1_{amd64,all}.deb plus SHA256SUMS from Releases into the same directory, verify, and install.

# Verify checksums (e.g. 0.4.0-1 — 11 packages)
sha256sum -c SHA256SUMS

# Install (apt resolves dependencies automatically)
sudo apt install ./unim*.deb

# Remove IBus (avoids conflict on GNOME)
sudo apt remove ibus

# Register UNIM as the system IME (Debian/Ubuntu standard tool)
im-config -n unim

Log out and back in once so the new environment variables propagate to your shell.

Method 3 — from source (Arch/Fedora/others)
git clone https://github.com/from104/unim.git
cd unim
make build           # Builds Rust workspace + GTK3/4 + Qt5/6 IM modules in one shot
sudo make install PREFIX=/usr
sudo make install-systemd PREFIX=/usr
systemctl --user daemon-reload
systemctl --user enable --now unim-daemon.service

Source builds need cargo 1.95+, GTK4/libadwaita headers, and Qt5/Qt6 dev packages. Package names vary by distro; see troubleshooting/build-failure.

2.2 Environment variables (any desktop without GNOME extension)

For KDE Plasma, XFCE, Sway, Hyprland, etc., add three lines to ~/.xprofile or /etc/environment:

export GTK_IM_MODULE=unim
export QT_IM_MODULE=unim
export XMODIFIERS="@im=unim"

Log out and back in. On Debian-family distros, im-config -n unim does the same in one command.

2.3 GNOME + Wayland users

On GNOME Shell, the unim-gnome-extension is responsible for key interception and popup rendering. You enable the extension instead of setting environment variables.

gnome-extensions enable unim-gnome@from104.github.io

Disable or remove IBus to avoid conflicts:

sudo apt remove ibus

2.4 First Korean keystroke (60 seconds)

  1. Open a text editor (e.g. GNOME Text Editor, Kate).
  2. Press Hangul (or Shift+Space, depending on your keyboard) — the tray icon switches to "한".
  3. Type dkssud → "안녕" appears.
  4. Press Hanja (or F9) — a popup with 安寧 candidates appears. Pick with digits 1–9.
  5. Press Hangul again to switch back to English mode.

If all five steps work, you are done. If not, head to troubleshooting.


2.5 Popup behavior overview

🐧 Linux — since UNIM 0.3.0, hanja, special-character, and emoji popups are rendered by a single service: unim-popup-service.

EnvironmentPopup rendererNotes
GNOME WaylandGNOME Extension popup_view.js (St widget)Mutter does not support wlr-layer-shell; extension renders directly
GNOME X11 / KDE / Xfce / X11 WMunim-popup-service GTK4 windowAuto-launched via D-Bus activation
Wayland (KDE Plasma 6 / Sway / Hyprland)unim-popup-service GTK4 window (wayland-backend)Requires libgtk4-layer-shell

Single source of truth: regardless of environment, the daemon's PopupRender payload (cells, header, footer, tabs, highlight) is the single view-model delivered to all renderers. Only the rendering implementation differs.

Outside-click dismiss: clicking outside the popup closes it, and the click event is passed through to the window below. If a popup closes unexpectedly, this is intended behavior — see troubleshooting.

KDE Plasma 5.x Wayland — unsupported: gtk4-layer-shell is not available in the Ubuntu 24.04 standard repository, so popups do not appear. Workaround: use an X11 session or switch to GNOME.

KDE Plasma 6 Wayland / Sway / Hyprland / river — experimental, undertested: builds with the wayland-backend cargo feature and libgtk4-layer-shell installed are theoretically functional, but this experimental status has not changed since the 0.3.0 QA cycle — no additional verification was done for v0.4.0. Expect possible regressions in popup placement, IME focus handover, and layer-shell coordinate translation. For the full per-environment support matrix, see troubleshooting §G environment matrix.


3. Per-environment setup

🐧 Linux — which path UNIM takes depends on your desktop environment and the app's toolkit.

EnvironmentInstall methodIM modulePopup ownerWatch out for
X11 + GTK appsGTK_IM_MODULE=unimgtk3/gtk4 IM moduleunim-popup-service (GTK4, D-Bus auto-activation)—
X11 + Qt appsQT_IM_MODULE=unimqt5/qt6 IM pluginSameOn Plasma, prefer Qt mode
X11 + legacy (Emacs, xterm)XMODIFIERS=@im=unimxim frontendXIM's own Xft popupover-the-spot mode
GNOME + WaylandEnable GNOME extension(apps speak text-input-v3 directly)GNOME ExtensionIBus removal mandatory
KDE + WaylandQT_IM_MODULE=unim + Wayland frontendwaylandunim-popup-service (wayland-backend)input-method-v2
Sway/Hyprland (Wayland)env vars + Wayland frontendwaylandunim-popup-service (wayland-backend)Compositor must support input-method-v2

Detect your environment: echo $XDG_SESSION_TYPE (x11/wayland), echo $XDG_CURRENT_DESKTOP (GNOME/KDE/sway).

3.1 Flatpak/Snap apps that fail to type Korean

On GNOME+Wayland, Flatpak/Snap apps (Telegram, VS Code) have no UNIM IM module inside their sandbox. The host's GTK_IM_MODULE=unim actually blocks input.

Automatic handling: when unim-daemon detects GNOME+Wayland, it sets a Flatpak global override at startup that empties the IM environment variables, so Flatpak apps fall back to the Wayland text-input-v3 → GNOME Extension path.

Manual override (if the auto setup did not run):

flatpak override --user --env=QT_IM_MODULE= --env=GTK_IM_MODULE=

Snap has no global override mechanism. Add a conditional snippet to ~/.profile that empties the IM vars on GNOME+Wayland — see README §1.7.


4. Daily use

4.1 Korean/English mode toggle

KeyActionNote
Hangul keyToggle modeKey code varies by keyboard
Shift+SpaceToggle (fallback)Works on any keyboard
Right Alt (RightAlt)Toggle mode (when added to toggle_keys)Now works on every environment, including GTK/Qt/GNOME
Tray icon clickToggle (mouse)unim-indicator lives in the tray

Mode share (mode_sharing setting, CLI key mode-sharing): "Global" or "Per-app". Global is the default — switching mode in one window instantly syncs every window. Switch to "Per-app" if you want your terminal to stay in English while your text editor stays in Korean.

Accessibility — turn on the toggle beep if you type without watching the screen: Linux has no screen-reader announcement for mode switches, and the toggle beep itself defaults to off (a deliberate choice to avoid false positives). If you type without watching the screen, we recommend turning it on:

unim-cli config set toggle-announce-beep true

On and off are announced with different pitches.

Note: this beep can go silent depending on the mode-share setting. The beep that fires from a tray-icon or GNOME-extension mode change only plays in "Global" mode (unim-dbus/src/engine_worker.rs:1766-1772). Switch to "Per-app" and a tray toggle no longer actually changes the focused window's mode (by design — it avoids sending a false signal), so this beep path goes silent. If you rely on the beep to confirm a language switch, be aware that switching to "Per-app" costs you this signal from tray/extension interactions.

Toggling with Right Alt: Add RightAlt to the toggle_keys setting to switch Korean/English with the right Alt key. GTK, Qt, and the GNOME extension used to filter Right Alt themselves, so it did nothing there (XIM and pure Wayland already worked); the toggle decision is now unified in the daemon, so it behaves the same everywhere. AltGr layouts (right Alt used as AltGr) are unaffected. Note that at the moment of toggling the application may also receive the Alt input (e.g. menu-bar focus in some apps); if you don't want that side effect, remove RightAlt from toggle_keys.

Key-name spelling: toggle_keys takes key names UNIM knows, one name per entry (defaults: Korean, RightAlt). Unlike the AutoTypeFix hotkeys (§4.4), the toggle key does not accept modifier combinations (Ctrl+X). The CLI and the settings app warn about names they cannot parse when saving, and the daemon logs the parse failure — the value is still stored, but the dead key no longer disappears silently.

4.2 Hanja conversion

  1. Type the Korean to convert (e.g. 한국).
  2. Press Hanja (or F9).
  3. A 9-cell grid popup appears: 韓國, 漢國, …
  4. Pick with digits 1–9, navigate with arrow keys, Enter to commit, ESC to cancel.
  5. With more than nine candidates, press . (period) to toggle to a 9×9=81-cell expanded grid. The ⊞/⊟ icon in the corner reflects the current mode.

Choosing the Hanja key: hanja_keys defaults to Hanja, F9. Like the toggle key (§4.1) it takes single key names only — no modifier combinations. The CLI and the settings app warn about names they cannot parse when saving, and the daemon logs the parse failure.

Page navigation (mouse / keyboard)

When candidates exceed one page (9 cells or 81 cells), the footer shows ◀ / ▶ buttons.

[◀]  page 2 / 5  [▶]  ⊞

Acronym: cursor here means the highlighted cell currently holding keyboard focus (rendered as a background highlight).

Right-click semantics — frontend differences

The ◀ / ▶ page buttons behave identically across every frontend, but right-clicking on the grid body itself carries different meaning depending on the frontend you are using. If you want to use it as a mouse shortcut, learn your environment's mapping; otherwise stick to the keyboard shortcuts which are uniform.

Why is GNOME different? GNOME Shell exposes each candidate cell as a Clutter.Actor, so per-cell right-click hit-testing is natural — mapping right-click to the bookmark toggle saves a hand move. GTK/Qt IM modules and XIM run in X11/Wayland override-redirect windows where per-cell hit-testing is more limited, so they keep the classical IME convention of right-click = next page.

In short: ◀ / ▶, keyboard ← / →, and Space mean the same thing everywhere. Only the right-click on the grid body varies. If in doubt, the keyboard alone covers every action.

Bookmarks ☆/★

You can star frequently used Hanja. With a candidate focused, Space toggles ☆ (unbookmarked) ↔ ★ (bookmarked).

The HanjaCandidatesReordered DBus signal refreshes every open popup across GTK/Qt/XIM/Wayland/GNOME/Windows instantly.

When you toggle, the candidate list reorders and the cursor follows the affected hanja:

Why is there flash on un-bookmark but not on bookmark? Bookmarking always lands on page 1 row 1, which is a predictable, eye-catching location — no extra hint needed. Un-bookmarking can jump to any page, so the flash is what tells you where the candidate went.

4.3 Special characters

In Korean mode, type a single jamo (consonant) and then press the Hanja key. The category depends on the consonant.

JamoCategoryExamples
ㄱSymbols!, @, ÷, ≠, ∞
ㄴBrackets「」, 『』, ≪≫
ㄷMath∂, ∇, √, ∫
ㄹUnits$, %, ℃, Å
ㅁShapes■, □, ●, ○
ㅂLines─, │, ┌, ┐
ㅅHangul jamoㄱ, ㄴ, ㅏ
ㅇCircled①, ⓐ
ㅈParenthesized Hangul㈀, ㈁
ㅊ/ㅋParenthesized digits⑴, ⑵
ㅌParenthesized letters⒜, ⒝
ㅍGreekΑ, β, γ
ㅎMisc●, ♨, ☏

Example: type ㅁ, press Hanja, pick 2 from the shapes grid → □ is committed.

4.4 AutoTypeFix

Auto-recovers text typed in the wrong mode. Two directions:

Suppression dictionary (Blacklist) — user learning

When a particular word keeps getting corrected against your wishes:

  1. Press BackSpace to undo the correction and switch modes — UNIM marks the word as "Pending".
  2. The next time the same word triggers AutoTypeFix, the attempt is suppressed and the word is registered as Tentative.
  3. In the GUI's "Suppression Words" page, select an entry and press Activate Permanently to promote Tentative → Confirmed. After 4 hours without a retrigger (the default; adjustable between 1 and 12), Tentative auto-flips to Inactive.

Storage: ~/.config/unim/typefix-blacklist.yaml. The daemon hot-reloads on mtime change.

User dictionary (reverse whitelist) — new in 0.2.0. Select text and use a shortcut to call the RegisterUserDictFromSelection DBus method, registering an English-side entry. Manage entries in the GUI's "User Dictionary" page.

Toggle hotkeys — turn correction on/off with a single key

A shortcut can turn AutoTypeFix on or off instantly. The master toggle defaults to Shift+F8; the forward- and reverse-only shortcuts are empty (assign them only if you want them). Three of them, set separately:

Set them from the CLI:

# The default (master toggle = Shift+F8)
unim-cli config set auto-typefix-toggle-keys "Shift+F8"

# Forward / reverse on F10 and F11 respectively
unim-cli config set auto-typefix-forward-toggle-keys F10
unim-cli config set auto-typefix-reverse-toggle-keys F11

# Multiple keys, comma-separated (any of them toggles)
unim-cli config set auto-typefix-toggle-keys "Shift+F8,Ctrl+Left"

# Clear — an empty value consumes no key
unim-cli config set auto-typefix-toggle-keys ""

In the GTK settings GUI the three fields are not grouped together but distributed across each feature group — the Master toggle sits in the "Type Correction" master group (next to the overall on/off switch), the Forward toggle in the "Forward" group, and the Reverse toggle in the "Reverse" group. Type a key name into each field; leave one empty to disable it.

In the Slint settings app (unim-settings, including Windows) the three fields are gathered side by side in the "Toggle hotkeys" group on the Type Correction page (5.2).

  • Modifier combinations are supported — write them as Shift+F8, Ctrl+Left, Ctrl+Shift+F7 (Ctrl/Control, Alt, Super/Win/Meta, Shift; case- and order-insensitive). A bare name like F10 fires on that key alone, as before. + is the canonical separator; when a spec contains no + at all, - is accepted too (Ctrl-F8 = Ctrl+F8). Mixing them (Ctrl+Shift-F8) is invalid.
  • It fires only on an exact modifier match. Combinations you did not configure (e.g. Shift+F10 for the context menu) are not intercepted and reach the application unchanged.
  • The default is Shift+F8 — F9–F11 are avoided because some keyboards lose them to media functions or remapping (cut/copy/paste) before they reach the OS. It does not clash with the hanja/emoji key (bare F9), and an F9 combo like Shift+F9 leaves the bare-F9 popup intact.
  • Key names must be ones UNIM knows, such as F1–F12 (ScrollLock, Pause, PrintScreen, and Menu are not recognized). The CLI and the settings app warn about names they cannot parse when saving, and the daemon logs the parse failure — nothing is dropped silently.
  • Clear the list ("") to disable a shortcut; it then consumes no key.
  • On GNOME (Wayland), Ctrl/Alt/Super combinations such as Ctrl+Left work too — the UNIM extension forwards toggle combos to the engine (re-login after updating the extension).
  • On Windows (TSF), combination specs behave exactly as on Linux — the default Shift+F8 works as-is.
  • Toggling only forward on while the master switch is off flips the flag but produces no correction until the master switch is on again (the master gates everything). The forward/reverse toggles change only each direction's flag.
  • Accessibility note: with toggle-announce-beep enabled, this toggle also announces its state with a differential beep (rising pitch = on / falling pitch = off), just like the Korean/English switch sound — on both Windows and Linux (on Linux the daemon plays the tone via whichever of paplay/pw-cat/aplay it finds on PATH; if none exist, it's a silent no-op). Default is off — see the accessibility note in 4.1.
Password-field auto-protection

In password and PIN fields, AutoTypeFix turns off automatically. When the app reports "this field is a password" (content_purpose), UNIM stops both forward and reverse correction while you are in that field, and also clears any keystroke-observation buffer and undo history already accumulated. This keeps a password typed like dkssud from being auto-corrected into Korean and corrupted.

4.5 Auto-English-Mode

Opt-in feature for vim command mode (Esc), CLI slash commands (/), etc. Off by default.

If your toggle key collides with a trigger key, the toggle wins (its branch comes first in press_key). Password fields are unaffected (they force English already).

Trigger spelling: write triggers as key:<key name> or char:<character> (e.g. key:Escape, char:/). The older prefix-less form (Escape) is still recognized, and modifier combinations such as key:Ctrl+B are allowed. The CLI and the settings app warn about specs they cannot parse when saving, and the daemon logs the parse failure — nothing is dropped silently.

4.6 Word-unit commit (composition-commit granularity)

By default, UNIM commits per syllable — a syllable is finalized as soon as it is complete. Set this to word unit instead and composition accumulates as underlined preedit through a word boundary (space, punctuation) before committing all at once. BackSpace during composition still steps back one jamo at a time, and this meshes more naturally with AutoTypeFix's reverse correction (4.4).

There are three values.

This does not apply to English input — by design. The commit unit governs Hangul composition only. So when you mix the two, only the Hangul stretches are underlined and English commits the moment you type it. Uneven underlining is that, not a broken setting.

The underline under Hangul shows a composition in progress — ㅎ+ㅏ+ㄴ becoming 한. English has nothing to compose, since one key is already one letter, and so nothing to show. Underlining English too would make the application treat those letters as "not yet committed", which stops autocomplete, spell check, and live search, and breaks single-letter shortcuts (keys like j or t in browsers and editors). It costs a lot and gains nothing, so it is not done.

Turning it on

# Global word-unit
unim-cli config set commit-unit word

# Smart + specific apps only (e.g. LibreOffice)
unim-cli config set commit-unit smart
unim-cli config set word-mode-apps "winword.exe,soffice"

In the settings GUI, pick it from the Korean commit unit combo under General → Layout options. word-mode-apps is edited via CLI/config.yaml (exact match, case-insensitive). Example Linux app ID: LibreOffice is soffice — app IDs can be checked in the log when Mode share is set to Per-app.

When it doesn't apply (safety net)

In word-unit mode, AutoTypeFix's reverse correction (Korean→English) only replaces the composition — it never touches already-committed text. In all of the excluded cases above, UNIM automatically falls back to syllable-unit, so it's safe to leave word-unit turned on without worrying about data loss.


5. Settings GUI Tour

unim-settings (Slint, a single codebase shared by Linux and Windows) is the one entry point for settings. That means the four pages below are identical on both operating systems — only the way you open the window differs.

🐧 Opening it on Linux — the "UNIM Settings" app-menu item, the first-run wizard, and the tray menu all launch this same executable. You can also start it from a terminal.

unim-settings &

About the legacy GTK dialog (unim-settings-gtk): the old GTK4+libadwaita settings window is still shipped in the package, but it is no longer exposed in the app menu (NoDisplay=true in its .desktop file). You can still launch it directly with unim-settings-gtk &, but new settings may not be reflected there — treat unim-settings above as the source of truth. The Qt dialog (unim-gui-qt) has already been retired; the tray icon is now owned by unim-indicator, and the hanja/special-char/emoji popups are owned by unim-popup-service, each running as its own process (see §2.5).

Four pages (left-hand navigation):

5.1 Page 1 — General

GroupWidgetNote
Layout optionsKorean layout / English layoute.g. ko_2bulstd (Dubeolsik standard) — see §7.1. Layout-specific dynamic options (e.g. Sebeolsik 390's "sun-arae batchim") also appear here
Korean commit unitSyllable / Word / Smart — see 4.6
Input modeInitial modeKorean or English when the daemon starts
Mode shareGlobal (default) / Per-app — see 4.1
Per-app rulesAdd rules so specific apps (matched by window/client-name substring) always start in a given mode. Most useful when Mode share = Per-app
Auto-English-ModeEnable switch + trigger keysOff by default — see 4.5
AccessibilityOne-click presets ("One-hand use" / "Relaxed timing") + individual switchesSee below

Accessibility presets: "One-hand use" applies the Sebeolsik-noshift layout + a non-modifier toggle key + moachigi off + auto-repeat suppression, all at once. "Relaxed timing" applies auto-repeat suppression + a wider typo-correction detection window + (on layouts that support it) a wider moachigi chord window. Either preset can still be fine-tuned afterward with the individual switches.

Suppress Composition Key Auto-repeat (accessibility): When you hold a key down, the OS re-fires it rapidly (auto-repeat); enabling this option makes the daemon ignore those repeats. It is meant for users with motor disabilities who tend to hold keys too long (e.g. tremor), and it is now enforced by the daemon on both Windows and Linux (Linux enforcement was previously missing; fixed in v0.4.0). Suppression applies to the Korean/English toggle key and character keys in Korean mode; repeats of editing keys (Backspace, arrows) and direct English typing are left alone. Wayland, Qt5/6, and the GNOME extension detect repeats precisely; the GTK3/4, XIM, and ibus-compatible paths approximate with an 80 ms time window, so the first repeat may slip through and, if your system key-repeat interval is set longer than 80 ms, repeats may not be filtered (in either case it errs toward suppressing less, fail-safe). The default is off; you can also enable it with unim-cli config set ignore-key-repeat true. GNOME extension users: applies after re-login.

Emoji input has no separate switch — it shares the hanja-popup path and is always on; call it with Super+. (or whatever shortcut you registered) — see the keyboard shortcuts guide.

GNOME-extension-only settings (whether the panel indicator is shown, the manual conversion shortcuts, etc.) live in gnome-extensions prefs unim-gnome@from104.github.io, not in this app — see the keyboard shortcuts guide's GNOME section.

5.2 Page 2 — Type Correction

GroupWidgetNote
EnableEnable AutoTypeFixMaster switch. OFF stops both forward and reverse
Correction strengthConservative / Standard / Aggressive presetsTunes thresholds, minimum word length, and detection window all at once. The "Advanced settings" section below still lets you fine-tune individual values
DirectionEnable forward / Enable reverseEach can be toggled independently — see 4.4
Toggle hotkeysMaster on/off, Forward on/off, Reverse on/off (three fields, one group)Toggle instantly with the assigned key. Leave empty to disable. Modifier combos like Shift+F9 are allowed — see 4.4
Advanced settings (collapsible)Korean-syllable threshold / English minimum word length / forward & reverse detection windows (ms) / Tentative expiry (hours) / Observation timeout (sec) — all slidersThe "Correction strength" presets above cover most cases
Options (inside Advanced)Skip English words / Skip complete syllables / Rollback detection / User-dictionary only—
—Restore defaultsResets AutoTypeFix settings to their initial values (undo within 5 seconds)

5.3 Page 3 — Suppression Words

A single list shows Tentative, Confirmed, and Inactive suppressions together (distinguished by a status badge, unlike the old GTK dialog's three separate sections). Select an entry and choose Confirm (promotes to Confirmed) or Delete; Clear all empties the whole list (undo within 5 seconds).

Even if the daemon updates the file, the GUI refreshes immediately. No manual reload needed.

5.4 Page 4 — User Dictionary (reverse whitelist)

Enter a word and an optional note, then Add, to register an English ↔ Korean-jamo-sequence mapping. E.g. wave ↔ ㅈㅐㅍㅁ. Select an entry below and Delete to remove it. Reverse correction prefers user-dict entries.


5.6 Keyboard-layout tools (Keymap Studio / Typing Practice)

Separate from the settings GUI, two GTK4 companion tools ship with UNIM for viewing, editing, and practicing layouts. Each registers in the app list with its own icon (io.github.from104.unim.KeymapStudio, io.github.from104.unim.TypingPractice).

unim-keymap-studio &      # view / edit layouts
unim-typing-practice &    # typing practice

5.6.1 unim-keymap-studio — view / edit layouts

See which jamo/characters each key produces for Korean/English layouts, and build your own.

Shortcuts
KeyAction
F1Help
Ctrl + NNew layout
Ctrl + DDuplicate current layout
Ctrl + SSave (user layouts)
Ctrl + Shift + SSave As
Ctrl + EExport
Ctrl + IImport
Ctrl + 1 / 2 / 3 / 4Switch tab (Basic / Keymap / Combos / Extended)

5.6.2 unim-typing-practice — typing practice

Practice typing with the currently active layout (the one the daemon uses). It auto-reloads when you switch layouts.

Shortcuts
KeyAction
F1Help
Ctrl + RRestart
Ctrl + Shift + CCopy results
Ctrl + 1Practice view
Ctrl + 2Results view
Ctrl + OImport material from file
Ctrl + Shift + VImport material from clipboard

6. Key cheat sheet

🐧 Linux

SituationKeyResult
AnywhereHangul (or Shift+Space)Toggle mode
Korean mode, after typed jamosHanja (F9)Hanja popup
Hanja popup1–9Direct select
Hanja popupArrowsMove focus
Hanja popup←/→ or PageUp/PageDownPage navigation (wrap-around)
Hanja popupMouse ◀ / ▶Page navigation (wrap-around, hidden on single page)
Hanja popupMouse right-clickFrontend-specific: GNOME = toggle ★ bookmark / GTK·Qt IM·XIM = next page / others = no action (see §4.2)
Hanja popupEnterCommit focused
Hanja popupESCCancel
Hanja popup.9 ↔ 81 grid toggle
Hanja popupSpaceBookmark ☆/★ (un-bookmark flashes destination cell 140 ms)
Korean mode, lone consonantHanja (F9)Special-char popup
ComposingBackSpaceDelete last jamo
After unwanted forward correctionBS + HangulTrigger Tentative learning
With Auto-English onEsc or /Force English + pass key

7. CLI usage (unim-cli)

Two purposes: (1) Korean↔English conversion filter, (2) settings management.

7.1 Conversion filter

echo "dkssudgktpdy" | unim-cli                # English → Korean (default)
echo "안녕하세요"   | unim-cli -d              # Korean → English
echo "ekswn"       | unim-cli -k 2bul         # Dubeolsik (default)
echo "j;ax"        | unim-cli -k 390          # Sebeolsik 390
unim-cli -o out.txt input.txt                 # File I/O

Supported layouts:

7.2 Settings management

# Show the full current config (or grep for a specific key)
unim-cli config show

# Set a value — key names take kebab-case (hyphens) only
unim-cli config set auto-typefix true
unim-cli config set auto-typefix-tentative-expiry-hours 6
unim-cli config set auto-english true

# Korean commit unit (syllable/word/smart) — see 4.6
unim-cli config set commit-unit word

# AutoTypeFix toggle hotkeys (comma-separated; modifier combos allowed) — see 4.4
unim-cli config set auto-typefix-toggle-keys "Shift+F8"
unim-cli config set auto-typefix-forward-toggle-keys F10
unim-cli config set auto-typefix-reverse-toggle-keys F11

# Layout profile management
unim-cli config layout list                    # built-in + user profiles
unim-cli config layout describe ko_3bul390     # profile details
unim-cli config layout validate my.json        # validate a custom layout

Setting changes apply to the daemon immediately. config.yaml ↔ unim-cli ↔ the settings GUI (unim-settings) are kept in sync at all three points by design.


8. Config files / backup

FilePurposeBack up?
~/.config/unim/config.yamlGeneral settingsYES
~/.config/unim/typefix-blacklist.yamlLearned suppressionsYES
~/.config/unim/typefix-userdict.yamlReverse user dictYES
~/.config/unim/layouts/*.jsonCustom v1 layoutsYES
~/.unim-errors.logDebug log (UNIM_DEVELOP=1)NO
tar -czf unim-backup-$(date +%F).tar.gz -C ~/.config unim
tar -xzf unim-backup-2026-04-26.tar.gz -C ~/.config
systemctl --user restart unim-daemon

9. Next steps


Doc version: 0.4.0 / 2026-08-01 / License: same as the project.

▲ Back to contents

Keyboard Shortcuts Guide

🐧 Linux

UNIM shortcuts are captured by different actors depending on your desktop / compositor environment. This document explains how to enable them on each environment.

Korean original: README-ko.md


GNOME only — manual conversion shortcuts (on by default)

On GNOME Shell (unim-gnome-extension), the three shortcuts below are on by default with no setup required. No other desktop/compositor (KDE, Sway, Hyprland, etc.) has them — this is a GNOME-only feature, registered directly with the Shell via Main.wm.addKeybinding by the GNOME extension.

ShortcutActionExample
Super+KConvert the focused word English → Korean and replace itgksrmf → 한글
Shift+Super+KConvert the focused word Korean → English and replace itㅗ디ㅣㅐ → hello
Super+ERead the selection and register it in the reverse (Korean→English) AutoTypeFix user dictionaryselect ㅎㅑㅅ → registered as git

These three are distinct from the automatic correction in 4.4 AutoTypeFix — they are manual conversions the user triggers directly. If you use Super combos for something else, or hit a conflict, open the extension's preferences to rebind or disable them:

gnome-extensions prefs unim-gnome@from104.github.io

Rebind or clear Super+K / Shift+Super+K in the "Conversion shortcuts" group, and Super+E in the "Register user dictionary" group.


Emoji popup shortcut (Super+.)

UNIM can pop up an emoji picker at the last active input location. The default shortcut is Super+. (Meta+.). However, who captures the shortcut differs per environment, so on some setups you must register it yourself.

Per-environment behavior

EnvironmentAuto?How to register
X11 / XIMAutoThe unim daemon receives the shortcut via X server redirect
Wayland + GNOMEAutoUNIM GNOME extension registers via Main.wm.addKeybinding
Wayland + KDE PlasmaManualKCM Custom Shortcuts
Wayland + HyprlandManualhyprland.conf
Wayland + SwayManualsway/config
Wayland + WayfireManualwayfire.ini
Wayland + other compositorsManualCompositor's shortcut tool

Why manual registration is needed

Wayland compositors (KDE / Hyprland / Sway / Wayfire, etc.) intercept modifier-based combos like Super+... in their own shortcut subsystem before any application sees them. If the compositor consumes the keystroke, the input method (IME) never receives the event.

On GNOME, the UNIM GNOME extension hooks into Shell's shortcut slot, so it works automatically. Other compositors do not have such an extension, so you need to register unim-cli trigger emoji_popup as a shortcut command in the compositor's own shortcut system.

Common command

unim-cli trigger emoji_popup

Internally this calls the daemon's DBus interface org.atit.unim.InputMethod via the TriggerAction RPC. When the daemon receives the signal, it shows the emoji popup at the most recently active input context (the text widget you used last).

Future actions (e.g. hanja_popup) will follow the same unim-cli trigger <action> pattern.


Per-environment registration

KDE Plasma 6 (Wayland)

  1. Open System Settings → Shortcuts → Custom Shortcuts
  2. Bottom-left Edit → New → Global Shortcut → Command/URL
  3. Name: Trigger UNIM emoji popup (any name)
  4. Trigger tab → press Meta+.
  5. Action tab → Command/URL: unim-cli trigger emoji_popup
  6. Apply

Plasma 5 works the same way (paths: System Settings → Shortcuts → Custom Shortcuts).

Hyprland

Add to ~/.config/hypr/hyprland.conf:

bind = SUPER, period, exec, unim-cli trigger emoji_popup

The config auto-reloads; force it with hyprctl reload.

Sway

Add to ~/.config/sway/config:

bindsym Mod4+period exec unim-cli trigger emoji_popup

Mod4 is the Super (Windows) key. Apply with swaymsg reload.

Wayfire

Add the following to the [command] section of ~/.config/wayfire.ini:

[command]
binding_emoji = <super> KEY_DOT
command_emoji = unim-cli trigger emoji_popup

The config auto-reloads on save.

GNOME (fallback when not using the extension)

If you have the UNIM GNOME extension installed and enabled, no setup is needed. Otherwise, GNOME's built-in shortcut system can do the same:

  1. Settings → Keyboard → View and Customize Shortcuts
  2. Custom Shortcuts → Add Shortcut
  3. Name: UNIM Emoji Popup
  4. Command: unim-cli trigger emoji_popup
  5. Set Shortcut: press Super+. → Add

Some Super combos are reserved by GNOME. If there is a conflict, try a different combo (e.g. Ctrl+Alt+E).

X11 + arbitrary WM (xbindkeys)

On X11/XIM, the daemon usually matches the shortcut automatically and no manual registration is required. However, in environments where the daemon does not receive the key (some game modes, certain screen-switching tools), you can supplement with xbindkeys.

Add to ~/.xbindkeysrc:

"unim-cli trigger emoji_popup"
  Mod4 + period

Apply:

xbindkeys -p   # stop existing instance
xbindkeys      # start again

Verifying it works

After registering the shortcut, watch the daemon log:

journalctl --user -f | grep unim

Or if you run it as a systemd service:

journalctl --user -u unim-daemon -f

A successful press should produce something like:

[DBus] TriggerAction(emoji_popup) received

If you don't see that message:


In-app shortcuts for the layout tools

The Super+. above is a desktop-global shortcut, but the two GTK4 layout tools that ship with UNIM have their own shortcuts that work only inside their windows (no compositor registration needed). For usage details see user manual §5.6.

unim-keymap-studio (view / edit layouts)

KeyAction
F1Help
Ctrl + NNew layout
Ctrl + DDuplicate current layout
Ctrl + SSave (user layouts)
Ctrl + Shift + SSave As
Ctrl + EExport
Ctrl + IImport
Ctrl + 1 / 2 / 3 / 4Switch tab (Basic / Keymap / Combos / Extended)

unim-typing-practice (typing practice)

KeyAction
F1Help
Ctrl + RRestart
Ctrl + Shift + CCopy results
Ctrl + 1Practice view
Ctrl + 2Results view
Ctrl + OImport material from file
Ctrl + Shift + VImport material from clipboard

Notes

Related docs:

▲ Back to contents

UNIM FAQ (English)

The questions people actually ask about UNIM 0.4.4. Each answer carries at least one line of "why it works that way" so you can use it for your next decision, not just as a fact lookup.


Q1. How is UNIM different from ibus-hangul, fcitx-hangul, kime, nimf?

ItemUNIMibus-hangulfcitx-hangulkimenimf
Core languageRustCCRustC
TransportDBus daemon + IM moduleIBus daemonFcitx daemonEmbeddedDaemon
GTK3/4✅ Native IM module✅✅✅✅
Qt5/6✅ Native plugin✅✅✅✅
XIM✅✅✅✅✅
Wayland (input-method-v2)✅✅ (IBus)✅△✅
GNOME Shell direct integration✅ Own extension✅ (IBus)△✗✗
Auto Korean↔English typo fix✅ AutoTypeFix (forward + reverse + learning)✗✗✗✗
Hanja 9-cell / 81-cell grid✅ unified△△✗△
Hanja bookmarks✅ DBus signal sync✗✗✗✗
User layout v1 JSON✅ inherits + rule_sets✗△△✗
License(see project license)LGPL/GPLGPLGPLv3LGPL

One-liner: UNIM's design is "one Rust core plugged into every environment", and it differentiates further on user-experience features (AutoTypeFix, learned suppression dictionary) that other IMEs do not have.


Q2. Can UNIM coexist with another IME on the same desktop?

🐧 Linux

Technically yes, but not recommended. With two IMEs alive, the OS and toolkit cannot tell where to deliver key events.

Bottom line: pick exactly one. Cleanly remove the other before installing UNIM.


Q3. Which environments are most stable?

🐧 Linux

Stability tier as of UNIM 0.2.0:

EnvironmentTierNote
Ubuntu 24.04 + GNOME(Wayland) + extension🟢 ARecommended; main dev/test environment
Ubuntu 24.04 + GNOME(X11)🟢 AEnv vars + Standalone popup
KDE Plasma 6 (Wayland)🟢 B+input-method-v2 works
KDE Plasma 6 (X11)🟢 B+XIM/Qt IM both fine
Sway (Wayland)🟡 BPopup positioning slightly off — see popup spec §8.4
Hyprland (Wayland)🟡 BSame
XFCE/MATE (X11)🟢 B+Traditional, solid
Pure Wayland (compositor-dependent)🟡 B/CDepends on the compositor's IM protocol support

Tier A = "first-time user starting point". Once you are familiar, the rest is fine too.


Q4. How does AutoTypeFix actually work?

Two stages.

Stage 1 — observation

The engine simulates two virtual tracks (Korean track, English track) for every keystroke regardless of mode. So in English mode, while gksrmf arrives, the Korean track is also producing 한글 in parallel.

Stage 2 — trigger

At a word boundary (space, punctuation, Enter), if the other track has produced a meaningful word, propose a correction.

Learning (suppression dictionary)

If the user rejects a correction with BS+mode-switch → marked Pending. The next time the same word triggers, the engine suppresses that attempt and registers it as Tentative. Pressing Confirm in the GUI promotes it to Confirmed (permanent).

Key insight: registration happens at retrigger time, not rollback time. This keeps a one-off mode mistake from becoming a permanent suppression.


Q5-1. When I un-bookmark a hanja, the popup jumps to a different page — is that intended?

Yes, that is the designed behavior. Bookmarking (★) promotes a hanja to the top of page 1; un-bookmarking (☆) demotes it back to its lexicographic home. If that home is on a different page, the popup follows.

To make sure you do not miss that jump, the destination cell flashes Catppuccin yellow (#f9e2af) for 140 ms. The flash answers "I just unstarred it — where did it go?" with a single visual signal.

For mechanics see user manual §4.2 and popup spec §3.6/§3.7.


Q5. What's the difference between the 9-cell and 81-cell Hanja popup?

Item9-cell (compact)81-cell (expanded)
Screen footprintsmalllarge
Visible candidates981 (9×9)
Best fortop candidate is the right onerare hanja, many homophones
Toggle key—. (period)
Indicator⊟ icon⊞ icon
Bindings1–9 direct, arrows1–9 + row jump, arrows

With more than 9 candidates, 9-cell paginates with arrow keys; 81-cell unfolds nine pages at once for visual comparison.


Q6. Where are the config files? Backup and restore?

🐧 Linux

Location

~/.config/unim/
├── config.yaml              # General settings (source of truth)
├── typefix-blacklist.yaml   # Learned suppressions
├── userdict.yaml            # Reverse user dict (new in 0.2.0)
└── layouts/                 # Custom v1 layouts
    └── my_3bul_variant.json

Backup

tar -czf ~/unim-backup-$(date +%F).tar.gz -C ~/.config unim

Restore

systemctl --user stop unim-daemon
tar -xzf ~/unim-backup-2026-04-26.tar.gz -C ~/.config
systemctl --user start unim-daemon

The daemon hot-reloads typefix-blacklist.yaml and userdict.yaml on mtime change, so you can restore them without stopping the daemon. config.yaml caches some keys at start, so a restart is safer for it.


Q7. What layouts exist, and can I add my own?

Built-in Korean layouts

ko_2bulstd (Dubeolsik standard), ko_3bul390 (Sebeolsik 390), ko_3bul391, ko_3bul_noshift, ko_3bul_anmatae (Ahnmatae, chord/moachigi).

Note: Qwerty Sebeolsik (ko_3bul_qwerty) is preserved as a research reference, not as a built-in. Copy docs/references/keymaps/ko_3bul_qwerty_v2.json to ~/.config/unim/layouts/ko_3bul_qwerty.json to activate it as a user profile.

English

qwerty, dvorak, colemak, colemak_dh, workman.

User-defined

🐧 Linux

Drop a v1 schema JSON into ~/.config/unim/layouts/<name>.json — daemon scans automatically. Use inherits: "ko_3bul390" to override only what you need.

unim-cli config layout validate ~/.config/unim/layouts/my.json
# activate
unim-cli config set korean-layout my

Schema details: docs/archive/plans/LAYOUT_PROFILE_V1.md.

Use rule_sets to bundle optional toggles with a layout. E.g. ko_3bul390's sun_arae_batchim. The settings GUI dynamically renders a SwitchRow.


Q8. How much memory does UNIM use?

In normal operation, unim-daemon RSS sits in 30–80 MB. UNIM 0.2.0 hardens this:

A previous incident saw RSS balloon to 2 GB on 0.1.x. Regression on those items is forbidden. If you observe RSS > 500 MB, see troubleshooting §14.


Q9. Does UNIM intercept passwords?

No. Password fields are detected via content_purpose and forced to English. AutoTypeFix (both forward and reverse), hanja conversion, and the special-char popup are all disabled. Any keystroke-observation buffer and undo history already accumulated are cleared too, so a password typed like dkssud is never auto-corrected into Korean and corrupted. The input is not retained in daemon memory.

Caveat: automatic detection only works when the app accurately reports content_purpose=password (Linux) or InputScope (Windows). Environments that do not report it — legacy XIM apps, and some Wayland compositors/web forms that do not send content-purpose — may fail to auto-detect; verify English mode manually via the toggle key there. (Environments that detect correctly: GTK3/4, Qt5/6, GNOME extension, Windows TSF — both 64-bit and 32-bit apps are detected the same way, via the unim_tsf32.dll TSF TIP's InputScope. If you've seen a claim that "Windows IMM32 apps are detected on a best-effort basis for standard ES_PASSWORD controls only," that describes the IMM32 fallback, which is not actually shipped in the release — see Q11.)


Q9-1. Why doesn't AutoTypeFix work in password fields?

This is intended. AutoTypeFix is deliberately disabled in password and PIN fields (see Q9), because otherwise a password typed like dkssud would flip to Korean at a word boundary and break your login. It returns to normal the moment you leave the field, and any on/off toggle state you set manually is preserved.

Conversely, if correction fails in a non-password field, the cause is different → Troubleshooting §8. In the undetectable environments above (XIM, some Wayland), a password field is treated as a normal field and correction may in fact fire — that limitation is documented in Troubleshooting §8-1.


Q9-2. Is the one-line install.sh safe?

curl -fsSL .../install.sh | bash is convenient, but it does mean "run an entire unseen script," which can be unnerving. The UNIM installer has four safety guards:

  1. SHA256 checksum verification — the SHA256SUMS shipped in the release acts as the manifest; every downloaded .deb is verified against it. On any mismatch it aborts before the install step (no partial install).
  2. Temp-directory isolation — all downloads land in a mktemp working directory that a trap removes automatically on success, failure, or interrupt. Nothing is left on your system.
  3. apt transaction — installation uses apt install, not dpkg -i, so even external runtime dependencies are resolved inside apt's atomic transaction; a failure leaves no partial install.
  4. Fully public script — the script is published verbatim on the main branch. You can download it first with curl ... -o install.sh and read it before running.

Limitation: because SHA256SUMS lives at the same origin (GitHub Releases) as the .debs, transfer integrity is guaranteed but origin authenticity relies on trusting GitHub's TLS. GPG/minisign signing is future work. For minimal trust, use Method 2 (manual download) and verify each file yourself.


Q10. Migration notes from 0.1.x to 0.2.0?

Mostly automatic. Two normalizations:

C API: UnimEnglishLayout / UnimKoreanLayout enums removed → setters/getters now take/return C strings. Affects only C/C++ clients.

Full migration: changelog 0.2.0.


Q11. Does UNIM run on macOS / Windows?

Windows: yes. macOS: not yet.

As of v0.4.0, Windows 10/11 (64-bit) is supported via unim-tsf, built on the Text Services Framework (TSF).

irm https://raw.githubusercontent.com/from104/unim/main/install.ps1 | iex

downloads and installs the MSI (see user manual §2.1 Install). 32-bit apps are handled by a separate 32-bit TSF TIP (unim_tsf32.dll) rather than the 64-bit TSF path. The IMM32 fallback explored earlier (the unim-imm32 crate) remains only as diagnostic/research source that is not included in the shipped MSI — if you've seen documentation advertising an "IMM32 fallback" as a shipped feature, it's out of date.

The Windows side is in daily production use on the maintainer's machine and is refined from that use, but it has not been through the same breadth of machines and applications as Linux. If you hit a problem, please report it on GitHub Issues with the app name and your Windows version (winver).

macOS is still not started (roadmap stage 5). Because the Rust core and C-API are separated, in principle an adapter for macOS's IMKit is feasible, but nobody has started it yet. Volunteers welcome.


Q12. Why does the build need cargo 1.95?

Cargo.lock is in v4 format. cargo 1.83+ handles it safely (1.95 is the version we verify). Some distros ship /usr/bin/cargo as 1.75; explicitly use rustup:

rustup update stable
which cargo                  # should be ~/.cargo/bin/cargo
cargo --version              # 1.95.0+

The error lock file version 4 requires '-Znext-lockfile-bump' is always this issue.


Q13. I'd like to contribute — where to start?

  1. CONTRIBUTING.md — branch/PR workflow.
  2. AGENTS.md — architecture and component map.
  3. IME_BEHAVIOR.md — behavior spec.
  4. Per-crate SPEC.md.
  5. Verify: make build warning-free + cargo test --workspace all pass.
  6. Convention: commit messages in English, docs in Korean.

good-first-issue labels are the best entry point.


Q14. Why "Universal" in the name?

Universal Next-generation Input Method. Although it is a Korean IME, "universal" stands for (a) bidirectional Korean ↔ English handling and (b) one core plugged into every toolkit. In the long term, also macOS/Windows (roadmap stage 5).



Q15. What is the difference between Ahnmatae and Moachigi?

Ahnmatae (안마태) is a specific keyboard layout. Finalized in 2003, it is a three-beol (sebeolsik) style layout with fixed cho/jung/jong regions mapped to distinct keyboard zones. In UNIM it ships as the ko_3bul_anmatae built-in profile.

Moachigi (모아치기, "gather-and-strike") is an input method. Multiple jamo pressed simultaneously or within a short window are combined into a single syllable. Unlike ordinary dubeolsik/sebeolsik which process one key at a time, moachigi collects all keys within the chord window (default 60 ms) and resolves them at expiry.

In UNIM 0.3.0, Ahnmatae is the first built-in layout that supports moachigi. The moachigi settings group in the GTK settings dialog appears only when the selected layout has supports_moachigi=true.


Q16. How do I diagnose a missing popup-service?

First check whether unim-popup-service is available on the bus:

busctl --user introspect org.atit.unim.PopupService /org/atit/unim/popup

No response means the package is not installed or the D-Bus service file is missing. See troubleshooting §16 for the full diagnosis flow.


Q17. Will my settings survive a deb to rpm (or rpm to deb) migration?

Yes. All user data lives under ~/.config/unim/ and is independent of the package format:

Uninstalling one package format and installing the other leaves these files untouched. Note that the unim-gui-qt package was removed in 0.3.0 — the tray icon, settings window, and popup renderer are now split between unim-desktop (indicator + legacy settings dialog + unim-popup-service, bundled together) and unim-settings (the Slint settings app). For the current full list of 11 packages, check debian/control or dpkg -l 'unim*'.


Q19. Is there a tool to view, edit, or practice keyboard layouts?

Two GTK4 companion tools ship alongside UNIM.

Both tools share the same five-row keyboard widget, so the layout looks consistent across them. For shortcuts see user manual §5.6.


Q18. What is the right chord_window_ms value?

Valid range: 10–200 ms. Default: 60 ms (tuned for experienced typists).

ProfileRecommended rangeNotes
Beginner100–150 msChord timing still inconsistent; extra window prevents missed chords
General60–100 msComfortable for most users
Expert10–60 msMinimize false positives, maximize responsiveness

Set to 0 to disable moachigi entirely.

🐧 Linux — adjust via the settings dialog slider or:

unim-cli config set korean-chord-window-ms 80

Q20. When I hold a key too long, the same letter is typed several times.

If you hold a key down (e.g. because of a tremor), the OS re-fires the same key rapidly (auto-repeat). UNIM has a Suppress Composition Key Auto-repeat (accessibility) option that makes the daemon ignore those repeats. Suppression applies to the Korean/English toggle key and character keys in Korean mode; repeats of editing keys (Backspace, arrows) and direct English typing are left alone. The default is off, so nothing changes until you enable it.

🐧 Linux

To enable it — the Accessibility → Suppress Composition Key Auto-repeat switch in the settings app, or the CLI:

unim-cli config set ignore-key-repeat true

Fallback limits: Wayland, Qt5/6, and the GNOME extension detect repeats precisely. The GTK3/4, XIM, and ibus-compatible paths approximate with an 80 ms time window, so (1) the first repeat may slip through, and (2) if your system key-repeat interval is set longer than 80 ms, repeats may not be filtered. In either case, when in doubt it errs toward suppressing less (fail-safe). GNOME extension users: applies after re-login.


Q21. Password fields in Chrome/Chromium are not being auto-protected. Why?

Chrome does not report input field types to the input method, so UNIM cannot auto-detect them.

Diagnosis by cause

1. Wayland Chrome (native, --enable-wayland-ime not enabled)

By default, Chrome does not use the Wayland input method protocol (input-method-v2). You must enable the flag explicitly.

Solutions:

After enabling the flag and restarting Chrome, UNIM will detect password fields.

2. X11 Chrome / Chromium

The Chromium engine does not report input field types to the input method even on X11. This is a design choice in Chromium that UNIM cannot override. Manually verify English mode by pressing the Hangul/Korean toggle key before entering the password.

Alternative: Firefox reports field info to the input method, so detection works correctly.


Q22. XIM environments: why doesn't password-field auto-detection work?

The XIM protocol itself has no way to convey input field semantics.

XIM (X Input Method) is a legacy protocol from 1994 with no facility to signal field types like "password". Your options:

  1. Manual English mode check — before entering a password field, press Hangul/Korean to verify English mode.
  2. Switch to GTK/Qt apps — migrate from XIM-only legacy apps to modern GTK/Qt equivalents (e.g., gvim → vim-gtk / nvim-qt).
  3. Try an alternative input path — for command-line use, also enable the ibus-compat path and test.

Q23. I removed UNIM and now Korean/English toggling doesn't work at all — how do I go back to another IME?

Removing UNIM does not automatically restore the system IME setting. If you removed IBus with sudo apt remove ibus while installing UNIM (as Q2 recommends), the "current IME = unim" setting made by im-config -n unim (or by enabling the GNOME+Wayland extension) survives even after you remove the UNIM package. Log back in after that and you're left with run_im unim pointing at a binary that no longer exists — no IME starts at all, and Korean/English toggling stops working entirely.

Switch back to another IME before removing UNIM.

# Example: install ibus-hangul first if you want to go back to it
sudo apt install ibus ibus-hangul

# Point im-config back
im-config -n ibus
# Or let it auto-pick from what's installed
im-config -n auto

# Now remove UNIM (all packages at once — shell glob)
sudo apt remove 'unim*'

If you already removed it and Korean input is completely broken

  1. Run im-config -n auto to auto-reassign to whatever IME is installed. If nothing is installed, sudo apt install ibus ibus-hangul first, then rerun it.
  2. Check ~/.xinputrc directly — if run_im unim is still there, delete it or replace it with another IME's name (on a GNOME+Wayland session this file may not be used at all — see user manual §2.2).
  3. Log out and back in.

This removal/rollback path is managed by Debian/Ubuntu's im-config framework, not by UNIM's package scripts, so UNIM cannot automatically revert it. The manual steps above are currently the only recovery path.


Read more

▲ Back to contents

UNIM Troubleshooting (English)

UNIM 0.4.0 — organized as Symptom → first diagnosis → second-level command → fix. Covers 14 commonly seen symptoms, from "Korean never types" to "broken in one specific app".

🐧 Linux

Every diagnosis starts with two questions: is the daemon alive? and what does the log say?

# (1) Is the daemon alive?
systemctl --user status unim-daemon
# Or PID check
unim-daemon --check && echo "RUNNING" || echo "STOPPED"

# (2) Turn on debug logging and reproduce
UNIM_DEVELOP=1 systemctl --user restart unim-daemon
> ~/.unim-errors.log    # truncate
# … reproduce the bug …
tail -f ~/.unim-errors.log

UNIM_DEVELOP=1 aggregates Engine/DBus/Frontend/Extension logs into a single file (~/.unim-errors.log). The default is OFF so the log file does not grow unbounded.


1. "Korean never types" — fresh install

🐧 Linux

First diagnosis

echo $GTK_IM_MODULE      # should be: unim
echo $QT_IM_MODULE       # should be: unim
echo $XMODIFIERS         # should be: @im=unim
unim-daemon --check && echo OK || echo MISSING

Cause-by-cause fix

SymptomCauseFix
Env vars emptyim-config not configuredim-config -n unim, then log out/in
unim-daemon --check → MISSINGSystemd unit not enabledsystemctl --user enable --now unim-daemon
Visible in shell, not in GUI appsDisplay manager did not load envexport in ~/.xprofile or /etc/environment
GNOME+WaylandEnv-var path is deadUse gnome-extensions enable unim-gnome@from104.github.io instead

🐧 Linux — §2–§4 cover the Linux frontends (GTK / Qt / GNOME extension) only.

2. "Broken only in GTK apps (GNOME Text Editor, etc.)"

Diagnosis

ls /usr/lib/x86_64-linux-gnu/gtk-3.0/3.0.0/immodules/im-unim.so 2>/dev/null
ls /usr/lib/x86_64-linux-gnu/gtk-4.0/4.0.0/immodules/libim-unim.so 2>/dev/null

sudo gtk-query-immodules-3.0 --update-cache
sudo gtk-query-immodules-4.0 --update-cache

Fix

Tip: GTK_IM_MODULE_FILE=/usr/lib/.../immodules.cache GTK_IM_MODULE=unim gnome-text-editor shows module-load errors on stderr.


3. "Broken only in Qt apps (Kate, Krita)"

Diagnosis

ls /usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/libunimplatforminputcontextplugin.so
ls /usr/lib/x86_64-linux-gnu/qt6/plugins/platforminputcontexts/libunimplatforminputcontextplugin.so
QT_DEBUG_PLUGINS=1 kate 2>&1 | grep -i unim

Fix


4. "GNOME extension not in the menu"

Diagnosis

gnome-extensions list | grep unim
gnome-extensions info unim-gnome@from104.github.io
journalctl --user -u gnome-shell -b | grep -i unim

Fix


5. "Hanja popup never appears"

🐧 Linux

Diagnosis

# Is the popup renderer alive? (X11/KDE/Xfce — if not, see §16)
pgrep -a unim-popup
# On GNOME Wayland, is the extension enabled?
gnome-extensions list --enabled | grep unim

# Are DBus signals being emitted? (in a separate terminal)
busctl --user monitor org.atit.unim.InputMethod
# Then type Korean and press Hanja → ShowHanjaPopup signal should appear

Fix

EnvironmentPopup renderer (0.3.0+)Note
GNOME+WaylandGNOME extension popup_view.js (St widget)Extension receives PopupRender and paints directly
GNOME X11 / KDE / Xfce / X11 WMunim-popup-service (GTK4)Auto-launched via D-Bus activation
Wayland (KDE Plasma 6 / Sway, etc.)unim-popup-service (GTK4, wayland-backend)Needs libgtk4-layer-shell, experimental — see popup spec §12

Since 0.3.0, IM modules no longer draw their own popups. Rendering of the hanja / special-char / emoji popups is centralized in unim-popup-service (or the GNOME extension). Diagnosis therefore checks whether the renderer process is alive, not popup_mode.

DBus dead?: busctl --user list | grep atit — if empty, the daemon failed to register. Check journalctl --user -u unim-daemon -n 100.


6. "Special-character popup never appears"

Same code path as Hanja popup, so the cause is similar.

🐧 Linux — There is no CLI key to query the current input mode (Korean/English) — check via the tray icon or the GNOME extension indicator instead.

Type one consonant (ㄱ–ㅎ) while in Korean mode, then press Hanja.

Works cleanly on Dubeolsik; on Sebeolsik the consonant entry is different.


7. "Hanja popup shows only 9 cells, period toggle does nothing"

🐧 Linux

Diagnosis

UNIM_DEVELOP=1 systemctl --user restart unim-daemon
# Open the Hanja popup, hit `.`, then:
grep -i 'ToggleExpanded\|9x9\|expanded' ~/.unim-errors.log

Fix


🐧 Linux — §7-1 and §7-2 are Linux-only symptoms (Wayland compositors / XIM).

7-1. "Wayland popup shows ◀/▶ buttons but mouse clicks do nothing"

Symptom

On unim-frontends/wayland popups (compositors: GNOME mutter, KWin, Sway, etc.) the ◀/▶ buttons render correctly but a mouse left-click on them produces no reaction.

Cause

Wayland popups are drawn on zwp_input_popup_surface_v2. For pointer events to reach this surface, the compositor must route them into the IM popup. Some compositors (notably some GNOME mutter versions) treat the IM popup as pass-through, so the click falls through to the application below.

Fix

Keyboard ←/→ is guaranteed across every compositor. Mouse ◀/▶ is best-effort, gated by compositor policy.


7-2. "XIM emoji popup shows ◀/▶ alongside category tabs"

Symptom

In XIM (unim-frontends/xim) the emoji popup shows category tabs (smileys, animals, food, …) along the top and ◀/▶ paginate buttons at the bottom. Both react to left-click, which can be confusing.

Cause / status

Working as intended. The XIM emoji popup has two distinct controls: (1) category tabs along the top (left-click switches category), (2) ◀/▶ in the footer (left-click moves one page within the active category). Both use left-click but they live in different regions.

Fix

The behavior is intended but visually under-separated. Tracked for a footer color tweak in a future release.


8. "AutoTypeFix not firing"

Diagnosis

🐧 Linux

unim-cli config show | grep -i typefix         # master/forward/reverse enabled state
cat ~/.config/unim/typefix-blacklist.yaml | head -50

Fix


8-1. "AutoTypeFix fires in a password field"

Cause

Password protection (FAQ Q9) works only when the app reports "this field is a password" (content_purpose). The environments below cannot deliver that signal to UNIM, so the password field is treated as a normal field.

EnvironmentStatusReason
GTK3/4, Qt5/6, GNOME extension, Windows TSF (both 64-bit and 32-bit unim_tsf32.dll)Detectedcontent_purpose / InputScope delivered correctly
Legacy XIM appsNot detectedXIM protocol has no such signal
Some Wayland compositors / web formsNot detectedcontent-purpose not sent (app/compositor's discretion)
GTK apps that change purpose after focusNot detectedThe GTK IM reads input-purpose only at focus time and does not subscribe to notify::input-purpose (existing limitation) — if the same field later becomes a password, it is not reflected until re-focus

This table is still sparse — reports are wanted. Which applications report password fields correctly and which do not can only be filled in from real-world use. On Linux and Windows alike there are not enough cases yet, so per-application handling is incomplete. If you find an app where correction fires inside a password field, please report the app name and version on GitHub Issues. That is the only way this table gets filled in.

Fix

preedit-exposure — tracked separately: In a password field, Korean composition itself is blocked, so a character briefly showing as preedit (underline) during composition is essentially absent in the correctly-detected environments. In the undetectable Wayland environments above, exposure could occur in theory; this is tracked as a separate issue, and the current recommended workaround is "verify English mode manually" above.


9. "AutoTypeFix corrects too aggressively / wrongly"

Fix

🐧 Linux

CaseFix
One specific wordBS + Hangul to roll back → next time the same word triggers, it auto-registers as Tentative
Frequent regretsSettings → "Type Correction" → bump tentative-expiry hours
Reverse fires in English modeTurn ON auto_typefix.reverse.skip_incomplete_syllable
Hand-editOpen ~/.config/unim/typefix-blacklist.yaml — daemon hot-reloads on mtime change

10. "Settings won't save / changes don't take effect"

🐧 Linux

Diagnosis

ls -la ~/.config/unim/
test -w ~/.config/unim/config.yaml && echo writable || echo BLOCKED
unim-cli config show 2>&1 | head -5
journalctl --user -u unim-daemon -n 50

Fix


🐧 Linux — §11–§14 are Linux-only. Windows has no GTK IM module, no Flatpak, no Snap, and no resident daemon.

11. "Keys are locked (ghostty/terminal)"

Symptom: after one keystroke, the terminal freezes IME-wise.

Cause

Missing preedit-end signal in GTK3/4 IM (a 0.1.x leftover; resolved in 0.2.0 via the unim_emit_preedit helper).

Fix

unim-cli --version       # 0.2.0+ contains the fix

If 0.1.x, rebuild and reinstall: make build && sudo make install.


12. "Korean broken in Flatpak apps (Telegram, VS Code)"

Diagnosis

flatpak list --columns=application,environment | grep -E 'GTK_IM|QT_IM'

Fix

On GNOME+Wayland, the host's IM env vars leak into the Flatpak sandbox and block input. Auto-handling should clear them.

# Verify auto-handling worked
journalctl --user -u unim-daemon | grep -i flatpak
# These two lines mean OK:
#   [Flatpak] GNOME+Wayland detected — applying Flatpak IM override
#   [Flatpak] IM environment override done

# Manual fallback
flatpak override --user --env=QT_IM_MODULE= --env=GTK_IM_MODULE=
flatpak kill org.telegram.desktop

On X11 or non-GNOME you actually need to keep the env vars — auto-handling fires only on GNOME+Wayland.

⚠️ Persists after uninstalling UNIM: this override is written permanently to your per-user ~/.local/share/flatpak/overrides/global file and is not reverted automatically when the unim package is removed. If you switch to another input method and Flatpak apps start misbehaving, unset it yourself:

flatpak override --user --unset-env=QT_IM_MODULE --unset-env=GTK_IM_MODULE

13. "Korean broken in Snap apps"

Snap inherits host env vars but offers no global-override mechanism.

Fix

Conditional export in ~/.profile:

if [ "$XDG_SESSION_TYPE" = "wayland" ] && echo "$XDG_CURRENT_DESKTOP" | grep -q "GNOME"; then
    export GTK_IM_MODULE=
    export QT_IM_MODULE=
else
    export GTK_IM_MODULE=unim
    export QT_IM_MODULE=unim
fi
export XMODIFIERS="@im=unim"

Or per-launch:

QT_IM_MODULE= GTK_IM_MODULE= snap run telegram-desktop

14. "Daemon eats too much memory (RSS 500 MB+)"

Diagnosis

grep -E 'VmRSS|VmData|Threads' /proc/$(pidof unim-daemon)/status
cat /proc/$(pidof unim-daemon)/smaps_rollup | grep -E 'Rss|Anonymous'

Fix

UNIM 0.2.0 ships with tikv_jemallocator + MALLOC_ARENA_MAX=2 + a 60-second malloc_trim(0) task, which keeps RSS in the low MB. If you still cross 500 MB:

# Quick recovery
systemctl --user restart unim-daemon

# Diagnostics for an issue report
ps -o pid,rss,vsz,cmd $(pidof unim-daemon)
journalctl --user -u unim-daemon -n 500 > unim-mem.log

AGENTS.md §Memory rules lists the regression-banned items and diagnostic commands.


15. "Moachigi (chord) not recognized correctly"

Chord input failures have several possible causes. Work through the items below in order.

15-1. The active layout does not support moachigi

Chord input is only available for layouts that carry supports_moachigi: true. Among the built-ins, only the Ahnmatae layout (ko_3bul_anmatae) qualifies. Qwerty Sebeolsik v2 is preserved as a research reference (docs/references/keymaps/ko_3bul_qwerty_v2.json); copy it into your user layout folder to enable it as a moachigi-capable user profile.

The user layout folder is ~/.config/unim/layouts/ — copy the file to ~/.config/unim/layouts/ko_3bul_qwerty.json.

# Check the active layout
unim-cli config show | grep -E 'layout|keymap'

If the active layout is not moachigi-capable, switch to one in the GTK settings dialog. The Moachigi option group appears automatically once a compatible layout is selected.

15-2. chord_window_ms is too short

The recommended default for chord_window_ms is 60 ms. If you are new to moachigi or type at a moderate pace, start at 80–100 ms and lower the value as you become comfortable.

# Check current setting
unim-cli config show | grep chord-window

# Set to 80 ms
unim-cli config set korean-chord-window-ms 80

Alternatively, use the settings app (unim-settings) → General page → layout options (shown only for chord-capable layouts) → slider.

15-3. bidirectional_combine is off

If reverse-order jamo combinations do not work (e.g., ᆯ+ᆨ → ᆰ, or ㅎ+ㄱ → ㅋ), the Bidirectional Jamo Combine option is disabled.

# Check current state
unim-cli config show | grep bidirectional-combine

# Enable
unim-cli config set korean-bidirectional-combine true

Or in the settings app (unim-settings) → General page → layout options → Bidirectional Jamo Combine toggle → ON.

15-4. Keyboard does not support NKRO (ghosting)

Standard membrane keyboards are limited to 2–3 KRO (Key Rollover). When more keys are pressed simultaneously than the keyboard can report, the extras are silently dropped — this is called ghosting. Symptoms include chords that are consistently incomplete or produce the wrong jamo.

Self-diagnosis:

# Check simultaneous key events on X11
xev -event keyboard

On Wayland, use wev instead of xev (apt install wev or equivalent).

Focus the window that appears, then press all keys in your chord at once. The terminal must print one KeyPress event per key. You can also use an online key tester such as keyboardchecker.com.

Fix: use a gaming keyboard or a mechanical keyboard in NKRO mode. See Ahnmatae keyboard guide — Keyboard Compatibility for details.

15-5. Low USB polling rate (125 Hz = 8 ms resolution)

The default USB polling rate is 125 Hz (one report every 8 ms). If chord_window_ms is set to 10–30 ms, the polling interval itself occupies most of the window, causing some chord keys to be missed.

Fix:


Build failure

🐧 Linux

make clean
make build 2>&1 | tee /tmp/unim-build.log
ErrorCauseFix
lock file version 4 requires '-Znext-lockfile-bump'cargo 1.75 (old)rustup update stable to get cargo 1.95+
gtk4/libadwaita not foundDev headers missingsudo apt install libgtk-4-dev libadwaita-1-dev
Qt6Core not foundQt6 dev missingsudo apt install qt6-base-dev
cxx-qt build errorQt header path mismatchInspect pkg-config --cflags Qt6Core
Any warningsUNIM enforces zero-warningFile the warning verbatim as an issue

The canonical build command is make build. cargo build --workspace alone misses the C/C++ frontends.


Diagnostic bundle (for issue reports)

🐧 Linux

{
  echo "=== version ==="
  unim-cli --version
  echo "=== env ==="
  echo "session=$XDG_SESSION_TYPE"
  echo "desktop=$XDG_CURRENT_DESKTOP"
  env | grep -E 'GTK_IM|QT_IM|XMOD' | sort
  echo "=== daemon ==="
  systemctl --user status unim-daemon --no-pager
  echo "=== config ==="
  unim-cli config show
  echo "=== logs (last 200) ==="
  tail -n 200 ~/.unim-errors.log 2>/dev/null
} > unim-report.txt

Attach unim-report.txt to your issue. Skim it once first — passwords/tokens are unlikely to be in the log, but a quick check is wise.


Read more


🐧 Linux — §16 and the 0.2.0 release notes below are Linux-only.

16. popup-service debugging (0.3.0+)

"Hanja / special-character / emoji popup never appears" (GNOME X11 or KDE/Xfce)

Since 0.3.0, all popups are rendered exclusively by unim-popup-service. Even if the daemon is running, popups will not appear if popup-service is not available.

Diagnostic commands
# Check whether popup-service process is running
pgrep -a unim-popup

# Verify the DBus interface is exposed
busctl --user introspect org.atit.unim.PopupService /org/atit/unim/popup

# Check that the D-Bus service activation file is installed
ls ~/.local/share/dbus-1/services/org.atit.unim.PopupService.service \
   /usr/share/dbus-1/services/org.atit.unim.PopupService.service 2>/dev/null
Fixes

"Popup closes immediately when I click it"

Clicking outside the popup is intentional dismiss behavior — the popup closes and the click event is passed through to the window underneath. Clicking inside a cell or button should not close the popup. If clicking inside the popup dismisses it, the popup position or size is being calculated incorrectly; check the DBus caret coordinates (caret_rect).

"Two popups appear at once on GNOME Wayland"

Meta.is_wayland_compositor() detection has failed, causing both the extension PopupView and the popup-service GTK4 window to render simultaneously. Check your GNOME Shell version, then disable and re-enable the unim-gnome@from104.github.io extension.

"The character after a commit does not show up (XIM)"

Right after a syllable is committed, the next jamo you type does not appear on screen. Open since 0.3.0, and the status now differs by path.

Fixed (2026-08-07) — for self-hosted XIM clients and OVER-THE-SPOT clients (XTerm, WezTerm). The cause was not what this page previously claimed (the xim crate's commit() not updating preedit_started) — removing that workaround entirely left the symptom unchanged. The real cause is that ON-THE-SPOT clients stop processing messages once they hit Commit while handling a key, so a new preedit sent after the commit was discarded. XIM now sends the preedit before the commit; see the exception in docs/dev/architecture/IME_BEHAVIOR.md §8.1.

Still open (confirmed 2026-08-10) — when GTK attaches through its XIM module (im-xim), the symptom remains and the cause is different. There the input method stalls right after the commit, so the next character is swallowed for several seconds (libX11 recovers on its own after a timeout). Sending PreeditDraw is what wedges that input context: it stops receiving further keys. Reproduces 3/3.

Progress is tracked in ROADMAP phase 3, "Sandboxed apps (Flatpak/Snap) input path".


0.2.0 release-specific notes

Auxiliary diagnostics drafted by manual-test-planner just before the 0.2.0 release. The user-facing sections above (§1–§14) take precedence; this section keeps only supplementary diagnostic tools and regression-watch items.

A. Diagnostic helpers

CommandPurpose
journalctl --user -u unim -b --no-pagerDaemon systemd logs (this boot)
: > ~/.unim-errors.log; UNIM_DEVELOP=1 /usr/libexec/unim-daemon -n --replace &Reset log + restart in dev mode
pgrep -a unim-All unim-* processes
busctl --user introspect org.atit.unim.InputMethod /org/atit/unim/InputMethodDBus API surface

B. 0.2.0 regression-watch cases

C. Multiple daemon instances

D. Hanja popup coordinates

E. CLI Korean text renders garbled

F. unim-cli config set doesn't show up in the GUI

G. Environment matrix (reconfirmed for 0.4.0 — originally written for 0.3.0)

EnvironmentSupportNotes
GNOME Wayland✅ ValidatedGNOME extension popup_view.js (St widgets) renders popups directly
GNOME X11✅ Validatedpopup-service GTK4 + GNOME extension assist
X11 + KDE Plasma 5.x✅ Validatedpopup-service GTK4
X11 + XFCE / MATE / Cinnamon / LXDE✅ Validatedpopup-service GTK4
Wayland + KDE Plasma 5.x❌ Unsupportedgtk4-layer-shell missing in Ubuntu 24.04 (noble) standard repos → use X11 session or GNOME
Wayland + KDE Plasma 6⚠️ ExperimentalRequires wayland-backend feature + libgtk4-layer-shell. Not exercised in 0.4.0 QA either (unchanged since 0.3.0)
Sway / Hyprland / river (standalone Wayland)⚠️ ExperimentalSame as above. Possible regressions in popup placement and IME focus handover
Weston etc. reference Wayland⚠️ ExperimentalSame as above

0.4.0 reconfirmation: the table above still holds as of the v0.4.0 release — pure (non-GNOME) Wayland still does not support the hanja/special-character popup in this release (a deliberate design constraint, unchanged), and Wayland compositors that don't go through GNOME remain "experimental". Windows (TSF, both 64-bit and 32-bit via unim_tsf32.dll) is a newly added experimental platform in v0.4.0 and is not included in this table — see FAQ Q11 instead.

⚠️ For issues on experimental environments, please file a bug at GitHub Issues.

H. Log-analysis slash command

# If you're using Claude Code
/unim-log

→ automatically classifies, summarizes, and diagnoses ~/.unim-errors.log.

▲ Back to contents