launcher: add CLAUDE_GTK_IM_MODULE opt-in override (#571)

* launcher: add CLAUDE_GTK_IM_MODULE opt-in override (#549)

Some users hit broken IBus integration on Linux and have to wrap
every launch with `GTK_IM_MODULE=xim claude-desktop`. Forcing this
for everyone would break CJK input methods, compose keys, and
dead-key sequences (rationale in #545), so this lands as opt-in.

When `CLAUDE_GTK_IM_MODULE` is set non-empty, `setup_electron_env`
exports `GTK_IM_MODULE=$CLAUDE_GTK_IM_MODULE` before the Electron
exec and logs the override (with the prior value) to launcher.log.
Unset/empty leaves `GTK_IM_MODULE` alone — no behavior change for
users not affected by the IBus issue.

Adds a TROUBLESHOOTING.md section documenting symptoms, valid
values, the trade-off note for `xim`, and BATS coverage for the
set / unset / empty / unset-prior cases.

Closes #549. Refs #545.

Co-Authored-By: Claude <claude@anthropic.com>

* launcher: tighten CLAUDE_GTK_IM_MODULE comment and docs (#549)

Trim the in-source comment to what's not implied by the guard, drop
the underscore prefix on the local, and remove a redundant trailing
sentence + duplicated trade-off line from TROUBLESHOOTING.md. No
behavior change; all 68 BATS tests still pass.

Co-Authored-By: Claude <claude@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.com>
This commit is contained in:
Aaddrick
2026-05-05 06:58:58 -04:00
committed by GitHub
parent 3ddfb7353c
commit 023a736f1c
3 changed files with 89 additions and 0 deletions

View File

@@ -80,6 +80,44 @@ If the global hotkey (Ctrl+Alt+Space) doesn't work, ensure you're not running in
See [CONFIGURATION.md](CONFIGURATION.md) for more details on the `CLAUDE_USE_WAYLAND` environment variable.
### Keyboard Input Doesn't Work (IBus / GTK Input Method)
If typing into the chat does nothing, characters get swallowed, or
dead-key sequences (e.g. ``` `e ``` → `è`) don't compose, your GTK
input module integration with the Electron-bundled GTK is broken.
Common symptoms:
- No characters appear when typing into any text field
- The first keystroke after focus is dropped, subsequent ones work
- CJK input methods (IBus, Fcitx) not engaging
- Compose key / dead-key sequences silently drop
The fastest workaround is to switch the launcher to a different GTK
input module. Set `CLAUDE_GTK_IM_MODULE` and Claude Desktop will
propagate it as `GTK_IM_MODULE` to Electron at startup:
```bash
# Bypass IBus entirely — uses the X Input Method (XIM) protocol
CLAUDE_GTK_IM_MODULE=xim claude-desktop
# To make it persistent, export it from your shell profile:
# echo 'export CLAUDE_GTK_IM_MODULE=xim' >> ~/.profile
```
Valid values: anything your GTK installation supports (`xim`, `ibus`,
`fcitx`, `simple`, etc.). When the override is active, the launcher
logs a line to `~/.cache/claude-desktop-debian/launcher.log`:
```
GTK_IM_MODULE override: ibus -> xim (via CLAUDE_GTK_IM_MODULE)
```
**Trade-off:** `xim` is the lowest-common-denominator input module
and does not support advanced IME features like CJK candidate
windows or rich compose-key sequences. Only reach for it if your
real input method (IBus/Fcitx) is broken; if you depend on CJK or
compose, prefer fixing the IBus/Fcitx integration instead.
### AppImage Sandbox Warning
AppImages run with `--no-sandbox` due to electron's chrome-sandbox requiring root privileges for unprivileged namespace creation. This is a known limitation of AppImage format with Electron applications.

View File

@@ -315,6 +315,15 @@ setup_electron_env() {
if [[ $(_resolve_titlebar_style) != 'hidden' ]]; then
export ELECTRON_USE_SYSTEM_TITLE_BAR=1
fi
# CLAUDE_GTK_IM_MODULE: opt-in override for users hit by broken
# IBus integration on Linux (#549). Propagated to GTK_IM_MODULE
# so e.g. `xim` can be persisted without wrapping every launch.
if [[ -n ${CLAUDE_GTK_IM_MODULE:-} ]]; then
local prev="${GTK_IM_MODULE:-<unset>}"
export GTK_IM_MODULE="$CLAUDE_GTK_IM_MODULE"
log_message \
"GTK_IM_MODULE override: $prev -> $GTK_IM_MODULE (via CLAUDE_GTK_IM_MODULE)"
fi
}
#===============================================================================

View File

@@ -355,6 +355,48 @@ teardown() {
[[ $ELECTRON_USE_SYSTEM_TITLE_BAR == '1' ]]
}
@test "setup_electron_env: CLAUDE_GTK_IM_MODULE set propagates to GTK_IM_MODULE" {
setup_logging
GTK_IM_MODULE='ibus'
CLAUDE_GTK_IM_MODULE='xim'
setup_electron_env
[[ $GTK_IM_MODULE == 'xim' ]]
# Override is logged so users can verify it took effect
run cat "$log_file"
[[ $output == *'GTK_IM_MODULE override: ibus -> xim (via CLAUDE_GTK_IM_MODULE)'* ]]
}
@test "setup_electron_env: CLAUDE_GTK_IM_MODULE set logs <unset> when GTK_IM_MODULE was unset" {
setup_logging
# GTK_IM_MODULE unset by setup()
CLAUDE_GTK_IM_MODULE='xim'
setup_electron_env
[[ $GTK_IM_MODULE == 'xim' ]]
run cat "$log_file"
[[ $output == *'GTK_IM_MODULE override: <unset> -> xim (via CLAUDE_GTK_IM_MODULE)'* ]]
}
@test "setup_electron_env: CLAUDE_GTK_IM_MODULE unset leaves GTK_IM_MODULE alone" {
setup_logging
GTK_IM_MODULE='ibus'
# CLAUDE_GTK_IM_MODULE unset by setup()
setup_electron_env
[[ $GTK_IM_MODULE == 'ibus' ]]
# No override line should appear in the log
run cat "$log_file"
[[ $output != *'GTK_IM_MODULE override'* ]]
}
@test "setup_electron_env: CLAUDE_GTK_IM_MODULE empty leaves GTK_IM_MODULE alone" {
setup_logging
GTK_IM_MODULE='ibus'
CLAUDE_GTK_IM_MODULE=''
setup_electron_env
[[ $GTK_IM_MODULE == 'ibus' ]]
run cat "$log_file"
[[ $output != *'GTK_IM_MODULE override'* ]]
}
# =============================================================================
# _resolve_titlebar_style
# =============================================================================