探索 X Window 服務與桌面環境:Linux 視窗 XWindow 服務、D-Bus 機制

探索 X Window 服務與桌面環境:Linux 視窗 XWindow 服務、D-Bus 機制

Overview of Content

本文將以概念上的方式探討顯示視窗的 X Window 服務及其相關概念,包括視窗管理器、GUI Widget 工具包、桌機環境和桌面應用的蓋念以及關係

其中也包括說明,如何在 Ubuntu 系統中取得、模擬對 XWindow 的事件、輸入

最後,討論桌面視窗、Widget... 等等事件的通訊方式 D-Bus

無論您是初學者還是資深使用者,透過本文您將了解 X Window 服務的運作原理和桌面環境的核心功能

寫文章分享不易,如有引用參考請詳註出處,如有指導、意見歡迎留言(如果覺得寫得好也請給我一些支持),感謝 😀


認識 X Window 服務

graph LR subgraph XWindow X伺服器 客戶端 支援函式庫 end

X Window 服務是由多個組件組成的服務,有分為「X 伺服器」與「X 客戶端」,並且 X Window 有以下特色

A. 目前的支援了很多個 GUI 函式庫

B. 用伺服器來管理客戶端,並作為它們(客戶端)與記憶體的仲介,由 X 伺服器端來管理記憶體,而客戶端不會真正觸碰到 記憶體

但也由於這層(X Window)隔離,導致了客戶端效能不佳

有更好的做法嗎

伺服器端使用少量記憶體管理組合視窗,而客戶端程序可以自行在顯存中繪製,這讓伺服器端的壓力變小,效能也會提升

Wayland 就是基於這種作法的新標準,它讓客戶端與組合視窗管理器透過協議通訊


視窗管理器概念:不同的是創管理器

視窗管理器

X Window System 是視窗管理器的其中一種實現,並非唯一的實現

還有許多視窗管理器的實現,像是 GNOME ShellCompiz... 等等都是獨立視窗管理器(Xfce 則是內建於整個環境之中)

視窗管理器沒有協定、標準

● X Window 客戶端不一定是視窗化系統,它可以是其他客戶端的服務提供者,或提供介面

就像前面所說的,它是一個 Clien/Server 模組,它不只為系統提供服務,也可以為其他應用提供服務,就像是系統顯示與應用顯示的中央處理處

graph BT; 視窗管理器 系統 --> 視窗管理器 其他應用 --> 視窗管理器

X 伺服器:管理、繪製元件

當談到 X 伺服器 時,通常指的是 X Window System(X11),它是一個用於圖形使用者介面(GUI)的標準和協議

Linux 桌機的設定有很大的靈活性,每種元件都可以找到各自的應用;雖然有很多元件可以使用,但這些元件仍要有共性,好方便系統統一管理,這個共性就是 X 伺服器

graph BT x --> 系統 x(X 伺服器) c1(元件 a) c2(元件 b) c3(元件 c) c1 --> x c2 --> x c3 --> x

● X Window System 是一種客戶端/伺服器(client/server)模型的系統,其中 X 伺服器是提供圖形顯示的伺服器端,而其他應用程序(例如遊覽器)則是客戶端;它要負責以下事項

管理視窗功能

X 伺服器負責管理屏幕上的視窗,包括創建、移動、調整大小和關閉視窗等功能;它提供了一個框架,使得多個應用程序可以在同一個螢幕上同時運行,並且能夠互不干擾地共享螢幕空間

顯示設定

X 伺服器處理顯示設定,例如顯示的解析度、色深和刷新率等;它允許用戶根據需要調整顯示設定,以適應不同的應用場景和硬體環境

I/O 設備的輸入(像是… 滑鼠、鍵盤)

X 伺服器負責處理來自輸入設備(例如滑鼠、鍵盤)的輸入事件;它將這些輸入事件傳遞給正在運行的應用程序,以便用戶可以通過這些輸入設備與應用程序進行互動

● X 伺服器只是伺服器不負責決定視窗的最終樣式

X 伺服器負責接收指令並繪製,還有 管理顯示,所以最終視窗的樣式是由各個使用者(訪問 X 伺服器的 Client)共同決定的;

GUI Widget 工具包

這些 GUI 元件又稱之為 Widget

工具包:工具包是一組用於創建圖形使用者介面(GUI)的元件… 像是按鈕、選單、導航 Bar... 等等(又稱為元件);Linux 最常見到的元件工具包則是 GTK+Qt 工具包

這些工具包會包含 共享函式庫、支援檔案,這使得開發人員可以更輕鬆地創建和定制 GUI 應用程序

桌機環境:聚集工具包 & 提供完整服務

桌機環境Desktop Environment

桌面環境是提供完整桌面使用體驗的軟體套件,它提供了整個桌面使用體驗,包括了工具包、窗口管理器、面板、應用程式啟動器等元素

