Skip to content

Fix non-ASCII keyboard input (ä ö ü ß, AltGr €) in Blit graphical apps and terminals - #298

Open
haraldschilly wants to merge 3 commits into
mainfrom
blit-keyboard-layout-20260826
Open

Fix non-ASCII keyboard input (ä ö ü ß, AltGr €) in Blit graphical apps and terminals#298
haraldschilly wants to merge 3 commits into
mainfrom
blit-keyboard-layout-20260826

Conversation

@haraldschilly

@haraldschilly haraldschilly commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

German-layout users cannot type ä ö ü ß or AltGr+ into Blit. Investigation
found two independent causes, only one of which is ours. Full notes, with
code references for every claim, are in
src/.agents/blit-keyboard-layout-20260826.md.

1. Terminals: projects had no locale (fixed here)

Projects ran with no LANG at all. Confirmed on cocalc.ai:

$ echo "$LANG"; locale
LANG=
LC_CTYPE="POSIX"
...

In the C locale readline enables convert-meta, which mangles every multi-byte
character — the classic "umlauts don't work in a container" problem. Anything
that trusts LC_CTYPE for its input encoding fails the same way, Blit's PTYs
included.

getEnvironment() now defaults LANG to C.UTF-8, which is always present and
needs no locale generation. An image naming its own locale keeps it. The
workspace runtime was never affected — its inherited-env allowlist already
passes the locale variables through from the host, which is also why local dev
never reproduced this.

2. Graphical windows: apps silently running on X11 (partly fixed here)

Blit's compositor compiles in a single US-QWERTY XKB keymap and has no way to
change it. The browser compensates by resolving the user's layout itself and
sending printable characters as text rather than keycodes — that part works, and
e.key is "ä" as it should be. But the compositor synthesises evdev keys only
for the ASCII subset US-QWERTY can express, and routes everything else through
zwp_text_input_v3.commit_string alone
. A client that never enables an input
method drops those characters, and X11 clients cannot bind the protocol at all.

So any app that ends up on Xwayland loses all non-ASCII input. Three apps in our
catalog were on the wrong side of that line:

  • Krita and TeXstudio — likely the most consequential, because it failed
    silently. Blit exports QT_QPA_PLATFORM="wayland;xcb", and Qt falls back to
    xcb without complaint when its Wayland platform plugin is missing. Nothing
    installed one, so both ran as X11 clients despite the hint. They now pull
    qt6-wayland and qtwayland5 (both generations, since the packaged Qt
    version moves between Ubuntu releases).
  • Chromium — launched with --ozone-platform=wayland but not
    --enable-wayland-ime. Chromium binds zwp_text_input_v3 only when its
    Wayland IME support is on, so it never received a commit_string.
  • Emacs — installed emacs-gtk, the X11 build. emacs-pgtk is the same
    editor built against GTK for Wayland.

What this does not fix

IDLE, XClock, and GIMP 2.x on Ubuntu 24.04 have no Wayland build to switch
to — Tk has no Wayland backend at all. They stay broken for non-ASCII input
until Blit grows a fallback for clients without text-input.

Reported upstream as indent-com/blit#317, with the
mechanism and a suggested direction (bind a spare keycode to the needed keysym,
push the updated keymap via wl_keyboard.keymap, press, restore — the approach
xdotool/wtype use; Blit already owns the keymap bytes). We are not sending a
PR for it. No prior upstream issue existed — a search for keymap, xkb, layout,
text-input, umlaut, AltGr and plain "keyboard" returned nothing.

Also worth knowing: the launcher skips installation once an app's executable
exists, so a project that already installed Krita or TeXstudio keeps the old
package set and is not repaired by this.

Ruled out

Version skew (we pin Blit 0.55.1, effectively upstream HEAD), iframe embedding,
and a per-account keyboard-layout setting — there is nothing for such a setting
to attach to, since the keymap is compiled into the Blit binary and the browser
already applies the user's real layout.

Validation

Unit tests for both changes; pnpm tsc and lint:frontend clean.

Verified on the local Launchpad dev stack (Multipass project host, podman
runtime):

  • The locale bug reproduces locally, matching cocalc.ai exactly — inside a
    running project container, LANG is empty and LC_CTYPE="POSIX".

  • Every new package name resolves, on both Ubuntu releases, so the app
    installer cannot break on a bad name (it runs apt-get install -y under
    set -euo pipefail, where one missing package fails the whole install):

    package 24.04 26.04
    emacs-pgtk 1:29.3+1-1ubuntu2 1:30.2+1-2ubuntu1
    qt6-wayland 6.4.2-5build3 6.10.2-4
    qtwayland5 5.15.13-1 5.15.18-1

    Worth noting Krita on 24.04 is 5.2.x (Qt5) while 26.04 has 6.x — which is
    exactly why both Qt generations are listed rather than just one.

