跳至主要内容

AppImage 裡面不能打中文

原理

因為 AppImage 幾乎都只帶 ibus 外掛,而不帶 fcitx 外掛。所以把系統的輸入法協定從 fcitx 改成 ibus 就修好了。

實際檢查 MuseScore 4.5.2 的內容:

plugins/platforminputcontexts/libcomposeplatforminputcontextplugin.so
plugins/platforminputcontexts/libibusplatforminputcontextplugin.so

只有 composeibus,沒有 fcitx。

而系統原本設定是:

GTK_IM_MODULE=fcitx
QT_IM_MODULE=fcitx

程式被叫去找 fcitx 外掛,找不到,所以輸入法完全不接,只能打英文。

而 fcitx5 其實有內建一個 ibus 前端模組。

/usr/lib/x86_64-linux-gnu/fcitx5/libibusfrontend.so

它啟動後會去佔用 org.freedesktop.IBus 這個 D-Bus 名稱,等於 fcitx5 對外「假裝自己是 ibus」。所以程式要 ibus 協定時,fcitx5 的 ibus 前端接住,就還是可以用 fcitx5 的輸入法。

改的檔案:~/.xsessionrc

在檔案最後面加上這段:

# --- Input method: route everything through fcitx5's IBus frontend ---
# AppImages bundle their own Qt/GTK without the fcitx plugin, but almost all
# of them ship the ibus one. fcitx5 owns org.freedesktop.IBus, so speaking
# "ibus" works for both bundled and system toolkits.
export XMODIFIERS=@im=fcitx
export GTK_IM_MODULE=ibus
export QT_IM_MODULE=ibus
export CLUTTER_IM_MODULE=ibus
export SDL_IM_MODULE=ibus
export GLFW_IM_MODULE=ibus

XMODIFIERS 刻意保持 @im=fcitx,那是給老式 XIM 程式用的,走另一條路,不要動它。

為什麼一定要放 ~/.xsessionrc(重要,別搬到別的地方)

X11 登入時 /etc/X11/Xsession.d/ 裡的腳本是照編號順序執行的:

40x11-common_xsessionrc ← 這一步會讀 ~/.xsessionrc(我們的設定在這)
...
70im-config_launch ← im-config 在這一步才想設定輸入法變數

70im-config_launch 裡面寫著這樣的判斷:

# If already tweaked, keep hands off :-)
if [ -z "$XMODIFIERS" ] && [ -z "$GTK_IM_MODULE" ] && [ -z "$QT_IM_MODULE" ] && ...

意思是「這些變數如果已經有人設過了,我就不插手」。

所以我們在第 40 步先設好,第 70 步 im-config 自動閃開,我們的設定會留下來。但 im-config 啟動 fcitx5 的那段程式碼在 if 判斷之外,所以 fcitx5 照常會被啟動,兩全其美。

~/.profile~/.bashrc 沒用(那些是給終端機用的,圖形程式讀不到,而且時機也不對)。放 ~/.pam_environment 也不建議(不支援註解與條件判斷,且已被 Ubuntu 淡出)。

怎麼確認有生效

環境變數只在登入時讀一次,改完一定要登出重進,不然舊值還留著。

檢查:

env | grep -E 'IM_MODULE|XMODIFIERS'

應該要看到:

GTK_IM_MODULE=ibus
QT_IM_MODULE=ibus
CLUTTER_IM_MODULE=ibus
SDL_IM_MODULE=ibus
GLFW_IM_MODULE=ibus
XMODIFIERS=@im=fcitx

檢查 fcitx5 有在跑,而且 ibus-daemon 沒有在跑:

ps -ef | grep -E 'fcitx|ibus-daemon' | grep -v grep

應該只看到 /usr/bin/fcitx5 -d 一個。如果看到 ibus-daemon,那是壞事, 它會跟 fcitx5 搶 org.freedesktop.IBus,要把它關掉。

檢查 D-Bus 名稱是被 fcitx5 佔著(最關鍵的一項):

dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply \
/org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep -iE 'ibus|fcitx'

應該同時看到 org.fcitx.Fcitx5org.freedesktop.IBus。兩個都在 = fcitx5 正在扮演 ibus 伺服器。

再看一下這個檔:

cat ~/.config/ibus/bus/*-unix-0

如果內容裡出現 fcitx_random_string=...,就百分之百確定是 fcitx5 寫的,不是真的 ibus。

檢查:直接開 AppImage 打字

隨便開一個有輸入框的,例如:

~/AppImage/MuseScore-Studio-4.5.2.251141401-x86_64_7265d111740deecd058ce7a99d0902c9.AppImage

Ctrl+Space 切輸入法,能打中文就成功。

如果不想登出、只想先試單一程式

在指令前面臨時加變數即可,不影響系統設定:

GTK_IM_MODULE=ibus QT_IM_MODULE=ibus ~/AppImage/某某.AppImage