#223·carbonyl

Chinese text input is garbled because UTF-8 input is forwarded byte-by-byte

Author: top-mindCreated Jun 20, 2026Updated Jun 22, 2026

Also see #212

Summary

Typing Chinese characters into text fields in Carbonyl produces garbled characters instead of the expected text.

For example, when typing 你好 into a search/input field, Carbonyl displays incorrect characters. This appears to happen even when the host terminal and container locale are configured for UTF-8.

Steps to Reproduce

  1. Run Carbonyl:

    bash
    docker run --rm -ti fathyb/carbonyl https://google.com
  2. Focus the search input.

  3. Type or paste Chinese text, for example:

    你好

Expected Behavior

The input field should contain:

你好

Actual Behavior

The input field shows garbled/incorrect characters.

Environment

  • Carbonyl version: 0.0.3 / Docker image fathyb/carbonyl
  • Terminal locale: UTF-8, for example LANG=en_US.UTF-8 or LANG=C.UTF-8
  • OS / terminal:

Technical Notes

This looks like an input handling issue rather than a terminal rendering issue.

From the current source code:

  • Key.char is stored as u8
  • src/input/parser.rs emits one KeyPress per input byte
  • src/browser/bridge.rs casts the byte to c_char
  • the Chromium bridge receives OnKeyPressInput(char key)
  • the Chromium patch writes only event.text[0] = key
  • there is already a TODO(fathy): support IME near this code path

This means UTF-8 multi-byte characters such as Chinese characters are split into multiple byte-level key events instead of being submitted as Unicode/IME text.

Suggested Fix

Carbonyl likely needs a separate text input path for Unicode/IME text, distinct from key events used for arrows, shortcuts, backspace, etc.

For example:

  1. Add an input event such as TextInput(String) on the Rust side.

  2. Decode UTF-8 text from stdin/paste/IME input instead of forwarding each byte as a KeyPress.

  3. Add an FFI bridge method such as:

    cpp
    void (*text_input)(const char* utf8);
  4. In the Chromium integration, convert UTF-8 to UTF-16 and commit it as text input / IME text, rather than pretending each byte is a keyboard key.

This should allow Chinese and other non-ASCII text input to work correctly.