Still unverified end-to-end: that LANG actually arrives as C.UTF-8 in a
container. getEnvironment() runs in the project-host inside the VM, so proving
it live needs a project-host bundle rebuild, version pin, and reconcile. The
pre-fix state is confirmed reproduced, and the change is unit-tested.

Also unverified: the umlaut round-trip itself, which needs a browser on a German
layout typing into the Blit iframe.

German-layout users cannot type ä ö ü ß or AltGr+€ into Blit. Two independent
causes, recorded here with the code references behind each.

Graphical windows: Blit's compositor compiles in a single US-QWERTY XKB keymap
with no way to change it, so the browser resolves the user's layout itself and
sends printable characters as text rather than keycodes. The compositor
synthesises evdev keys only for the ASCII subset US-QWERTY can express and
routes everything else through zwp_text_input_v3.commit_string alone. Clients
that never enable an input method drop those characters, which upstream's own
comments state outright, and Xwayland cannot bind the protocol at all.

Terminals: a different path entirely, since Blit writes UTF-8 straight to the
PTY. Projects ran with no LANG, so the shell sat in POSIX where readline's
convert-meta mangles multi-byte input.

Also rules out version skew, iframe embedding, and a per-account keyboard-layout
setting, and records which applications each downstream fix does and does not
reach. Upstream gap filed as indent-com/blit#317.
Projects ran with no LANG at all, so every process inherited POSIX/C. Confirmed
on cocalc.ai: `locale` reports POSIX across the board with LANG and LC_ALL empty.

In the C locale readline enables convert-meta, which mangles every multi-byte
character, so a German-layout user cannot type ä ö ü ß into a terminal. Anything
else that trusts LC_CTYPE for its input encoding — Tk, Emacs, and Blit's PTYs
among them — fails the same way. This is the "umlauts don't work in a container"
problem: the Ubuntu images name no locale and nothing downstream supplied one.

Default LANG to C.UTF-8 in the project container environment. It is always
present and needs no locale generation, and an image that names its own locale
keeps it. The workspace runtime was never affected — its inherited-env allowlist
already passes LANG, LC_ALL and LC_CTYPE through from the host.
Blit's compositor advertises a single hard-coded US-QWERTY keymap and delivers
every character that keymap cannot express -- umlauts, AltGr characters --
through zwp_text_input_v3 alone. X11 clients cannot bind that protocol, so any
app that ends up on Xwayland silently drops non-ASCII input. Three apps in the
catalog were on the wrong side of that line.

Chromium was launched with --ozone-platform=wayland but not
--enable-wayland-ime, and Chromium binds zwp_text_input_v3 only when its
Wayland IME support is enabled, so it never saw a commit_string.

Emacs installed emacs-gtk, which is the X11 build. emacs-pgtk is the same
editor built against GTK for Wayland.

Krita and TeXstudio relied on the QT_QPA_PLATFORM="wayland;xcb" that Blit
exports, but Qt falls back to xcb without complaint when its Wayland platform
plugin is missing and nothing installed one -- so both ran as X11 clients
despite the hint. They now pull qt6-wayland and qtwayland5; both generations
are listed because the packaged Qt version moves between Ubuntu releases.

Projects that already installed one of these apps keep the old packages, since
the launcher skips installation once the executable exists.

IDLE, XClock, and GIMP 2.x on Ubuntu 24.04 remain X11-only with no Wayland
build to switch to; those depend on indent-com/blit#317.
@blacksmith-sh

blacksmith-sh Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Found 15 test failures on Blacksmith runners:

Failures

Test View Logs
account/tests/membership-package-manager.test.tsx/
lets admins add site-license delegates with admin user search
View Logs
admin/receivables/create.test.tsx/
previews and fresh-authenticates an explicit order submission
View Logs
admin/receivables/detail.test.tsx/
shows a friendly payment rejection inside the active modal
View Logs
Blit application launcher/runs Chromium's repository installer after confirmation View Logs
Blit application launcher/runs Chromium's repository installer after confirmation View Logs
frame-editors/x11-editor/blit-launcher.test.tsx/
runs Chromium's repository installer after confirmation
View Logs
membership package managers/
lets admins add site-license delegates with admin user search
View Logs
membership package managers/
lets admins add site-license delegates with admin user search
View Logs
membership package managers/
lets admins add site-license delegates with admin user search
View Logs
membership package managers/
lets admins add site-license delegates with admin user search
View Logs

...and 5 more test failures. View all on Blacksmith

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@haraldschilly
haraldschilly marked this pull request as ready for review August 26, 2026 15:33

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 051a58f5c6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/packages/frontend/frame-editors/x11-editor/blit-applications.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant