Ghostty Devlog 005

Mitchell Hashimoto

Ghostty 開發日誌 005

哈囉!歡迎來到 Ghostty 👻 的官方開發日誌!

距離上次的開發日誌已經超過兩個月了,Ghostty 在這段期間有了非常多的更新。這段時間我忙著當新手爸爸,而且把大部分的電腦空閒時間都投入在改進 Ghostty 上,所以有點疏於更新開發日誌,抱歉!

如果你錯過了之前的開發日誌,或想更了解 Ghostty 是什麼,請參考本站上的 Ghostty 頁面


社群動態

在過去兩個月內,Beta 測試群組已從 100 人成長到超過 350 人!哇!兩個月前測試版還不到 50 人。我非常感謝大家對這個終端機專案的關注,以及我們所擁有的 Beta 測試者。這群龐大且持續成長的測試者,將確保 Ghostty 在正式公開發布時,是一個強大且穩定的專案。

我之所以能夠在每一波大幅擴大 Beta 群組,唯一的原因就是 Ghostty 正變得越來越功能完整與穩定。以前每一波 Beta 只邀請 5 個人,就會產生十幾個錯誤或功能需求。現在,我們邀請 50 人才會得到同樣數量的回報。而且這個數字只會越來越大。看到這個專案變得如此真實且穩定,真的令人非常滿足。

如果你有興趣加入 Beta 測試計畫,請加入 Ghostty Discord,就有機會被納入下一波 Beta 名單。在撰寫本文時,Discord 社群中約有 20% 的成員已是 Beta 成員。


