Linux——Linux桌面概覽

Linux桌面概覽

桌面組件

爲了能協同工作,各種應用就需要有一些共性,而在幾乎所有的Linux桌面組件中,這種共性就是X服務器(即X Window系統服務器)。你可以把它想象爲桌面的“內核”,管理着窗口功能和顯示配置,並處理來自鍵盤和鼠標等設備的輸入。它是難以取代的。

X服務器只是一個服務器,它無法決定桌面的表現形式。相反,用戶界面是由X客戶端處理的。基本的X客戶端應用如終端窗口和網頁瀏覽器,會連接到X服務器,並請求它繪製窗口。這樣X服務器就會算出窗口的位置並在該位置提供圖形。X服務器也會在適當的時候將用戶輸入反饋給客戶端。

窗口管理器

X客戶端不一定是窗口化的應用,它可以是其他客戶端的服務供應者,或者提供接口功能。而窗口管理器或許是最重要的服務於客戶端的應用,因爲它負責窗口的位置安排,以及提供一些交互式裝飾(例如用於窗口移動、縮放的標題欄)。這些都是用戶體驗的核心。

窗口管理器的實現有很多種。像Mutter/GNOME Shell和Compiz之類基本上是獨立的窗口管理器,而Xfce之類則是內置於整個環境中的。大部分窗口管理器的目標都是方便用戶使用。有一些是爲了實現特別的視覺效果,或者只爲提供極簡的界面。窗口管理器一般是不會有標準的,因爲用戶的品味和需求多種多樣,而且經常變化,所以也經常誕生新的窗口管理器。

工具包

在Windows或Mac OS X這類操作系統中,供應商會提供一套通用的工具包,大多數程序員都會使用到。而
Linux最常用的則是GTK+工具包。除此之外,Qt框架等其他工具也不少見。

工具包一般會包含共享庫和支持文件,如圖像和主題信息。

桌面環境

GNOME、KDE、Unity和Xfce都是常見的Linux桌面環境。

工具包在多數桌面環境中都處在覈心位置,但要創建一個統一的桌面,環境還必須具備各種支持文件,例如圖標和配置所構成的主題。所有這些都要被描述設計協議(如應用菜單和標題如何呈現、應用對某些系統事件要做什麼反應等)的文檔捆綁在一起。

應用

桌面的頂端就是各種應用了,諸如網頁瀏覽器、終端窗口等。原始如xclock程序,複雜如Chrome瀏覽器和LibreOffice套件,都是X應用。一般情況下它們是獨立工作的,但其實它們也會使用進程間通信來響應與它們有關的事件。

X Window 系統

