2025/10/10

GNOME Terminal 啟動逾時問題

 

問題描述

當從 xterm 啟動 gnome-terminal 時,會顯示以下錯誤訊息:

Error constructing proxy for org.gnome.Terminal:/org/gnome/Terminal/Factory0: Error calling StartServiceByName for org.gnome.Terminal: Timeout was reached

雖然最終 gnome-terminal 會成功啟動,但需要等待約 25 秒的逾時時間。

原因:fcitx5 重複啟動導致的競態條件(Race Condition)

這個問題是由 im-configsystemd 雙重啟動 fcitx5 所引起的競態條件。

完整時間軸

10:33:15 - 使用者工作階段啟動(systemd --user)
10:33:17 - im-config 自動啟動 fcitx5(過早!)
10:33:17 - fcitx5 透過 D-Bus 觸發 xdg-desktop-portal
10:33:17 - xdg-desktop-portal 嘗試啟動 xdg-desktop-portal-gnome
10:33:17 - xdg-desktop-portal-gnome 啟動失敗
         - 錯誤:「graphical-session.target is inactive」
         - 錯誤:「Dependency failed for xdg-desktop-portal-gnome.service」

10:33:19 - GNOME Shell 完成啟動(2 秒後)
10:33:19 - graphical-session.target 變為 ACTIVE
10:33:19 - 如果 fcitx5 在此時啟動,portal 就能正常運作

--- 經過 84 秒 ---

10:34:43 - 使用者從 xterm 啟動 gnome-terminal
10:34:43 - gnome-terminal(GTK 應用程式)嘗試存取 xdg-desktop-portal-gnome
10:34:43 - Portal 後端仍未執行(從未從早期失敗中恢復)
10:34:43 - D-Bus 嘗試啟動 portal,但發生逾時
10:35:08 - 25 秒逾時後,terminal 仍然啟動

細節

  1. im-config 框架透過 ~/.xinputrc 設定在 X11 session 初始化時自動啟動 fcitx5
  2. fcitx5 在登入後約 2 秒時過早啟動(在 graphical-session.target 就緒前
  3. fcitx5 立即透過 D-Bus 請求 xdg-desktop-portal
  4. xdg-desktop-portal 嘗試載入 xdg-desktop-portal-gnome 後端
  5. xdg-desktop-portal-gnome.service 有嚴格的相依性:Requisite=graphical-session.target
  6. 在該時刻(10:33:17),graphical-session.target 尚未就緒
  7. 服務因未滿足的相依性而啟動失敗
  8. 2 秒後(10:33:19),graphical-session.target 變為就緒(GNOME Shell 完成載入後)
  9. Portal 服務從未重試 - 保持失敗狀態
  10. 當啟動 gnome-terminal 時,它嘗試存取 portal
  11. D-Bus 啟動在 25 秒後逾時

為什麼會有重複啟動的問題?

系統中存在兩種啟動 fcitx5 的機制

  • im-config(傳統方式):透過 ~/.xinputrc 在 X session 早期啟動
  • systemd service(現代方式):透過 fcitx5.service 在 graphical-session.target 後啟動

im-config 的啟動時機太早,導致 fcitx5 在 graphical-session.target 就緒前就請求 portal,觸發競態條件。

重點:這是一個時序問題,不是效能問題。解決方案是禁用 im-config 自動啟動,改用 systemd 服務在正確時機啟動 fcitx5。

解決方案

方案 1:正確的永久修復(推薦,已驗證有效)

步驟 1:禁用 im-config 自動啟動 fcitx5

im-config -n none

這會將 ~/.xinputrc 設定為 run_im none,停止過早啟動 fcitx5。

步驟 2:建立 systemd 使用者服務來管理 fcitx5

mkdir -p ~/.config/systemd/user

cat > ~/.config/systemd/user/fcitx5.service << 'EOF'
[Unit]
Description=Fcitx5 Input Method
Documentation=man:fcitx5(1)
PartOf=graphical-session.target
After=graphical-session.target
Wants=graphical-session.target

[Service]
Type=simple
ExecStart=/usr/bin/fcitx5
ExecStartPost=/usr/bin/dbus-update-activation-environment --systemd GTK_IM_MODULE=fcitx QT_IM_MODULE=fcitx XMODIFIERS=@im=fcitx
Restart=on-failure
RestartSec=3

[Install]
WantedBy=graphical-session.target
EOF

systemctl --user daemon-reload
systemctl --user enable fcitx5.service

說明:

  • After=graphical-session.target 確保 fcitx5 在圖形工作階段就緒後才啟動
  • ExecStartPost 設定必要的環境變數讓應用程式能使用 fcitx5
  • 這完全避免了競態條件,因為 fcitx5 會在正確的時機啟動

步驟 3:重新啟動系統

systemctl reboot

登入後,fcitx5 會在 graphical-session.target 就緒後自動啟動,gnome-terminal 將立即開啟。

方案 2:繞過 D-Bus Factory(臨時快速修復,不建議長期使用)

gnome-terminal --disable-factory

這會完全避免 D-Bus 啟動機制。可以在 ~/.bashrc 或 ~/.zshrc 中建立別名:

alias gnome-terminal='gnome-terminal --disable-factory'

缺點:會失去 terminal server 的功能,每次都會啟動新的 terminal 實例。

方案 3:等待工作階段初始化完成(暫時性緩解)

登入後等待 5 秒以上再啟動 gnome-terminal。這不是真正的解決方案,只是避開競態條件的時間窗口。

測試

套用方案 1 後(禁用 im-config 並使用 systemd 服務):

  1. 重新啟動系統
  2. 登入後檢查啟動順序:journalctl --user -b 0 | grep -E "fcitx5|graphical-session.target|xdg-desktop-portal"
  3. 應該看到:
    • graphical-session.target 先就緒
    • fcitx5.service 在之後啟動
    • xdg-desktop-portal-gnome 成功啟動
  4. 立即嘗試啟動 gnome-terminal
  5. 應該不會出現 25 秒的逾時,terminal 會立即開啟

修復前後對比

修復前(問題狀態):
10:33:17 - im-config 啟動 fcitx5 (graphical-session.target 未就緒)
10:33:17 - xdg-desktop-portal-gnome 啟動失敗
10:33:19 - graphical-session.target 就緒 (太晚了)
10:34:43 - 啟動 gnome-terminal
10:35:08 - 25 秒逾時後 terminal 才開啟
修復後(正常狀態):
13:03:34 - graphical-session.target 就緒
13:03:34 - systemd 啟動 fcitx5.service
13:03:34 - xdg-desktop-portal-gnome 成功啟動
13:03:39 - gnome-terminal 立即開啟 (無逾時)

結論

這個問題的根本原因是 im-config 和 systemd 雙重啟動機制造成的競態條件。im-config 在 X session 初始化早期就啟動 fcitx5,此時 graphical-session.target 尚未就緒,導致 fcitx5 觸發的 xdg-desktop-portal-gnome 因相依性未滿足而啟動失敗。Portal 服務從未重試,因此當 gnome-terminal 稍後嘗試使用 portal 時,就會發生 25 秒的 D-Bus 逾時。

正確的解決方案是禁用 im-config 自動啟動,改用 systemd 使用者服務在 graphical-session.target 就緒後才啟動 fcitx5。這確保了正確的啟動順序,完全避免競態條件。

系統資訊:

沒有留言:

張貼留言