Terminal Inspector(終端機檢測器) (#728)

終端機是一個應用程式平台。我覺得「平台」這個詞被太多人過度濫用了,大家都想讓自己的工作看起來比實際上更重要(或者至少想讓投資人相信它比實際上更重要),但終端機確實是一個用於文字互動的平台1

沒有在其上執行的應用程式,終端機就毫無趣味可言。更進一步說,沒有應用程式,終端機根本毫無意義。提升終端機應用程式數量與品質的方法之一,就是讓為終端機開發變得更容易。

以網頁為例,對我而言,開發便利性的量子躍進來自 Firebug 的問世,現在它更常被稱為「web inspector(網頁檢測器)」,而且每個主流瀏覽器都具備類似功能。我想把類似的體驗帶到終端機,因此 Ghostty 現在有了Terminal Inspector

Terminal Inspector 的運作方式與 web inspector 類似:它是一個針對每個終端機的面板,內含關於執行中終端機的即時更新資訊。你可以看到鍵盤輸入(以及它們的編碼方式)、終端機模式、字型大小、網格大小、儲存格詮釋資料、調色盤顏色等等。

這個 Terminal Inspector 的目標是成為終端機開發者不可或缺的工具,讓開發與除錯終端機應用程式(能在任何終端機上運作,而不僅是 Ghostty)變得更容易。

Terminal Inspector 目前仍處於非常早期且非常實驗性的階段。今天它還只是一個純唯讀介面,但我計畫未來讓它支援讀寫,讓你可以修改儲存格、終端機模式、建立合成輸入事件等。

最初的 Terminal Inspector 構想來自 Beta 社群的一位成員,包括我在內的一小群 Beta 社群成員很快便集結起來,將它發展成一個非常具體的構想。感謝所有參與的人!


亞洲語系輸入 (#八百八十八)

在最近幾波 Beta 中,我特別努力邀請來自更多不同時區的人。這帶來了更多使用中文、日文和韓文等語言輸入的測試者。這些測試者回報了近十個與亞洲語系輸入和算繪相關的問題。因此,Ghostty 現在在這些語言上的表現已經非常好。

開發日誌 003中,我有一個專門講鍵盤輸入的章節,標題是「Keyboard Input Handling Hates You」。我在那裡大肆宣揚 Ghostty 的運作有多好,現在我要接續這個話題,再次強調這一切有多麼極其複雜,並再一次說明 Ghostty 都能完美處理2

更複雜的輸入狀態

開發日誌 003中,我介紹了 dead key state(死鍵狀態) 的概念。當時的 Ghostty 僅能處理單一碼位的死鍵狀態。我以帶有重音的英文字母為例。在該範例中,你會輸入像是 '(單引號)接著一個字母如 a,然後得到 á

在日文等語言中,你會輸入一些字元,得到建議輸入(可能會出現帶有更多建議的下拉式選單),然後你可以按下如 enter 或 tab 等按鍵來完成選字。

Ghostty 之前無法處理多碼位的建議選字,而且在顯示建議時也會錯誤地處理如 enter 或 tab 等字元。這些問題現在都已修正,你已經可以輸入日文(及其他語言)了。

這種多碼位建議狀態也帶來了一些邊界情況:在行尾輸入,以及在過窄的視窗中輸入。這些情況現在 Ghostty 也都能處理了。請注意,上方的影片是在另一個錯誤被修正前錄製的(如果你能發現的話),但那個問題現在也已經解決了。

中文字元對齊 (#982)

在等寬終端機網格中,以乾淨且一致的方式算繪多種字型(加上 Emoji)是一大挑戰,而中文字元看起來就是不太對勁:

請注意,以 開頭的詞彙算繪得有點偏低。這是因為在混用某些字型時,使用了錯誤的字型度量計算(在此案例中是儲存格的基線)所導致。這個問題現在已在 Ghostty 中修正。

Linux IME 輸入 (#919)

macOS 在作業系統內就對 input method editors(輸入法編輯器) (IMEs) 提供了很好的支援。在使用 GTK 的 Linux 上,IME 是由可選擇安裝的外掛程式所提供。正因如此,它們與 Ghostty 的測試不夠充分,對於中文、日文和韓文完全無法運作。

所幸,我已經在 Ghostty 的共用核心中為支援 IME 做了大量工作,因此要讓它在 Linux 上正常運作,只需要一個 +47/-1 的 diff 來銜接正確的 GTK 與 Ghostty API。結果,IME 在 Linux 上也能正常運作了:

註:此影片是在上述修正之前錄製的,因此你可以看到字元算繪不正確的情況。


Custom Shaders(自訂著色器) (#903)

你是否曾想讓你的終端機看起來像一台經典的 CRT 顯示器?或者像一捲壞掉的 VHS 錄影帶?我在胡說什麼?我是瘋了嗎?總之,你現在可以在 Ghostty 中透過指定custom shaders來實現以上所有效果,甚至更多。

撇開實用性不談,這類功能看起來似乎會嚴重影響電池續航。現代軟體普遍的沒效率把我們都當傻子了!CPU 和 GPU 速度超快,而這點運算幾乎不算什麼。在我的機器上,上方的效果只用了約 1% 的 CPU 和約 2% 的 GPU。它確實比不使用此功能時更耗電(當然!),但還不至於讓風扇狂轉。

Ghostty 是一款由 GPU 驅動的終端機模擬器。它在 macOS 上使用原生的 Metal,在 Linux 上使用 OpenGL。GPU 透過呼叫 shaders 來算繪畫面。Shaders 就是揮手帶過在 GPU 上執行的程式。

Shaders 通常以特定技術的程式語言撰寫。例如,macOS 上的 Metal 使用 MSL(Metal Shading Language),OpenGL 則使用 GLSL(GL Shading Language)等等。Ghostty 接受以 GLSL 撰寫的 shaders,並會在 macOS 上即時將它們轉換為 MSL。為此,Ghostty 使用 glslang 將 GLSL 轉換為 SPIR-V(大致上是一種中介表示法),然後使用 SPIRV-Cross 將 SPIR-V 轉換為目標格式,例如 MSL。我們透過它們所提供的 C API 來編譯並綁定這兩項工具。

關於這項功能的另一個超酷細節是,Ghostty 提供了 Shadertoy 介面,因此你可以將許多 Shadertoy 上的 shaders 直接套用到 Ghostty 中,無需任何修改。更重要的是,你還可以把 Shadertoy 本身當作 Ghostty custom shaders 的即時、互動式開發工具!

別擔心,這項功能不會對效能造成負面影響。Ghostty 採用多執行緒算繪架構,在影格之間有充足的閒置時間。當使用 custom shaders 時,閒置時間會減少,但對其他執行緒(IO 與 GUI)幾乎沒有影響。當未使用 custom shaders 時,Ghostty 會使用與以往相同的算繪管線,不會為現有執行增加任何新資源(除了對 custom shaders 的一次布林值檢查,以及用來表示空 custom shaders 清單的極小記憶體佔用)。

好吧,但這一切都完全毫無意義,對吧?最常見的使用情境就是好玩,而那當然不是必要的(對啊,去他的樂趣,對吧?)。然而,custom shaders 最主要的實用用途是無障礙輔助。Custom shaders 是針對某些類型的色盲、調整對比或亮度以提高可讀性、創造「放大鏡」效果等非常好的方式。

我並不是想把無障礙的責任推給他人,我也樂於將各種無障礙功能做成內建的一級功能,但在 Ghostty 尚未具備某些功能的情境下,這是讓使用者能自行掌握的好方法。


Xterm 相容性稽核與行為文件 (#632)

終端機模擬器是模擬器,但它們在模擬什麼?傳統上,終端機模擬器模擬的是如 VT52、VT100、VT220 等實體終端機。實際上,這些硬體已經有很長一段時間不再容易取得或被實際使用,因此大多數現代終端機模擬器只是彼此模仿行為。這導致不同終端機模擬器之間的行為有各種不太一致的地方,許多終端機模擬器在邊界情況上也存在錯誤3

xterm 是 X 視窗系統的標準終端機模擬器,也經常被譽為歷史終端機行為的黃金標準。此外,xterm 的使用非常廣泛,即使忽略歷史終端機,其行為對於它所支援的功能而言,也可被視為事實上的標準。

我已決定,在一切可行且合理的範圍內,Ghostty 應該完全匹配 xterm 的行為。這讓專案對於「為什麼 <feature> 會這樣運作?」這個問題,能有一個一致的答案4

我所謂的「在一切可行且合理的範圍內」是什麼意思?我的意思是,預設情況下在實作功能時,我們應該匹配 xterm。如果某個功能被回報有錯誤,我們總會問:「xterm 在這種情況下會怎麼做?」如果有充分的理由可以偏離該行為,那麼它就是例外,而非通則。

為此,我已開始慢慢稽核 xterm 的每一項有文件記載的功能,並與 Ghostty 進行比較。在此過程中,我也一直在建立我們自己的文件,並盡量讓它越詳細越好。文件還包含了帶有預期輸出的 shell 指令碼驗證案例,以便撰寫端對端測試來確保相容性。看起來像這樣:

終端機支援許多功能,xterm 的程式碼庫很複雜,而這項任務非常繁瑣,所以我無法一夜之間完成。但在過去幾個月裡,我一直在逐項功能慢慢勾選,到目前為止,這已經讓 Ghostty 修復了數十個錯誤,也在其他終端機中發現了數十個錯誤(有些已回報,有些我之後會回報,沒有一個是嚴重的)。

這並不意味著 Ghostty 會支援 xterm 支援的所有功能。相反地,對於 Ghostty 已有而 xterm 也支援的功能,Ghostty 將以與 xterm 達到最大相容性為目標(在有充分理由的情況下允許例外)。


結語

在開發日誌中,我專注於挑選幾項我覺得有趣、想分享的變更。開發日誌不是變更日誌,我也不希望它們讀起來只是枯燥的變更清單。話雖如此,我想指出的是,在過去兩個月裡,Ghostty 專案也完成了超過 100 項錯誤修正與改進,Ghostty 每天都越來越接近可公開發布的狀態。

隨著 Beta 版的成長,貢獻者的人數也隨之增加。已有將近 50 人為 Ghostty 做出貢獻(幾乎每 6 位 Beta 測試者中就有 1 位不只是回報錯誤,還貢獻了程式碼!)。這真的非常驚人,我非常感謝大家為這個專案投入的時間與關注。

如果你想掌握最新動態,請在 Twitter 或 Mastodon 上追蹤我(連結在頁尾)。這個部落格也有 RSS 訂閱

Boo. 👻

註腳

  1. 我沒有在尋找投資人。希望沒有人會那樣解讀這段話,但我覺得必須這麼說。而且這不是那種「眨眨眼說沒在找」的說法,我是真的沒興趣。

  2. 處理輸入是很複雜的,我確定還有更多錯誤存在,但現在的狀態已讓說日文、韓文和中文的 Beta 測試者能夠全職使用 Ghostty。

  3. 幾乎沒有終端機模擬器能正確處理將如 這類寬字元切開的逸出序列。這裡的「正確」是有爭議的,因為沒有規範,所以我想它們愛怎麼做就怎麼做。換句話說,其行為極度不一致。

  4. 當然,這僅適用於 xterm 有實作的功能。有些功能如 Kitty Graphics Protocol 是由 Kitty 明確定義的,在那種情況下,我們會盡可能完全匹配 Kitty。

原文由 Mitchell Hashimoto 發布

本文章由 muse-spark-1.2-contributor 進行翻譯