X Window系統(http://www.x.org/)歷來就很龐大,它基礎的發行版包括了X服務器、客戶端支持庫和各種客戶端。因爲GNOME和KDE等桌面環境的出現,X發行版的角色也一直在變換。現在它的關注點主要在覈心服務器(即管理渲染和輸入設備的部分)和簡化的客戶端庫。

X服務器的運行不難識別。它就叫X。看看進程列表,你通常會發現它以這些選項運行着:

/usr/bin/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch

這裏的:0被稱爲顯示接口,是一個標識,代表着一個或多個用鍵盤和(或)鼠標訪問的顯示器。通常,顯示接口只與單個顯示器對應,但你也可以將多個顯示器放到一個顯示接口上。使用X會話時,環境變量DISPLAY包含了顯示接口的標識。

Linux的X服務器是運行在虛擬終端的。上例的vt7參數表明了它運行在/dev/tty7之上。(一般服務器會優先選擇第一個可用的虛擬終端。)你可以在不同的虛擬終端上同時運行不同的X服務器,這樣每個服務器都會需要一個各自獨立的顯示接口標識。你可以用CTRL-ALT-FN鍵或chvt命令在不同服務器之間切換。

顯示管理器

一般你是不會從命令行啓動X服務器的,因爲這麼做不會啓動任何客戶端來連接到這個服務器,結果只會得到一個空白的屏幕。相反,通常的做法是用顯示管理器來啓動X服務器,它會在屏幕上放置一個登錄框。當你登錄之後,顯示管理器就會啓動一系列的客戶端諸如窗口管理器和文件管理器,以便你使用機器。

顯示管理器有很多種,例如gdm(用於GNOME)和kdm(用於KDE)。上例中的lightdm是一個跨平臺的顯示管理器,它能打開GNOME和KDE會話。

網絡透明性

X還有一個特性就是其網絡透明性。因爲客戶端跟服務器的溝通是遵循協議的,所以我們可以讓服務器監聽6000端口的TCP連接。也就是說,可以通過網絡來連接不同機器上的客戶端和服務器。客戶端只需通過驗證,就可將窗口信息發送給服務器。

不幸的是,這個方法是沒有加密的,所以並不安全。爲了填補這個漏洞,大多數發行版都會關閉X服務器的網絡監聽器(如上例的–nolisten tcp選項)。不過,你還是可以通過SSH管道,使用Unix域套接字讓X客戶端遠程連接X服務器。

探索X客戶端

xwininfo是最簡單的工具之一。不帶參數運行它的話,它會要你點選一個窗口:

$ xwininfo
xwininfo: Please select the window about which you
would like information by clicking the
mouse in that window.

選完之後,它就會打印出該窗口的信息列表,如位置和尺寸

xwininfo: Window id: 0x5400024 "xterm"
Absolute upper-left X: 1075
Absolute upper-left Y: 594
--snip--

注意這裏的窗口ID,它是X服務器和窗口管理器用來識別窗口的標識。xlsclients -l命令可打印出所有窗口ID的客戶端。

X事件

X客戶端通過事件系統獲取輸入和服務器狀態等信息。X事件的工作方式類似於其他異步進程間通信(如udev事件和D-Bus事件):X服務器從輸入設備等源頭獲取信息,再將它們當作事件重新分發給感興趣的X客戶端。

你可以通過運行xev命令來體驗什麼叫作事件。運行xev,就會打開一個可以打字、點擊和使用鼠標的窗口。根據你的操作,xev就會輸出X服務器接收到的事件的描述。以下是一個鼠標事件的輸出例子:

$ xev
--snip--
MotionNotify event, serial 36, synthetic NO, window 0x6800001,
root 0xbb, subw 0x0, time 43937883, (47,174), root:(1692,486),
state 0x0, is_hint 0, same_screen YES
MotionNotify event, serial 36, synthetic NO, window 0x6800001,
root 0xbb, subw 0x0, time 43937891, (43,177), root:(1688,489),
state 0x0, is_hint 0, same_screen YES

理解X輸入以及偏好設定

X最讓人困惑的地方或許是它提供多種途徑設定偏好,但不是所有的都可行。

總結起來,底層設施有以下幾點是需要關注的。
輸入設備(通用)

X服務器使用X輸入擴展來管理各種不同設備的輸入。基本的輸入設備有兩種——鍵盤和指針(鼠標)——其實你可以想用多少設備就用多少。爲了做到同時使用多個同種設備,X輸入擴展會創建一個“虛擬核心”設備,用於將輸入彙集到X服務器。

這個虛擬核心設備就被稱爲主機(master),各種接入到機器的物理設備就被稱爲從機(slave)。

查看機器上的設備配置,可用xinput --list命令:

$ xinput --list
Virtual core pointer id=2 [master pointer (3)]
Virtual core XTEST pointer id=4 [slave pointer (2)]
Logitech Unifying Device id=8 [slave pointer (2)]
Virtual core keyboard id=3 [master keyboard (2)]
Virtual core XTEST keyboard id=5 [slave keyboard (3)]
Power Button id=6 [slave keyboard (3)]
Power Button id=7 [slave keyboard (3)]
Cypress USB Keyboard id=9 [slave keyboard (3)]

每個設備都有一個ID,可用於xinput和其他命令。

大多數X客戶端只會監聽核心設備的輸入,而對其他具體設備發起的事件卻漠不關心。事實上,大多數客戶端完全不知道X輸入擴展的存在。不過,客戶端其實可以通過輸入擴展來識別出某個具體設備。

每個設備都有自己的屬性。使用xinput時帶上設備的號碼,就可查看其屬性

$ xinput --list-props 8
Device 'Logitech Unifying Device. Wireless PID:4026':
Device Enabled (126): 1
Coordinate Transformation Matrix (128): 1.000000, 0.000000,0.000000,
0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
Device Accel Profile (256): 0
Device Accel Constant Deceleration (257): 1.000000
Device Accel Adaptive Deceleration (258): 1.000000
Device Accel Velocity Scaling (259): 10.000000
--snip--

鼠標

你可以用xinput命令修改設備相關的屬性,其中最有用的就是鼠標(指針)。很多設置都可以通過直接修改屬性來做到,但其實還有更簡單的方法,就是使用xinput的–set-ptr-feedback和–set-button-map選項

鍵盤

鍵盤佈局的多樣化使得我們無法將所有佈局都整合到X中。所以它的協議中內置了鍵盤映射的功能,讓你可以通過xmodmap命令來定義佈局。但爲了更方便操控,大部分現代系統其實也都是用XKB(X鍵盤擴展)的。

桌面背景

X有個舊的命令xsetroot,它可以讓你設置root窗口的背景色和其他屬性,但在大多數機器上它並不可行,因爲root窗口是不可見的。相反,大部分桌面環境卻會將一個大窗口放置在其他所有窗口的背後,以在其中實現“動態壁紙”或桌面文件瀏覽的功能。通過命令行更換背景的方法有很多(例如某些GNOME的gsettings命令),但真做起來是很費時間的。

X的未來

X的發展有個很明顯的跡象,即它的服務器支持了極多的庫,其中很多是爲了向下兼容。但更明顯的是,用服務器管理客戶端、客戶端的窗口,並作爲它們與內存的中介,這種做法對性能有很大影響。更高效的做法是用一種輕量的組合窗口管理器來管理窗口,並只對顯存做少量控制,且允許應用自行在顯存中渲染窗口的內容。

ayland是基於這種做法的新標準,它最突出的部分是客戶端與組合窗口管理器的溝通協議。另外,它還定義了輸入設備管理和X兼容系統。

D-Bus

D-Bus(即桌面總線)是Linux桌面系統的最重要的產物之一,它是一個消息傳遞系統。D-Bus之所以重要,是因爲它作爲一種進程間通信的機制,使得各種桌面應用能夠相互溝通。大多數的Linux系統都是用它來把系統事件(例如插入USB設備)通知給進程的。

D-Bus本身包含有支持任何兩個進程相互溝通的庫,其中定義了規範進程間通信的協議。該庫其實只是一種進程間通信方式,就像Unix域套接字。它的重點是一個叫dbus-daemon的“中央槽”。需要對某些事件做出反應的進程,可以到dbus-deamon上註冊,然後就能收到想要的事件通知了。當然,進程也可以創建事件。例如,udisks-daemon進程從ubus監聽硬盤事件,併發送到dbus-deamon,而dbus-deamon會把這些事件再轉發給那些對硬盤事件感興趣的應用。

系統和會話實例

D-Bus在Linux中正變得越來越重要,systemd和Upstart也使用它來通信。然而,在覈心繫統中加入對桌面工具的依賴,這有違Linux的設計宗旨。

我們將dbus-daemon實例(進程)分爲兩種。一種叫系統實例,它在開機時由init啓動,並帶上–system選項。這種實例通常作爲D-Bus用戶來運行,它的配置文件是/etc/dbus-1/system.conf(一般你不應該修改這個文件)。進程可以通過/var/run/dbus/system_bus_socket的Unix域套接字連接到該實例。
另一種叫會話實例。與系統實例不同的是,會話實例只在你打開桌面會話時纔會運行。你運行的桌面應用會連接這種實例。

監視D-Bus消息

查看系統實例與會話實例區別的最佳方法之一是監視總線上的消息。試試使用dbus-monitor的system模式:

$ dbus-monitor --system
signal sender=org.freedesktop.DBus -> dest=:1.952 serial=2 path=/org/
freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired
string ":1.952"

以上啓動信息說明了該監視器已連接,並獲得了一個名字。這樣運行的話,能看見的信息並不多,因爲系統實例一般不太繁忙。想多看點信息的話,插入一個USB存儲設備試試。

相比之下,會話實例就比較忙了。假設你登錄了一個桌面會話,然後運行以下命令:

$ dbus-monitor --session

接下來在不同窗口上點擊鼠標。如果你桌面用到了D-Bus,你會看到有大量的信息輸出,顯示了那些被激活的窗口。

打印

在Linux上打印文檔是一個多步的過程,其步驟如下所示:

  1. 打印程序通常會先將文檔轉成PostScript格式。不過也可以不這麼做。
  2. 程序將文檔發給打印服務器。
  3. 打印服務器收到文檔後,將其放到打印隊列中。
  4. 當輪到該文件時,打印服務器會將其發送到打印過濾器。
  5. 如果發現該文檔不是PostScript格式,打印過濾器可以對其進行轉換。
  6. 如果目標打印機不能識別PostScript,打印機驅動會將該文檔轉換成打印機能識別的格式。
  7. 打印機驅動可在文檔上加一些額外的指令,例如紙匣和復件數。
  8. 最後打印服務器將文檔發給打印機。

PostScript是一種編程語言,所以如果你用它來打印文件,那麼你實際上就是將一段程序發給了打印機。PostScript是類Unix系統中的打印標準,就像.tar是打包標準一樣。(現在有些應用用到的PDF格式,也是能轉成PostScript的。)

CUPS

CUPS(http://www.cups.org/)是Linux和Mac OS X的標準打印系統。它的服務器守護進程是cupsd,你可以用lpr命令作爲客戶端來發送文件給這個守護進程。

CUPS有個突出的功能是實現了互聯網打印協議(Internet Print Protocol,以下簡稱IPP),使得它允許客戶端與服務器端通過TCP端口631進行類HTTP的事務處理。事實上,如果你係統上運行着CUPS,你就可以連接http://localhost:631/去看看你的打印配置和打印任務。大多數的網絡打印機和打印服務器都支持IPP,就連Windows也是。IPP簡化了建立遠程打印機的任務。

通過網頁界面來管理這個系統可能不太可靠,因爲它的默認設置不太安全。作爲替代方案,發行版中通常自帶了圖形界面工具以便你添加和更改打印機。這些工具會修改配置文件,它們一般位於/ets/cups中。因爲配置文件可能比較複雜,所以最好還是用工具來處理。在出現問題的時候,用圖形工具來新建打印機也是不錯的做法。

格式轉換與打印機過濾器

很多打印機,包括幾乎所有低端型號的,都無法識別PostScript或PDF。爲使Linux支持這些打印機,我們必須將文檔轉換成它們能識別的格式。CUPS把文檔送給RIP(即光柵圖像處理器)以生成位圖。而RIP幾乎總是使用Ghostscript(gs)程序來實現這個過程。但是,要讓生成的位圖能適應打印機的格式,還是有點麻煩的。所以,CUPS使用的打印機驅動會參考特定打印機的PostScript打印機定義(PostScript Printer Definition,以下簡稱PPD)文件,以解決分辨率和紙張大小之類的問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章