桌機環境能提供體一的外觀,也能讓不同(GUI)元件進行溝通;而在桌機環境中的元件則須遵守對應的設計協定

GNOME、KDE、Unity、Xfce... 等等都是 Linux 桌機環境

桌機環境 與 工具包 的關係?

桌面環境是提供整個桌面使用體驗的完整軟體套件,而工具包則是用於開發和定製 GUI 應用程序的底層元件和函式庫

桌面環境依賴於工具包來提供 GUI 功能,但它們是兩個「不同層次」和「角色」的軟體組件

classDiagram class 桌機環境 { 桌機環境名稱 桌面元素 窗口管理器 面板 應用程式啟動器 文件管理器 } class 工具包 { 工具包名稱 GUI元件 函式庫 } 桌機環境 o-- 工具包 : 使用

桌面應用:基於桌面環境產生的應用軟體

桌面應用

像是「網頁遊覽器」、「終端機」、「文件管理器」、「文本編輯器」... 等等都是桌面應用… 工具包、桌面環境、桌面應用的關聯性如下圖表示

classDiagram class 桌面應用 { 應用名稱 GUI介面 功能 } class 桌機環境 { 桌機環境名稱 桌面元素 窗口管理器 面板 應用程式啟動器 文件管理器 } class 工具包 { 工具包名稱 GUI元件 函式庫 } 桌面應用 -- 桌機環境 : 運行在 桌機環境 o-- 工具包 : 使用

● 這些桌面應用都是 X 伺服器的 Client 端

一般情況下都是獨立運作,但它們也可以向有興趣的元素註冊事件,當事件發生時就可以收到通知

像是 D-Bus,當有通訊發生在 D-Bus 上時,就可以對有其有興趣的客戶發送通知(之後會介紹 D-Bus 這個角色、應用概念)

X 伺服器:服務目標、查看 X 伺服器

graph LR subgraph XWindow X伺服器 客戶端 支援函式庫 end

● XWindow 的發行版本包括 X 伺服器、客戶端、支援函式庫,不同的桌機環境會有不同的發行版;這些發行版的共同核心關注點包括「核心伺服器」和「簡化的客戶端函式庫」

A. 核心伺服器:管理繪製、輸入設備

XWindow 的核心伺服器是 X 伺服器,它負責管理「繪製」和「輸入設備」… 這意味著 X 伺服器負責處理圖形渲染、視窗管理、事件處理等工作

它提供了一個基本的框架,使得不同的客戶端應用程序可以在圖形顯示設備上運行並與用戶進行互動

B. 簡化的客戶端函式庫

為了方便開發人員開發 XWindow 客戶端應用程序,通常會提供簡化的客戶端函式庫。這些函式庫包含了一組常用的函式和工具,可以幫助開發人員更容易地創建和管理客戶端應用程序

這些函式庫通常封裝了與 X 伺服器的通信細節,提供了高層次的 API,使得開發人員可以更加方便地使用 XWindow 系統的功能

Ubuntu 中可以使用以下指令找到桌機中運行的 X 伺服器,並取得相關的訊息


ps aux | grep X

# 運行結果

root         605  0.1  2.6 431948 101548 tty7    Rsl+ Jul22  46:07 /usr/lib/xorg/Xorg 
    :0 
    -seat seat0 
    -auth /var/run/lightdm/root/:0 
    -nolisten 
    tcp 
    vt7 
    -novtswitch

我們對照 aux 執行的結果,查看運行結果的意義

參數概述說明
:0運行路徑之下,:0 是一個顯示介面(標識),可以將多個顯示器放到同一個顯示介面上
vt7X 伺服器是運行在虛擬終端,以 vt7 來說,就是執行在 /dev/tty7 伺服器上
-nolisten tcp不監聽 Port

X 伺服器的啟動、通訊概念

X 伺服器的啟動:單獨啟動 X 伺服器沒有太大意義,通常是通過 顯示管理器先啟動,再由它來啟動 X 伺服器(這樣我們 X 伺服器操控的結果才會顯得可見),以下是常見的啟動過程

A. 顯示管理器來啟動 X 伺服器

B. 顯示管理器跳出登入視窗、並登入

C. 顯示管理器啟動一系列客戶端元素,像是:視窗管理器、檔案管理器

graph LR 顯示管理器 -.-> X伺服器 subgraph XWindow X伺服器 end X伺服器 -.-> 登入視窗 --> 顯示

● 你也可以在另一個虛擬終端上 startxxinit 指令來啟動 X 伺服器

由於 X 伺服器是遵循伺服器、客戶端的協定,所以 可以透過像是 TCP 協定這種方式操作

可以讓 X 伺服器監聽某個 Port,只要客戶端連接指定的 Port 號,並通過驗證,就可以將視窗資訊發送到 X 伺服器,並顯示在遠端

graph LR subgraph XWindow X伺服器 end X伺服器 -.-> |1. 連接| Port Port -.-> |3. 下達指令| X伺服器 使用者 -.-> |2. tcp 傳送指令| Port

● 注意:

要注意,這種 tcp 通訊方式是「沒有加密」的… 所以通常 X 伺服器啟動後會使用 -nolisten 選項關閉 Port 監聽,來避免不安全操作


X Window 客戶端

與 X 伺服器溝通的就是 X 客戶端,我們可以透過以下指令來監控 X 客戶端 的執行

A. 查看指定窗的資訊


xwininfo

運行該命令後任意點擊一個視窗… 顯示的資訊中包含 Window id,該 ID 是 X 伺服器、視窗管理器用來識別的標識

B. 查訊所以視窗 ID


xlsclients -l

X 事件:嘗試觸發事件

● X 伺服器會將輸入設備的資訊,透過「非同步」程序通信,把事件(X 事件)分發給感興趣的 X 客戶端;我們可以透過以下命令來 體驗事件的分發


xev

執行該命令後,會顯示一個可監測鍵盤輸入、滑鼠移動點擊的空白視窗,當該視窗接收到輸入後就會 X 伺服器就會向該終端(X 客戶端)發送 X 事件

A. 滑鼠事件:移動,顯示座標

我們可以看到,滑鼠的移動會觸發 MotionNotify event 事件

B. 鍵盤事件:輸入,顯示字元(以下輸入 1)

我們可以看到鍵盤事件會觸發 KeyRelease event事件,「1」出現在 XLookupString gives 1 butes 中

X 輸入:通用、擴充設備

通用輸入設備

X 伺服器會使用 X 輸入擴充 來管理各種不同的設備輸入(像是上面觸發事件時使用的鍵盤、滑鼠)

X 輸入擴充

X 輸入擴充會建立一個 虛擬核心 設備(這個設備通稱被稱為 master),將所有外界的輸入訊息做匯集,再傳遞給 X 伺服器

graph TD; 輸入設備1_slave-->虛擬核心_master; 輸入設備2_slave-->虛擬核心_master; 輸入設備3_slave-->虛擬核心_master; 虛擬核心_master-->X_伺服器;

可使用以下指令查看當前設備上的輸入裝置


xinput --list    

每個設備的屬性

每個設備都有 ID 並且也有屬性,客戶端其實可以透過輸入擴充來識別出某個具體設備


# xinput --list-props <ID>

xinput --list-props 7

這些屬性都可以透過 --set-prop 再設定

● 使用 xset 命令可以快速顯示一些當前系統中的功能、狀態


xset q

認識 D-Bus 機制

D-Bus (桌機匯流排) 是桌機系統最終要的產物之一,它是一個 訊息傳遞系統可以讓不同程序之間進行通訊

D-Bus 使底層機制它可以把硬體的插入事件傳遞給有興趣的桌面程序

D-Bus 機制

D-Bus 會啟動一個守護進程 dbus-daemon (又稱為中央槽),如果需要對某個事件有興趣,可以到 dbus-daemon 註冊,就可以收到想要的事件通知


graph LR
桌面應用 -.-> |1. 註冊事件, dbus-daemon| D-Bus
硬體 --> D-Bus --> |通知| 桌面應用

D-Bus:降低核心對於系統細節的依賴

● D-Bus 在 Linux 中佔有很重要的地位,系統服務管理程序(SystemdUpstart)在使用 D-Bus 來通訊,這可以有效地降低特定的依賴性

那我們讓核心依賴於 系統服務管理程序(SystemdUpstart)可以嗎?

核心系統中加入桌機的依賴這「有違」Linux 的設計

這不符合依 賴倒置原則… 在這邊桌機的服務(SystemdUpstart)、作為實現的細節,而核心卻要依賴實作的細節,這樣會讓核心的可拓展性變低!而 D-Bus 機制就可以作為「抽象」概念,作為核心與桌機的抽象依賴

graph LR 桌面應用 -.-> |依賴| D-Bus 核心 -.-> |依賴| D-Bus

● 核心為了解決這個問題依賴問題,出現常見的以下方案(將客戶分為兩種

A. 系統實例xxx.config

它在開機時由 init 程序啟動,並帶上 --system 選項;這種實例通常作為 D-Bus 使用者來執行,並與 dbus-daemon 通訊


# 設定檔通常在以下目錄中
cat /etc/dbus-1/system.d/

# 藍牙作為 D-bus 客戶端的使用者的設定檔
cat /etc/dbus-1/system.d/bluetooth.conf

● 程序可透過 /var/run/dbus/system_bus_socket 來與該實例(底層裝置)通訊

B. 實例對話

這種客戶端只會在有需要時與 dbus-daemon 通訊

監聽 D-Bus 訊息:dbus-monitor

● 我們可以使用以下方式監聽 dbus-daemon 匯流排上的訊息

A. dbus-monitor --system

B. dbus-monitor --session:如果有任何桌面應用使用到 D-bus 就可以監聽到

以下啟動了 Chrome 遊覽器(桌面應用)


更多 Linux Shell 知識

探索 Debian 系統上的套件管理系統(PKMS 概念)| 套件倉庫

Linux 環境、服務:用戶、權限管理

Linux 環境、服務、管理

在這個主題中,你可以探索各種 Linux 環境、服務和管理相關的重要概念…

了解 Linux 組成:內核責任、GNU 工具、桌面環境 | 基礎版到發行版

在這裡,你將了解 Linux 系統的基本組成部分,包括內核、GNU 工具和桌面環境,並了解不同 Linux 發行版之間的差異

探索 X Window 服務與桌面環境:Linux 視窗 XWindow 服務、D-Bus 機制

這裡探討了 Linux 系統中 X Window 服務和 D-Bus 機制的工作原理,讓你深入了解桌面環境的背後運作方式

Linux 系統管理入門:安全性、用戶管理與權限設定指南

在這個指南中,你將學習如何管理 Linux 系統,包括安全性、用戶管理和權限設定,以確保系統的安全和有效運作

認識身份驗證與權限管理:UNIX UID、使用者驗證與 PAM | PAM 設定

這裡介紹了 UNIX 系統中的身份驗證機制和權限管理方式,包括 UNIX UID、使用者驗證和 PAM(Pluggable Authentication Modules)設定

Linux Shell 相關知識

Linux Shell 相關知識

這個主題涵蓋了各種與 Linux Shell 相關的知識,從基礎到進階都有…

Shell 基礎知識:包括 Shell 的基礎使用以及差異,還有變數以及計算

認識命令行:Shell 類型、命令差異 | Sub Shell 關係 | Builtin 命令

這裡介紹了命令行中不同類型的 Shell,以及各種 Shell 命令之間的區別和內建命令的用法

Shell 全局及區域變數、特殊變數及環境變數 | Shell 啟動順序 | Array 變數

學習如何在 Shell 中使用全局變數、特殊變數和環境變數,以及如何設置和管理這些變數

探索腳本與命令:Shell 腳本的必備相關知識 | 腳本的數學運算

這裡介紹了 Shell 腳本的基本知識和常用技巧,包括如何執行腳本和進行數學運算

Shell 結構化

Shell 腳本程式中的條件語句和高級特性 | Shell 結構化 & 判斷

該篇文章是介紹結構化腳本的基礎以及特殊的高級技巧,轉著於腳本中的邏輯判斷

掌握 Bash 腳本中的迴圈與循環控制技巧 | Shell 結構化 & 循環

接著是腳本中的循環與控制的技巧,它可以讓我們在 Shell 腳本中有更多的判斷與技巧

探索 Shell 函數與腳本庫 | Shell 結構化 & 函數

這裡你將會學在到結構化腳本的重要技巧「函數」,它可以讓你建立可重複利用的腳本,以節省我們之後開發的時間

Shell 掌握參數處理與用戶輸入技巧 | Shell 結構化 &輸入互動

不可互動的腳本有時候相對無趣,這篇文章有分享如何讓腳本與使用者產生交互互動,並依照使用者輸入的參數做讀取

Shell script 進階

Shell 命令輸入與輸出指南:掌握標準文件描述符與重定向 | 臨時文件

掌控 Shell、指令的輸出輸入是成為進階使用 CLI 之人必經的一課,透過這篇文章可以了解到輸出輸入、臨時文件等等資訊

探索 Linux 訊號與後台進程管理:安排定期啟動腳本 | 運行時啟動腳本

信號可以算是 Shell 腳本與 Linux 系統之間的通訊方式,透過這個文章,我們可以了解到信號與 Shell 腳本的安排時間

Linux 硬體規劃:檔案系統、分區

Linux 硬體規劃:檔案系統、分區

最後,這個主題涵蓋了 Linux 系統中硬體結構相關的重要概念…

Shell 文件和目錄操作的常用命令和技巧 | 尋找檔案

這裡介紹了 Shell 中常用的文件和目錄操作命令,包括如何尋找文件和管理文件系統

深入探索 Linux 文件系統與硬體管理 | 分區、檔案系統、邏輯卷 | inode

學習如何管理 Linux 文件系統,包括分區、文件系統和邏輯卷等相關概念,以及文件系統中的 inode 機制

理解 Unix/Linux 設備偵測、建立 | 認識與使用 udevd | SCSI 與 Linux 核心

這裡介紹了 Unix/Linux 系統中的設備偵測和管理,包括如何使用 udevd 和 SCSI 相關的 Linux 核心知識


Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

發表迴響