章節概覽#
本章快速介紹典型 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 和其他函式庫打包成更大的套件,提供統一的使用者體驗:
- 常見的桌面環境:GNOME、KDE、Xfce
- 包含主題(圖示、配置)、設計慣例文件
- 定義應用程式選單和標題的外觀,以及應用程式如何回應系統事件
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-keycodeslibinput 不只用於 Wayland,它也被 X Window System 使用。它本質上是一個捕捉 kernel 事件的系統。
14.3.3 Wayland 中的 X 相容性#
由於有大量為 X 開發的應用程式,從 X 遷移到 Wayland 需要解決相容性問題。有兩種方式:
- 原生移植:為應用程式添加 Wayland 支援。由於大部分圖形應用程式已使用 GNOME 和 KDE 的 toolkit,而這些 toolkit 已支援 Wayland,所以移植通常不困難
- 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 在系統上很容易識別,名稱為 X 或 Xorg:
Xorg -core :0 -seat seat0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch:0是 X 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,可以使用 startx 或 xinit 命令。
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
$ xwininfo14.4.4 X Events#
X client 透過 event 系統接收輸入和伺服器狀態資訊。X events 的運作方式類似其他非同步行程間通訊事件(如 udev events、D-Bus events)。
使用 xev 命令可以實驗 X events:
$ xevxev 會開啟一個視窗,當你移動滑鼠、點擊或打字時,會顯示收到的 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_socketUnix 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 上列印文件是一個多階段過程:
- 程式將文件轉換為 PostScript 格式(此步驟為可選,部分應用程式輸出 PDF)
- 程式將文件傳送到 print server
- Print server 接收文件並放入 print queue
- 輪到該文件時,print server 將文件傳送給 print filter
- 如果文件不是 PostScript 格式,print filter 可能進行轉換
- 如果印表機不理解 PostScript,printer driver 將文件轉換為印表機相容格式
- Printer driver 添加可選指令(如紙匣選擇、雙面列印)
- 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 瀏覽器為核心,移除了傳統桌面的大部分功能