章節概覽#

本章快速介紹典型 Linux 桌面系統中的各種元件。Linux 桌面領域是最多元且多彩的軟體領域之一,有大量的環境和應用程式可供選擇。

與儲存和網路等系統不同,桌面結構並不涉及層次分明的複雜架構。每個元件各自執行特定任務,並在需要時與其他元件溝通。本章重點討論兩個核心基礎設施:桌面視窗系統的核心架構,以及 D-Bus 這個行程間通訊服務。此外也簡要介紹列印系統。

14.1 桌面元件#

Linux 桌面配置提供了極大的彈性。大部分 Linux 使用者體驗的「外觀與感覺」來自各種應用程式或應用程式的建構基礎。目前 Linux 桌面的核心正處於過渡期:

  • 從一開始到最近,Linux 桌面使用 X Window System(又稱 Xorg
  • 現在許多發行版已轉向基於 Wayland 協定的視窗系統

14.1.1 Framebuffers#

Framebuffer 是所有圖形顯示機制的基礎,是一塊顯示卡硬體讀取並傳送到螢幕的記憶體區塊。

  • Framebuffer 中每幾個 byte 代表螢幕上的一個 pixel
  • 要改變畫面,就需要寫入新的值到 framebuffer 記憶體
  • 視窗系統必須解決的核心問題:如何管理多個視窗對 framebuffer 的寫入,避免互相覆蓋

14.1.2 X Window System#

X Window System 採用 client-server 架構:

  • X server 扮演桌面的「核心」角色,管理從渲染視窗到處理輸入裝置的一切事務
  • X client 程式(如終端機、瀏覽器)連接到 X server,要求繪製視窗
  • X server 決定視窗的位置與大小,並負責將圖形渲染到 framebuffer

由於 X server 作為所有事務的中介,它可能成為效能瓶頸。此外,X 包含許多不再使用的功能,其程式碼可追溯到 1980 年代。

14.1.3 Wayland#

Wayland 在設計上顯著去中心化:

  • 沒有大型顯示伺服器來管理所有 graphical client
  • 每個 client 擁有自己的記憶體緩衝區(可視為 sub-framebuffer)
  • Compositor(合成器)負責將所有 client 的緩衝區合併到螢幕的 framebuffer
  • 由於通常有硬體加速支援,compositor 的效率很高

大多數 Wayland 設置和 X server 使用 libinput 函式庫來標準化輸入事件的處理。

14.1.4 Window Managers#

Window manager(視窗管理器)決定如何在螢幕上排列視窗,是使用者體驗的核心。

  • X 中:window manager 是一個 client,作為 server 的輔助,負責繪製視窗裝飾(標題列、關閉按鈕)、處理輸入事件
  • Wayland 中:window manager 基本上就是 server,負責合成所有 client 視窗緩衝區到顯示 framebuffer,並處理輸入裝置事件

常見的 window manager 包括 Mutter(GNOME)和 Kwin(KDE),它們都已擴展支援 Wayland compositing。

14.1.5 Toolkits#

Toolkit(工具包)提供桌面應用程式常見的 UI 元素,如按鈕和選單,這些稱為 widgets

  • 在 Linux 上,GTK+ 是最常見的 toolkit
  • Qt 框架也被廣泛使用
  • Toolkit 通常由共享函式庫和支援檔案(如圖片、主題資訊)組成

14.1.6 Desktop Environments#

Desktop environment(桌面環境)將 toolkit 和其他函式庫打包成更大的套件,提供統一的使用者體驗:

  • 常見的桌面環境:GNOMEKDEXfce
  • 包含主題(圖示、配置)、設計慣例文件
  • 定義應用程式選單和標題的外觀,以及應用程式如何回應系統事件

14.1.7 Applications#

應用程式位於桌面架構的最頂層:

  • 從簡單的(如 xclock)到複雜的(如 Chrome 瀏覽器、LibreOffice 套件)
  • 應用程式通常獨立運作,但會使用行程間通訊來感知相關事件
  • 例如:當插入新儲存裝置或收到新郵件時,應用程式可以透過 D-Bus 獲得通知

14.2 判斷執行的是 Wayland 或 X#

要判斷系統使用哪個圖形系統,檢查 $WAYLAND_DISPLAY 環境變數:

echo $WAYLAND_DISPLAY
  • 如果值類似 wayland-0,代表正在執行 Wayland
  • 如果未設定,可能正在執行 X

這兩個系統不是互斥的。如果系統使用 Wayland,它很可能同時執行一個 X 相容性伺服器。也可以在 X 內啟動 Wayland compositor。

14.3 深入了解 Wayland#

Wayland 這個名稱指的是 compositing window manager 與圖形 client 程式之間的通訊協定。它不是一個大型的核心套件,而是由以下部分組成:

  • Wayland 函式庫:大多數 client 用來與協定溝通的函式庫
  • Weston:參考用的 compositing window manager,用於展示正確的實作方式,不適合日常使用

14.3.1 Compositing Window Manager#

要找出正在執行的 Wayland compositing window manager,可以追蹤它用來與 client 通訊的 Unix domain socket:

# ss -xlp | grep wayland-
  • Socket 的 display name 在 WAYLAND_DISPLAY 環境變數中,通常是 wayland-0
  • 通常位於 /run/user/<uid>/wayland-0

Wayland 系統中,視窗裝飾(如標題列)的繪製方式比較特殊。在 X 中由 window manager 全權處理,但在 Wayland 早期實作中是由 client 應用程式自行處理,導致裝飾風格不一致。現在有 XDG-Decoration 協定讓 client 與 window manager 協商由誰來繪製裝飾。

可以使用 weston-info 命令查看 compositor 的介面特性。

14.3.2 libinput#

libinput 函式庫負責從 kernel 收集輸入裝置(如鍵盤、滑鼠)的輸入,並以標準化格式傳遞給 Wayland compositor 中的適當 client。

列出可用的輸入裝置:

# libinput list-devices

監聽輸入事件:

# libinput debug-events --show-keycodes

libinput 不只用於 Wayland,它也被 X Window System 使用。它本質上是一個捕捉 kernel 事件的系統。

14.3.3 Wayland 中的 X 相容性#

由於有大量為 X 開發的應用程式,從 X 遷移到 Wayland 需要解決相容性問題。有兩種方式:

  1. 原生移植:為應用程式添加 Wayland 支援。由於大部分圖形應用程式已使用 GNOME 和 KDE 的 toolkit,而這些 toolkit 已支援 Wayland,所以移植通常不困難
  2. Xwayland 相容層:在 Wayland 中執行一個完整的 X server 作為 Wayland client。稱為 Xwayland,大多數 compositor 啟動序列都會預設執行它

不建議同時在 X 內執行 compositor。如果在 X session 中啟動 compositor,某些應用程式(GNOME、KDE 等同時支援 X 和 Wayland 的程式)可能會自動連接到 compositor 而非 X session,導致工具行為異常。最好的做法是不要同時在 X 或 compositor 中執行另一個。

14.4 深入了解 X Window System#

X Window System(http://www.x.org/)歷史上是一個非常龐大的發行套件,包含 X server、client 支援函式庫和各種 client 程式。隨著 GNOME 和 KDE 等桌面環境的出現,X 的角色已轉向專注於核心 server(管理渲染和輸入裝置)和簡化的 client 函式庫。

X server 在系統上很容易識別,名稱為 XXorg

Xorg -core :0 -seat seat0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch
  • :0X display 識別碼,代表一個或多個螢幕,共用鍵盤和滑鼠
  • 對於在 X session 下的行程,DISPLAY 環境變數會設定為此識別碼
  • X server 在 Linux 上運行於 virtual terminal,上例的 vt7 表示 /dev/tty7

14.4.1 Display Managers#

通常不會手動從命令列啟動 X server。Display manager 是啟動 X server 並顯示登入畫面的程式:

  • 常見的 display manager:gdm(GNOME)、kdm(KDE)、lightdm(跨平台)
  • 登入後,display manager 啟動一組 client,如 window manager 和 file manager

如果想從 virtual console 手動啟動 X session,可以使用 startxxinit 命令。

14.4.2 Network Transparency#

X 的一個特色是網路透通性:client 透過協定與 server 通訊,因此可以透過網路在遠端機器上執行 client,將視窗顯示在本地 X server 上。

  • X server 監聽 TCP port 6000
  • 但直接的網路連線不安全(無加密),大多數發行版已停用(使用 -nolisten tcp 選項)
  • 可以透過 SSH tunneling 安全地執行遠端 X client

Wayland 沒有簡單的遠端執行方式,因為 client 必須直接存取自己的螢幕記憶體。不過,RDP(Remote Desktop Protocol)等新興系統可以與 compositor 協作提供遠端功能。

14.4.3 探索 X Client 的方式#

可以使用以下工具從命令列探索 X Window System:

  • xwininfo:點擊視窗即可查看其位置、大小和 window ID 等資訊
  • xlsclients -l:列出所有 window ID 和 client
$ xwininfo

14.4.4 X Events#

X client 透過 event 系統接收輸入和伺服器狀態資訊。X events 的運作方式類似其他非同步行程間通訊事件(如 udev events、D-Bus events)。

使用 xev 命令可以實驗 X events:

$ xev

xev 會開啟一個視窗,當你移動滑鼠、點擊或打字時,會顯示收到的 X event 描述,包括:

  • MotionNotify:滑鼠移動事件(含座標)
  • KeyPress / KeyRelease:鍵盤事件(含 keycode)
  • LeaveNotify / FocusOut:視窗失焦事件

可以使用 xev -id <window_id> 附加到已存在的視窗來監控其事件。window ID 可從 xwininfo 取得(十六進位數字,以 0x 開頭)。

14.4.5 X 輸入與偏好設定#

X 的設定管理是其中一個最令人困惑的特性——通常有多種方式可以設定偏好,且某些方法可能不起作用。

輸入裝置(一般)

X server 使用 X Input Extension 管理來自多個裝置的輸入。兩種基本輸入裝置類型:鍵盤和滑鼠(pointer)。為處理同類多個裝置,X Input Extension 建立 virtual core 裝置來匯聚輸入。

$ xinput --list

查看特定裝置的屬性:

$ xinput --list-props 8

滑鼠

使用 xinput 可以操控滑鼠相關設定:

$ xinput --set-button-map dev 3 2 1

上述命令可反轉三鍵滑鼠的按鈕順序(適合左撇子使用者)。

鍵盤

X 的鍵盤對映使用 XKB(X keyboard extension):

  • xkbcomp 編譯鍵盤對映
  • setxkbmap 載入並啟用對映
  • 可定義部分對映來補充現有對映(例如將 CAPS LOCK 改為 CTRL)
  • 可為每個連接的鍵盤定義獨立的對映

桌面背景

X server 的桌面背景由 root window 定義。舊式的 xsetroot 命令可設定背景,但大多數桌面環境會用自己的大視窗覆蓋在 root window 之上,以啟用「動態桌布」和桌面檔案瀏覽等功能。

xset

xset 是最老的偏好設定命令,雖然已不太常用,但仍可查詢一些設定:

$ xset q

主要用途是查看 screensaver 和 DPMS(Display Power Management Signaling)設定。

14.5 D-Bus#

Desktop Bus (D-Bus) 是 Linux 桌面最重要的發展之一,是一個訊息傳遞系統(message-passing system)。

  • 作為行程間通訊機制,讓桌面應用程式互相溝通
  • 用於通知系統事件的行程(如插入 USB 裝置)
  • 核心是 dbus-daemon 這個中央「hub」,行程連接到它來註冊和接收事件

D-Bus 已超越桌面範疇成為 Linux 系統的重要組成部分。例如 systemd 和 Upstart 都有 D-Bus 通訊通道。

14.5.1 System 與 Session 實例#

有兩種 dbus-daemon 實例:

  • System instance:由 init 在開機時啟動(使用 --system 選項),以 D-Bus 使用者身份執行。設定檔為 /etc/dbus-1/system.conf,透過 /var/run/dbus/system_bus_socket Unix domain socket 連接
  • Session instance:在桌面 session 啟動時才執行,桌面應用程式連接到此實例

14.5.2 D-Bus 訊息監控#

使用 dbus-monitor 工具可觀察 D-Bus 上的事件:

監控 system instance:

# dbus-monitor --system

監控 session instance:

$ dbus-monitor --session

監控 system instance 時通常不太有活動。可以嘗試插入 USB 儲存裝置來觸發事件。Session instance 則有更多活動——嘗試使用 D-Bus 感知的桌面應用程式(如檔案管理器),會看到大量訊息。

14.6 列印#

在 Linux 上列印文件是一個多階段過程:

  1. 程式將文件轉換為 PostScript 格式(此步驟為可選,部分應用程式輸出 PDF)
  2. 程式將文件傳送到 print server
  3. Print server 接收文件並放入 print queue
  4. 輪到該文件時,print server 將文件傳送給 print filter
  5. 如果文件不是 PostScript 格式,print filter 可能進行轉換
  6. 如果印表機不理解 PostScript,printer driver 將文件轉換為印表機相容格式
  7. Printer driver 添加可選指令(如紙匣選擇、雙面列印)
  8. Print server 使用 backend 將文件傳送到印表機

PostScript 實際上是一種程式語言,列印時等於是傳送一個程式給印表機。它在 Unix-like 系統中作為列印標準,類似 .tar 格式作為歸檔標準。

14.6.1 CUPS#

CUPS(Common Unix Printing System,http://www.cups.org/)是 Linux 標準的列印系統,也是 macOS 使用的相同系統。

  • CUPS server daemon 稱為 cupsd
  • 可使用 lpr 命令作為簡單的 client 傳送檔案
  • CUPS 實作了 IPP(Internet Print Protocol),允許 client 和 server 間進行類似 HTTP 的交易,使用 TCP port 631
  • 可透過 http://localhost:631/ 查看目前配置和列印工作

設定檔通常在 /etc/cups,建議使用發行版提供的圖形設定工具來管理印表機,因為手動配置可能相當複雜。

14.6.2 格式轉換與 Print Filters#

許多印表機(尤其是低階型號)不理解 PostScript 或 PDF。CUPS 透過以下方式處理:

  • 將文件傳送給 RIP(Raster Image Processor)來產生 bitmap
  • RIP 幾乎都使用 Ghostscript (gs) 程式完成大部分工作
  • CUPS 的 printer driver 會參考 PPD(PostScript Printer Definition)檔案,取得特定印表機的設定(如解析度和紙張尺寸)

14.7 其他桌面主題#

Linux 桌面環境的一個有趣特性是,你可以自由選擇想使用的部分,並停用不喜歡的部分。

  • 各種桌面專案的郵件列表和連結可在 https://www.freedesktop.org/ 找到
  • Chromium OS 是 Linux 桌面的另一重要發展——它是 Chrome OS 的開源版本,使用了本章描述的許多桌面技術,但以 Chromium/Chrome 瀏覽器為核心,移除了傳統桌面的大部分功能