| RFC-0189:視窗管理 | |
|---|---|
| 狀態 | 已接受 |
| 區域 |
|
| 說明 | 說明平台架構和視窗管理標準 API。 |
| 問題 | |
| Gerrit 變更 | |
| 作者 | |
| 審查人員 | |
| 提交日期 (年-月-日) | 2022-08-12 |
| 審查日期 (年-月-日) | 2022-09-20 |
摘要
本 RFC 建議一個模型,說明 Fuchsia 平台、產品工作階段和工作階段殼層如何共同運作,支援多個視窗的複雜圖形應用程式。請特別注意以下幾點:
- 平台負責將圖像顯示在螢幕上並轉送輸入內容的機制,但產品元件必須指定產品專屬的政策,說明圖像的顯示時間和方式。
- 平台會定義視窗管理1 的標準化 API 介面,盡可能確保應用程式和產品之間的相容性。
這項設計的重要結果是,應用程式會與 Fuchsia 平台整合,而非與特定 Fuchsia 產品整合。因此,只要其他 Fuchsia 產品支援相同的視窗功能,應用程式就能與這些產品搭配使用。具體來說,針對某項 Fuchsia 桌機產品執行的應用程式,應能針對任何這類產品執行,無論特定產品工作階段或系統殼層實作方式為何。
這份 RFC 擴充了 RFC-0092:工作階段。這份文件描述的是規劃狀態,而非目前的運作方式。本 RFC 中所述的方法會取代所有先前的嘗試 (模組化、工作階段架構),並成為日後記錄的計畫。
提振精神
目前的 Fuchsia API 難以讓產品和應用程式實作豐富的視窗管理功能和多視窗應用程式。平台和產品的責任劃分令人困惑,且平台提供的 API 來自 Fuchsia 願景的早期階段,缺少目前工作 (例如 Workstation) 所需的一些重要功能。先前曾多次嘗試解決這個問題和相關問題 (模組化、工作階段架構),但沒有一個解決方案完全實作在所有 Fuchsia 介面上。
目前系統的職責劃分不明確,且有多種方式可執行相同動作。這導致不同產品之間出現片段化現象。現在批准架構,可讓我們在日後決定平台將支援的 API (例如可能採用 Wayland 供 Fuchsia 使用),並解除殼層和應用程式的開發限制。
這份 RFC 可能是涵蓋視窗管理不同層面的系列文件第一篇。目標是釐清產品和平台之間的區別,並讓您日後更容易決定要使用哪些 API (例如 Wayland)。
利害關係人
協助人員:abarth@google.com
審查者:
- 顯示卡:dworsham@google.com
- 工作站:sanjays@google.com
- 架構:abarth@google.com
- 元件架構:thatguy@google.com
- Chrome:wez@google.com
- UX:asz@google.com
諮詢對象:quiche@google.com、jasoncampbell@google.com、geb@google.com、 masonben@google.com、jsankey@google.com、tjdetwiler@google.com
社交化:透過 Gerrit 發布前,我們已與利害關係人分享這份 RFC 草案,並進行深入討論。
定義
本文件用途:
- 顯示伺服器 (又稱 Compositor):這個元件負責允許應用程式元件建立及顯示檢視區塊、控管這些檢視區塊的放置位置和大小,並確保圖形輸入事件會根據檢視區塊傳送至應用程式元件。在 Fuchsia 上,這是 scenic。
- 視窗管理員:控制應用程式提供視窗的位置和外觀的元件 (或多個元件)。在某些系統上,這個系統也負責算繪 UI (例如標題列)。由於 Fuchsia 平台可用於實作各種產品,這些產品的圖形和輸入功能差異很大,因此 Fuchsia 上的視窗管理員責任分配方式,可能與其他作業系統大相逕庭,因為在其他作業系統中,平台與單一使用者體驗的關係更密切。
- 系統殼層:負責繪製產品 UI 的元件。這個元件擁有檢視畫面階層中產品子樹狀結構的頂端景觀檢視畫面,可顯示視覺內容。這個檢視畫面有時也稱為「殼層檢視畫面」。系統殼層負責在檢視區塊樹狀結構中安裝應用程式元件提供的檢視區塊,並決定如何顯示這些檢視區塊。
- 產品工作階段:負責實作 Fuchsia 產品體驗的元件。這個元件會以工作階段管理員的子項身分執行。這個元件負責啟動應用程式元件,並根據使用者動作提供適當功能。撰寫本 RFC 時,Fuchsia 一次只支援一個工作階段。
- 元素:工作階段架構概念,指含有圖形的元件。這項 RFC 會淘汰元素角色。
- 應用程式元件:實作圖形使用者體驗的元件,會在系統殼層中執行。
- 檢視區塊樹狀結構:Scenic 場景圖中的檢視區塊階層。
設計
總覽
Fuchsia 的視窗管理主要有兩個層面:機制和政策。
- 「政策」是指產品專屬的詳細資料,包括允許在畫面上放置圖像的元件、圖像的顯示位置、接收輸入內容和焦點的方式,以及在檢視樹狀結構中的關聯性。政策是決定視窗可執行的動作。
- 「機制」是指在畫面上顯示像素,以及將輸入內容傳送至基礎元件的機制,這項作業主要透過 Fuchsia UI 堆疊處理。所有提供圖像的元件都必須與這些 API 通訊。政策決策的影響可能需要多次呼叫機制 API,才能對 UI 進行相關變更。
Fuchsia SDK 定義了兩個視窗管理政策的 API 介面:
- 系統殼層的 API,可實作產品專屬的視窗管理政策,並提供產品可用的視窗管理功能相關資訊。目前,這項功能的實作方式是要求系統殼層實作圖形簡報者角色。
- 應用程式元件可使用 API 或 API 集,要求變更該元件擁有的檢視區塊存在狀態和外觀。這會以核心 API 的形式呈現,所有應用程式用戶端都應使用這個 API,並可能擴充其他行為 (可在執行階段偵測)。所有 Fuchsia 應用程式都應共用這個 API 介面,方便在 Fuchsia 上建構的不同產品之間維持相容性。
目前用戶端應用程式的實作詳細資料差異很大。部分應用程式會實作元素角色,其他應用程式則會直接與元件架構和 Scenic 互動,或在應用程式中實作元素管理員 API。這項 RFC 規定簡化此程序,為所有應用程式元件改用單一 API。
本 RFC 目前並未針對系統殼層和應用程式元件是否直接通訊,或平台元件是否應中介這些互動,表達任何意見。
架構圖

上圖顯示在 Fuchsia 上執行的圖形產品可能採用的架構。產品工作階段負責啟動系統殼層和任何應用程式。應用程式和系統殼層必須就任何政策決策進行通訊,可能透過平台提供的視窗管理工具或「橋接器」元件 (請參閱下方的「可能的平台橋接器元件」)。系統殼層和應用程式也必須與 Fuchsia 平台 UI 堆疊 (包括處理圖像和輸入處理的元件) 通訊,才能執行視窗管理「機制」方面的作業。這類通訊也可能透過橋接器元件進行。
產品工作階段的職責
產品工作階段是產品啟動時要啟動的第一個產品專屬元件。對於有圖像的產品,這項功能還肩負下列額外責任:
- 產品工作階段負責啟動應用程式元件,並提供適當功能,包括在畫面上顯示 UI 所需的功能。
- 產品工作階段必須為使用者體驗提供根檢視區塊,方法是直接實作,或將這項作業委派給子項元件。提供這個檢視區塊的元件也稱為系統殼層 (有時也稱為系統 UI)。系統殼層具有一項能力 (fuchsia.session.scene.Manager),可讓它在檢視區塊樹狀結構中安裝根檢視區塊。(請注意,產品可能包含多個殼層,例如登入和使用者殼層,並視需要切換。)
- 產品工作階段負責視窗管理的產品政策層面。具體來說,工作階段必須實作 Fuchsia SDK 提供的視窗管理政策 API。這項責任包括提供資訊,說明此產品可用的視窗作業類型。
元件階層範例

這張圖表顯示使用者體驗的可能元件階層。請注意,這會淘汰元素管理工具。如圖所示,應用程式元件是產品工作階段的子項。部分產品可能會選擇以不同方式設定,例如在產品工作階段領域中建立負責啟動應用程式的元件,或是將應用程式元件例項化作業委派給具有不同功能的平台元件。
設定檢視區塊階層
啟動後,應用程式可以聯絡 Scenic 建立應用程式檢視畫面,然後透過視窗管理 API 聯絡系統殼層,將該檢視畫面顯示為系統殼層使用者體驗的一部分。系統殼層會聯絡 Scenic,將應用程式檢視區塊安裝到檢視區塊樹狀結構中,通常是做為根檢視區塊的子項。
應用程式可能會按照上述初始視窗建立流程,開啟第二個頂層視窗。如要執行進一步的視窗管理動作,例如調整應用程式檢視區塊大小、啟動彈出式視窗等,應用程式元件必須透過呼叫視窗管理 API,向系統殼層要求這些變更。一般來說,每個元件都負責直接與 Scenic 通訊,瞭解其擁有的 View 內容。不過,如果檢視區塊擁有者/應用程式想要變更檢視區塊的顯示方式 (例如調整大小、縮小或開啟另一個頂層檢視區塊),系統殼層必須以某種方式指出允許這項動作。系統殼層可以回應用戶端 API 呼叫,或是在檢視樹狀結構中儲存資訊,指出該檢視可執行的動作,並允許 Scenic 執行相關政策。
注意:
- 產生的元件階層和檢視區塊樹狀結構看起來並不相同!應用程式檢視區塊必須是系統殼層所擁有檢視區塊的子項檢視區塊,但應用程式元件不一定要屬於系統殼層元件的領域。
- 這份說明省略了許多檢視區塊建立的詳細資料,包括使用者輸入等內容如何透過檢視區塊樹狀結構路徑傳送至檢視區塊。
檢視區塊階層範例

上圖顯示執行多個圖形應用程式的系統 UI 範例檢視區塊樹狀結構。系統殼層檢視區塊是使用者體驗的根檢視區塊。請注意,檢視區塊樹狀結構的父子關係可能與上方的元件階層不同。
視窗管理功能交涉
並非所有系統殼層實作都會公開相同的功能,因為系統殼層會部分實作產品專屬政策。因此,這些實作方式會因產品而異。舉例來說,智慧手錶的 UI 可能非常簡單,一次只會在螢幕上顯示一個檢視畫面,而桌機則支援多個應用程式,以及多個重疊視窗。部分產品支援透過觸控螢幕輸入,其他產品則僅支援滑鼠和鍵盤。
如要使用「核心集」以外的特定產品功能,用戶端必須能夠探索目前產品支援哪些功能。這項功能可讓用戶在不同產品中調整行為,並實作可在不同產品中運作的圖形化 Fuchsia 應用程式。
同樣地,系統 UI 必須告知平台目前可用的功能。
可能的平台橋接器元件
平台可能會導入「橋接器」元件,負責調解用戶端應用程式和系統 UI 之間的通訊。這個元件類似於其他平台上的視窗管理員,可自動執行視窗管理的一些「機制」動作,減少開發人員編寫程式碼的需求,不必再將低階指令傳送至 Fuchsia UI 堆疊。這樣做的好處是,用戶端可以透過單一 API 介面與機制和政策通訊,這是其他系統的常見模式 (例如 Wayland)。將橋接器元件放在平台中,產品就能共用視窗管理程式碼,避免類似功能重複。
是否要使用平台橋接器元件/平台視窗管理員,將在日後的 RFC 中決定。
實作
本 RFC 說明視窗管理的高階架構。由於我們預期日後的 RFC 會對相關 API 進行重大變更,因此許多實作細節應在這些 RFC 中說明。
API 推出後,這項 RFC 意味著系統目前缺陷的許多舊有解決方法將會移除。請特別注意以下幾點:
- 這項 RFC 會淘汰 Element Manager (目前元素管理員功能會成為產品工作階段的工作)。
- 這項 RFC 批准了應用程式行為正常化的意圖 (不再需要 Chrome 專屬的解決方法)。現有 API 的替代方案將在日後的 RFC 中說明。
效能
雖然圖像和使用者輸入處理程序對效能非常敏感,但開啟新應用程式或視窗等視窗管理政策決策通常會以「人類速度」進行,因此不需要與算繪或輸入處理程序相同的效能。因此,執行「控制」動作 (例如開啟新視窗) 時,通常可以使用額外的 RPC。不過,設計 API 時應謹慎,確保任何對效能敏感的流程 (通常是涉及資料流的流程,例如在畫面上放置影格、路由傳送使用者輸入內容) 避免不必要的 IPC,且不會不必要地封鎖用戶端回應。如果視窗管理員和殼層不是同一個元件,就特別需要注意這一點。後續的 RFC 應詳細說明特定 API 的效能影響。
動畫和同步
為確保使用者體驗順暢,請務必確保 UI 動作 (例如大小調整動畫) 可在多個元件之間同步處理。雖然這主要是特定 API 的功能,以及其有關原子性的保證,但架構可能會影響建構使用者體驗的難易度,進而影響這類同步作業是否可行。
這項 RFC 並未正式採用特定 API,但其中包含的決策是根據 Wayland API 評估而來,該 API 的目標是「讓每個影格都完美」。在完成本 RFC 中所述的 API 時,同步問題將是重要的考量因素。
安全性和隱私權注意事項
元件安全性
這項 RFC 說明元件階層和檢視區塊階層不必相同,並允許應用程式以產品工作階段的子項啟動,而非系統殼層 (在某些系統上可能較不穩定或較不安全)。這項做法可讓產品更輕鬆地確保產品內的元件階層符合該產品的特定安全和隱私權需求。
查看安全性
如要瞭解檢視系統的安全性保證,請參閱檢視系統 RFC。這項 RFC 的重點在於確保檢視區塊只能在目前聚焦於自身或子項時操控檢視區塊焦點,且與檢視區塊樹狀結構中斷連線的檢視區塊無法接收使用者輸入內容。也就是說,產品工作階段安裝系統 UI 檢視區塊,以及系統殼層做出的視窗管理政策決策 (例如為啟動的應用程式安裝子檢視區塊),也是決定哪些元件在任何時間點都有資格接收使用者輸入內容的決策。雖然平台無法保證所有產品都會實作安全行為,但檢視系統提供產品的建構區塊,可建立安全體驗。
測試
平台應為所有視窗管理 API 提供一致性測試,確保產品和應用程式與 Fuchsia 平台相容。這些測試可能因視窗管理 API 的擴充功能而異,具體取決於特定應用程式或產品工作階段支援哪些擴充功能。
系統 Shell 和應用程式開發人員可以使用「測試 UI 堆疊」,為程式碼與 Fuchsia 平台 UI 堆疊的互動編寫整合測試。
說明文件
這項 RFC 和後續處理 API 細節的 RFC,都需要大幅更新 fuchsia.dev 上的 Session Framework 說明文件,以反映產品和平台之間的分工,以及淘汰 Element Manager 的最新期望。
缺點、替代方案和未知事項
替代方案:Scenic 負責視窗管理
- 如果沒有新的 API,系統殼層就無法套用產品層級的政策/概念。
- 不清楚如何擴充這個 API 來處理產品差異。否則,會將大量產品專屬邏輯 (例如「最小化」的意義) 推送至平台。
既有技術和參考資料
-
這些 API 會在後續的 RFC 中定義。 ↩