Skip to content

Non-ASCII input is dropped for clients without zwp_text_input_v3, which includes every X11 app #317

Description

@haraldschilly

Summary

Any character that is not on US-QWERTY is delivered only through
zwp_text_input_v3.commit_string. Clients that do not bind and enable that
protocol receive nothing at all — the character is silently dropped, with no
key event and no visible error.

The largest group of affected clients is every X11 application, since
Xwayland does not implement zwp_text_input_v3 (X11 input methods go through
XIM/ibus inside the X world instead). With BLIT_XWAYLAND=1, an X11 app is
therefore unable to receive any non-ASCII input at all.

For a user on a non-US keyboard layout this reads as "the keyboard is half
broken": ASCII types fine, and their own language's characters do nothing.

Why this is being reported

CoCalc embeds Blit 0.55.1 to run graphical applications inside user projects.
A German-keyboard user reported that ä ö ü ß and AltGr+ do nothing in
graphical apps, while ASCII is unaffected. Tracing it led here.

We are fixing what we can on our side — steering our app catalog to
Wayland-native builds and installing Qt's Wayland platform plugin, since apps
that fall back to xcb are the ones that break. But that only covers apps that
have a Wayland build. Tk (Python's IDLE) has no Wayland backend at all, and
GIMP 2.x on Ubuntu 24.04 is GTK2/X11-only, so those remain unusable for anyone
whose alphabet is not ASCII. That part we cannot fix downstream, which is why
we are raising it here.

Mechanism (refs at 5b06f43)

  1. The compositor compiles in a single keymap —
    include_str!("../data/us-qwerty.xkb"), crates/compositor/src/imp.rs:11788
    — and hands it to every client. There is no way to change it: no env var,
    flag, or config path reaches it.

  2. Because the keymap is fixed, the browser resolves the user's real layout and
    sends printable characters as text rather than keycodes
    (sendSurfaceTextCompositorCommand::TextInput). This part works
    correctly; e.key is "ä" as it should be.

  3. CompositorCommand::TextInput synthesises evdev key sequences only for
    characters char_to_keycode can express (imp.rs:1969) — i.e. the ASCII
    subset that exists on US-QWERTY. Everything else accumulates into composed.

  4. flush_composed (imp.rs:2639) hands composed to the focused client's
    zwp_text_input_v3, and to nothing else. Its own doc comment is explicit
    about the consequence:

    Only the characters the keymap cannot express come through here, so a
    client with no enabled input method is no worse off than before: they were
    dropped then and they are dropped now.

That reasoning is sound for a client that never had the character anyway — but
it means the ASCII/non-ASCII split lands on an axis the user cannot see or
influence, and X11 clients land entirely on the wrong side of it.

Reproduction

  1. German (or any non-US) keyboard layout in the browser.
  2. BLIT_XWAYLAND=1, and an X11-only client — xterm, xclock, IDLE, or
    Ubuntu's emacs-gtk.
  3. Type ä, ö, ü, ß, or AltGr+e for .

Nothing arrives. ASCII in the same window is unaffected. The same characters
typed into a native Wayland GTK3 client, which does bind text-input-v3, work
correctly — which is the tell.

Suggested direction

The fallback that native compositors and xdotool/wtype use would fit here,
and Blit is unusually well placed for it because it already owns the keymap
bytes (keyboard_keymap_data) and is the sole source of truth for them:

When the focused client has no enabled text-input, bind a spare keycode to the
needed keysym, push the updated keymap with wl_keyboard.keymap, send the
press/release, then restore the original keymap. Xwayland picks up keymap
changes, so this reaches X11 clients — the population that currently has no
path at all.

Worth considering if you take that route: a run of characters can share one
temporary keymap using several spare keycodes rather than one reload per
character, and the restore wants to be robust against a client that takes
focus mid-sequence.

A narrower alternative would be to make the compiled-in keymap replaceable, so
a session can start with a layout matching its user. That is less general —
it does not help mixed input or an unexpected layout — but it is much smaller,
and for a single-user session it would cover most real usage.

We are not planning to send a PR for this; flagging it so you have the analysis.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions