2021年11月10日 星期三

telegram + gcin 無法輸入中文

你可能遇到這個問題, telegram 和 gcin 搭配時, 無法正常喚起 gcin 輸入中文, 在網路上找了很多資料, 改了一些環境變數之後, 沒有其他人幸運, 你還是不能使用 gcin 輸入中文, 然後找到我寫的這篇, 很遺憾, 我要說的答案是換掉 gcin, 改用 fcitx, 這個問題本身很可能出在 gcin, 在某些組合之下, telegram 就是無法搭配 gcin 使用中文輸入。在 gcin 還沒做出修改之前, 這問題可能無解。

因為軟體改版的關係, 之前找的解法在新版可能無法使用, 這是正常的情形。

另外的建議是使用該 linux 套件提供的 gcin 和 telegram, 這樣應該會比較沒問題, 可以正常使用 gcin 在 telegram 輸入中文。

我的情形是這樣, 舊版的 ubuntu 已經沒有更新 telegram, 所以我使用官網的新版 telegram, 然後 gcin 就無法輸入中文。在一陣子推測之後, 有了以下結論。

telegram + gcin 看起來應該是 telegram 在某個版本之後, 沒有用 dynamic link qt, 造成 gcin 在某種情況下無法被叫出來, 這個會有點麻煩, 但是 fcitx 不知道使用了什麼方法, 可以正確處理這個問題。

list 1. 官網 3.2.2 telegram
 1 	linux-vdso.so.1 (0x00007ffc31967000)
 2 	libgtk3-nocsd.so.0 => /usr/lib/x86_64-linux-gnu/libgtk3-nocsd.so.0 (0x00007fc1fc23e000)
 3 	libgio-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0 (0x00007fc1fbe9f000)
 4 	libgobject-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 (0x00007fc1fbc4b000)
 5 	libglib-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007fc1fb935000)
 6 	libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007fc1fb6f0000)
 7 	libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007fc1fb43c000)
 8 	libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fc1fb214000)
 9 	libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007fc1faedc000)
10 	libX11-xcb.so.1 => /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1 (0x00007fc1facda000)
11 	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc1faabb000)
12 	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc1fa8b7000)
13 	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc1fa519000)
14 	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc1fa128000)
15 	/lib64/ld-linux-x86-64.so.2 (0x00007fc1fc445000)
16 	libgmodule-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 (0x00007fc1f9f24000)
17 	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fc1f9d07000)
18 	libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fc1f9adf000)
19 	libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007fc1f98c4000)
20 	libmount.so.1 => /lib/x86_64-linux-gnu/libmount.so.1 (0x00007fc1f9670000)
21 	libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007fc1f9468000)
22 	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fc1f91f6000)
23 	libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fc1f8fc4000)
24 	libpng16.so.16 => /usr/lib/x86_64-linux-gnu/libpng16.so.16 (0x00007fc1f8d92000)
25 	libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007fc1f8b8e000)
26 	libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fc1f8988000)
27 	libblkid.so.1 => /lib/x86_64-linux-gnu/libblkid.so.1 (0x00007fc1f873b000)
28 	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fc1f8533000)
29 	libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fc1f831e000)
30 	libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007fc1f8117000)


list 1 可以看到, 從官網抓的 telegram 沒有 dynamic link qt, 可能是這個原因造成 gcin qt 模組無法正常發揮, 因為 link gcin qt 模組的 qt library 和 telegram 用的 qt library 版本可能不一樣。

list 2. linux 套件提供的 telegram
e7000)
 21 	libxcb-record.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-record.so.0 (0x00007f125c1c6000)
 22 	libxcb-screensaver.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-screensaver.so.0 (0x00007f125c1c1000)
 23 	libqrcodegencpp.so.1 => /usr/lib/x86_64-linux-gnu/libqrcodegencpp.so.1 (0x00007f125c1b1000)
 24 	libminizip.so.1 => /usr/lib/x86_64-linux-gnu/libminizip.so.1 (0x00007f125bfa5000)
 25 	liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f125bf7c000)
 26 	libQt5Network.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Network.so.5 (0x00007f125bdf2000)
 27 	libQt5Gui.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5 (0x00007f125b730000)
 28 	libQt5Core.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 (0x00007f125b1e6000)
 29 	libQt5WaylandClient.so.5 => /usr/lib/x86_64-linux-gnu/libQt5WaylandClient.so.5 (0x00007f125b0b3000)
 30 	libdbusmenu-qt5.so.2 => /usr/lib/x86_64-linux-gnu/libdbusmenu-qt5.so.2 (0x00007f125b073000)
 31 	libQt5Widgets.so.5 => /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 (0x00007f125a9e9000)
 32 	libQt5DBus.so.5 => /usr/lib/x86_64-linux-gnu/libQt5DBus.so.5 (0x00007f125a960000)
 33 	libKF5WaylandClient.so.5 => /usr/lib/x86_64-linux-gnu/libKF5WaylandClient.so.5 (0x00007f125a877000)


list 2 L31 可以看到 dynamic link 的 qt library, 所以我才推測 gcin 的問題和 qt 有關。但如果都使用 xim 的話, 不應該會有這種差異的, ref 2 有提到一些 qt 處理 xim 的問題, 也許就是這個差異。

另外有個方法就是重新編譯 telegram, 也許可以解決, 如果真的不想換掉 gcin, 那只好用 web 版本了。

linux 上還有其他輸入法架構, 我沒有接觸其他的輸入法架構, 不確定會不會也有類似問題。

ref:
  1. Ubuntu 20.04/18.04/16.04/ 安裝最新的 gcin 中文輸入的完整步驟
  2. 為什麼Linux下的輸入法如此Fxxk

2 則留言:

  1. 我在自己實現 scim 對 QT5 & flatpak 支援時學到了不少.

    ref 2 中提到, GTK+ & QT 的 IM module 會把輸入再轉發給 XIM, 雖然不是 100% 確定, 但應該不是這麼一回事. 本身 XIM 當初似乎就是因為 context switch 造成 high latency 所以 UX 不佳, 所以再這麼轉發...

    之所以不能輸入中文, 是因為少了 IM module, 一般是 `.so`, 這玩意, 在 GUI framework 啟動時, 會被找出並將如 $GTK_IM_MODULE/$QT_IM_MODULE 之類的值傳給它們, 這樣, 當有多個 IM module (多個輸入法提供的) 裝在同一系統中時, 這些 IM module 才知道是否自己應該啟用. 因此, app 的 process 中其實是運行著一個 IM 的 client, 通過如 Unix socket, DBus 之類的跟 IM server (engine 運行在其中被共享著) 溝通.

    在 QT5 中, plugin 目錄位置在
    /usr/lib/x86_64-linux-gnu/qt5/plugins/

    輸入法是屬於 QPlatformInputContextPlugin, 實現以後放在上面的子目錄中
    /usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/

    在 QT 程式啟動時一一的載入並給予機會初始並運行於跟 app 同一個 process 中, 也就是說, 在 /proc/[PID]/maps 中是能看到 IM module 的 .so 的.

    但 static build 時, QT disable 了 plugin 機制, 所以也就不會去掃這些 .so, 這麼執行 telegram 能夠看到 log
    $ QT_DEBUG_PLUGINS=1 ./Telegram
    QFactoryLoader::QFactoryLoader() ignoring "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3" since plugins are disabled in static builds

    第一行就是 IM 沒法用的答案了~

    如果 gcin 有實現 flatpak 的 IM portal, 可以考慮通過 flatpak 安裝.

    回覆刪除
    回覆
    1. 感謝說明, scim 目前還是主流輸入法之一嗎? 我自己接觸過的只有 gcin 和 fcitx, 也想過弄個簡單的 xim 輸入法, 不過資料實在不好找, 一直沒能成功。

      fcitx 不知道是怎麼辦到, 可以正常在 telegram 輸入中文。

      刪除

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。