<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Desktop on Tarragon</title><link>https://tarrragon.github.io/blog/tags/desktop/</link><description>Recent content in Desktop on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Thu, 02 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/desktop/index.xml" rel="self" type="application/rss+xml"/><item><title>桌面環境選型：整合度與組裝自由度的取捨</title><link>https://tarrragon.github.io/blog/linux/tools/gui/desktop-environment-selection/</link><pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/linux/tools/gui/desktop-environment-selection/</guid><description>&lt;p>桌面環境（desktop environment，DE）是一整套讓你能用圖形介面操作 Linux 的元件集合——它同時提供視窗管理、面板/工作列、應用啟動器、設定中心、通知、檔案管理員、鎖屏這些功能，並保證它們彼此整合、開箱即用。這跟只負責「畫視窗、管理視窗位置」的 window manager 或 compositor 是不同層次的東西：DE 通常內含一個 window manager，再把上面那一整圈桌面服務組裝好交給你。理解這個責任邊界，是選型的起點——你在選的不是「哪個比較漂亮」，是「別人幫你整合到什麼程度、你自己要組裝多少」。&lt;/p>
&lt;h2 id="選型的真正軸線整合度-vs-組裝自由度">選型的真正軸線：整合度 vs 組裝自由度&lt;/h2>
&lt;p>桌面環境的選擇，核心不是「輕或重」，是&lt;strong>別人幫你整合好多少、你保留多少自己組裝的自由&lt;/strong>。這條軸線的一端是 GNOME 這種高整合方案：面板、設定、通知、檔案管理全部設計成一致的整體，你開機就有一台能用的機器，代價是想改動它預設的行為要對抗它的設計哲學。另一端是 Hyprland 這種 compositor：它只負責畫面與視窗，面板、啟動器、鎖屏、通知你全部自己挑自己接，代價是要花時間組裝、每個元件都要自己維護。&lt;/p>
&lt;p>「輕/重」只是這條軸線的副產品。高整合方案因為要保證所有元件協同，通常帶較多常駐服務、吃較多記憶體；自己組裝的方案可以只裝你要的，所以輕——但如果你把面板、啟動器、通知、鎖屏一個個補齊，最後的資源佔用未必比一個現成 DE 省多少。所以判選型別問「哪個輕」，要問「我想花多少時間在組裝與維護、換到多少客製自由」。&lt;/p>
&lt;h2 id="五個主流選項的定位">五個主流選項的定位&lt;/h2>
&lt;p>下表是常見選項在「整合度」這條軸線上的位置與代價。每個選項底下有延伸說明，因為同樣一句「適合客製」在不同方案裡的實際體驗差很多：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>方案&lt;/th>
 &lt;th>定位&lt;/th>
 &lt;th>整合度&lt;/th>
 &lt;th>資源&lt;/th>
 &lt;th>客製自由&lt;/th>
 &lt;th>預設顯示協定&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>GNOME&lt;/td>
 &lt;td>高整合、意見鮮明的現代桌面&lt;/td>
 &lt;td>高&lt;/td>
 &lt;td>較高&lt;/td>
 &lt;td>低（要對抗設計）&lt;/td>
 &lt;td>Wayland&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>KDE Plasma&lt;/td>
 &lt;td>高整合但高度可調&lt;/td>
 &lt;td>高&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>高（內建設定深）&lt;/td>
 &lt;td>Wayland&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>XFCE&lt;/td>
 &lt;td>輕量傳統桌面&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>低&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>X11&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Cinnamon&lt;/td>
 &lt;td>傳統桌面隱喻、易上手&lt;/td>
 &lt;td>中高&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>X11&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Hyprland（WM）&lt;/td>
 &lt;td>自己組裝的平鋪式 compositor&lt;/td>
 &lt;td>無（自組）&lt;/td>
 &lt;td>最低（裸）&lt;/td>
 &lt;td>最高&lt;/td>
 &lt;td>Wayland&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="gnome把選擇替你做完的現代桌面">GNOME：把選擇替你做完的現代桌面&lt;/h3>
&lt;p>GNOME 的定位是「一套有明確設計主張的完整桌面」——它預設一個不同於 Windows/macOS 的工作流（頂欄 + Activities 總覽 + 動態工作區），並且刻意收斂可調選項，讓多數人不用設定就有一致體驗。從 Windows/macOS 轉來、想要「裝好就能用、不想折騰」的人，GNOME 是穩妥選擇：它的整合度最高，通知、設定、線上帳號、檔案管理彼此協調。&lt;/p>
&lt;p>代價在客製。GNOME 把很多設定收進 extension 或需要另裝 &lt;code>gnome-tweaks&lt;/code>（Arch：&lt;code>pacman -S gnome-tweaks&lt;/code>）才改得動的角落，想把它調成傳統工作列風格是在對抗它的設計方向，而 extension 又會隨 GNOME 大版本更新而失效。所以 GNOME 適合「接受它的工作流」的人，不適合「想按自己習慣重排一切」的人。資源上它是這幾個裡偏吃的，老硬體上會感覺得到。&lt;/p>
&lt;h3 id="kde-plasma整合度高但幾乎每個角落都能調">KDE Plasma：整合度高、但幾乎每個角落都能調&lt;/h3>
&lt;p>KDE Plasma 少見地同時做到高整合與高可調：它像 GNOME 一樣開箱即用、元件協調，但幾乎每個行為都攤在設定介面裡讓你改——面板可以拆解重組、視窗規則、快捷鍵、視覺效果都有深度選項。從 Windows 轉來的人會覺得它的預設隱喻（底部工作列 + 開始選單）親切，又保留了往下鑽的空間。&lt;/p>
&lt;p>它的代價不在資源（現代 Plasma 已相當精實，中階機器順暢），在「選項多到需要自己收斂」——設定深意味著你可能花很多時間在調整上。想要「高整合又想保留大量客製、但不想從零組裝」的人，Plasma 通常是比 GNOME 和 Hyprland 都平衡的落點。它的 Wayland session 近年已是預設且成熟。&lt;/p>
&lt;h3 id="xfce老硬體與要傳統要穩要輕的預設">XFCE：老硬體與「要傳統、要穩、要輕」的預設&lt;/h3>
&lt;p>XFCE 的定位是輕量而傳統：它給你熟悉的桌面隱喻（工作列、選單、系統匣），資源佔用在這幾個裡最低，且以穩定少變著稱——它不追新，多年來介面與行為變動小。老硬體、低階 VM、或「我只要一個不吵不鬧、能穩定工作的桌面」的場景，XFCE 是可靠預設。&lt;/p>
&lt;p>它的取捨是現代感與顯示協定：XFCE 目前仍以 X11 為主，Wayland 化在進行但尚未是預設，所以想要 Wayland 的分數效益（見下節）目前要往別的方案找。客製自由度中等——比 GNOME 開放、但沒有 KDE 那種深度設定，也沒有 Hyprland 那種完全重組的自由。&lt;/p>
&lt;h3 id="cinnamon給要-windows-式熟悉感的轉移者">Cinnamon：給「要 Windows 式熟悉感」的轉移者&lt;/h3>
&lt;p>Cinnamon 出身 Linux Mint，定位是把傳統桌面隱喻做得順手好上手——底部工作列、開始選單式的應用選單、系統匣，對從 Windows 轉來的人幾乎零學習曲線。它比 XFCE 現代一點、視覺完整度高一些，整合度也高（自帶檔案管理員 Nemo、設定中心、特效）。&lt;/p>
&lt;p>代價與 XFCE 類似：以 X11 為主，資源比 XFCE 略高。它適合「要一台立刻上手、像 Windows 但是 Linux」的工作機，不適合追求 Wayland 或極致輕量的場景。附帶一提，Cinnamon 的檔案管理員 Nemo 假設 Cinnamon 桌面服務在旁邊，把它單獨裝進裸 window manager 會拖進整套 Cinnamon 元件——這正是&lt;a href="../gui-file-manager-dependencies/">加圖形檔案管理員那篇&lt;/a>講的桌面環境耦合。&lt;/p>
&lt;h3 id="hyprland不是-de是你自己組一個桌面">Hyprland：不是 DE，是你自己組一個桌面&lt;/h3>
&lt;p>Hyprland 嚴格說不是桌面環境，是一個平鋪式（tiling）Wayland compositor——它只負責畫面合成與視窗排列，面板、啟動器、鎖屏、通知、桌布、音量控制全部不含，要你自己挑元件接上去。選它意味著你接受「從零組裝一個桌面」這件事，換來的是最高的客製自由（每個元件都你選、佈局規則完全你定）和最低的裸資源佔用。&lt;/p>
&lt;p>它適合「把配置桌面當成一種投入、想要一套完全長成自己樣子的環境」的人，不適合「只想裝好開始工作」的人。組裝過程本身有相當的學習曲線與維護成本——這也是為什麼本系列用一整個 &lt;a href="https://tarrragon.github.io/blog/linux/dotfile/06-rice-design/" data-link-title="模組六：桌面 Rice 設計" data-link-desc="Hyprland 桌面從能用到好看好用 — 狀態列、啟動器、通知、鎖屏、配色系統的設計與配置">Rice 設計模組&lt;/a>談「選了 Hyprland 之後怎麼把它組起來」。如果你還在「要不要走這條路」的階段，這篇就是那個模組的上游：先確認你要的是組裝自由、而不是開箱即用。&lt;/p>
&lt;h2 id="wayland-vs-x11選型時避不開的底層判斷">Wayland vs X11：選型時避不開的底層判斷&lt;/h2>
&lt;p>顯示協定是選型時的一條隱形軸線，因為它決定了一部分未來相容性。Wayland 是較新的顯示協定，設計上更安全、對高 DPI 與多螢幕不同刷新率支援更好，是 Linux 桌面的方向；X11 是沿用數十年的舊協定，相容性最廣但架構老舊、社群維護逐漸收斂到維持模式。GNOME、KDE Plasma、Hyprland 都已預設或原生 Wayland；XFCE、Cinnamon 目前仍以 X11 為主。&lt;/p>
&lt;p>實務判讀：如果你用 NVIDIA 專有驅動、或依賴某些只支援 X11 的老工具（部分螢幕錄製、遠端桌面、自動化工具），X11 方案目前可能更少驚喜；如果你要高 DPI 筆電、多螢幕混合刷新率、或想跟上長期方向，優先選 Wayland 方案。這不是非此即彼的道德選擇，是看你的硬體與工具鏈落在哪邊。&lt;/p></description><content:encoded><![CDATA[<p>桌面環境（desktop environment，DE）是一整套讓你能用圖形介面操作 Linux 的元件集合——它同時提供視窗管理、面板/工作列、應用啟動器、設定中心、通知、檔案管理員、鎖屏這些功能，並保證它們彼此整合、開箱即用。這跟只負責「畫視窗、管理視窗位置」的 window manager 或 compositor 是不同層次的東西：DE 通常內含一個 window manager，再把上面那一整圈桌面服務組裝好交給你。理解這個責任邊界，是選型的起點——你在選的不是「哪個比較漂亮」，是「別人幫你整合到什麼程度、你自己要組裝多少」。</p>
<h2 id="選型的真正軸線整合度-vs-組裝自由度">選型的真正軸線：整合度 vs 組裝自由度</h2>
<p>桌面環境的選擇，核心不是「輕或重」，是<strong>別人幫你整合好多少、你保留多少自己組裝的自由</strong>。這條軸線的一端是 GNOME 這種高整合方案：面板、設定、通知、檔案管理全部設計成一致的整體，你開機就有一台能用的機器，代價是想改動它預設的行為要對抗它的設計哲學。另一端是 Hyprland 這種 compositor：它只負責畫面與視窗，面板、啟動器、鎖屏、通知你全部自己挑自己接，代價是要花時間組裝、每個元件都要自己維護。</p>
<p>「輕/重」只是這條軸線的副產品。高整合方案因為要保證所有元件協同，通常帶較多常駐服務、吃較多記憶體；自己組裝的方案可以只裝你要的，所以輕——但如果你把面板、啟動器、通知、鎖屏一個個補齊，最後的資源佔用未必比一個現成 DE 省多少。所以判選型別問「哪個輕」，要問「我想花多少時間在組裝與維護、換到多少客製自由」。</p>
<h2 id="五個主流選項的定位">五個主流選項的定位</h2>
<p>下表是常見選項在「整合度」這條軸線上的位置與代價。每個選項底下有延伸說明，因為同樣一句「適合客製」在不同方案裡的實際體驗差很多：</p>
<table>
  <thead>
      <tr>
          <th>方案</th>
          <th>定位</th>
          <th>整合度</th>
          <th>資源</th>
          <th>客製自由</th>
          <th>預設顯示協定</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>GNOME</td>
          <td>高整合、意見鮮明的現代桌面</td>
          <td>高</td>
          <td>較高</td>
          <td>低（要對抗設計）</td>
          <td>Wayland</td>
      </tr>
      <tr>
          <td>KDE Plasma</td>
          <td>高整合但高度可調</td>
          <td>高</td>
          <td>中</td>
          <td>高（內建設定深）</td>
          <td>Wayland</td>
      </tr>
      <tr>
          <td>XFCE</td>
          <td>輕量傳統桌面</td>
          <td>中</td>
          <td>低</td>
          <td>中</td>
          <td>X11</td>
      </tr>
      <tr>
          <td>Cinnamon</td>
          <td>傳統桌面隱喻、易上手</td>
          <td>中高</td>
          <td>中</td>
          <td>中</td>
          <td>X11</td>
      </tr>
      <tr>
          <td>Hyprland（WM）</td>
          <td>自己組裝的平鋪式 compositor</td>
          <td>無（自組）</td>
          <td>最低（裸）</td>
          <td>最高</td>
          <td>Wayland</td>
      </tr>
  </tbody>
</table>
<h3 id="gnome把選擇替你做完的現代桌面">GNOME：把選擇替你做完的現代桌面</h3>
<p>GNOME 的定位是「一套有明確設計主張的完整桌面」——它預設一個不同於 Windows/macOS 的工作流（頂欄 + Activities 總覽 + 動態工作區），並且刻意收斂可調選項，讓多數人不用設定就有一致體驗。從 Windows/macOS 轉來、想要「裝好就能用、不想折騰」的人，GNOME 是穩妥選擇：它的整合度最高，通知、設定、線上帳號、檔案管理彼此協調。</p>
<p>代價在客製。GNOME 把很多設定收進 extension 或需要另裝 <code>gnome-tweaks</code>（Arch：<code>pacman -S gnome-tweaks</code>）才改得動的角落，想把它調成傳統工作列風格是在對抗它的設計方向，而 extension 又會隨 GNOME 大版本更新而失效。所以 GNOME 適合「接受它的工作流」的人，不適合「想按自己習慣重排一切」的人。資源上它是這幾個裡偏吃的，老硬體上會感覺得到。</p>
<h3 id="kde-plasma整合度高但幾乎每個角落都能調">KDE Plasma：整合度高、但幾乎每個角落都能調</h3>
<p>KDE Plasma 少見地同時做到高整合與高可調：它像 GNOME 一樣開箱即用、元件協調，但幾乎每個行為都攤在設定介面裡讓你改——面板可以拆解重組、視窗規則、快捷鍵、視覺效果都有深度選項。從 Windows 轉來的人會覺得它的預設隱喻（底部工作列 + 開始選單）親切，又保留了往下鑽的空間。</p>
<p>它的代價不在資源（現代 Plasma 已相當精實，中階機器順暢），在「選項多到需要自己收斂」——設定深意味著你可能花很多時間在調整上。想要「高整合又想保留大量客製、但不想從零組裝」的人，Plasma 通常是比 GNOME 和 Hyprland 都平衡的落點。它的 Wayland session 近年已是預設且成熟。</p>
<h3 id="xfce老硬體與要傳統要穩要輕的預設">XFCE：老硬體與「要傳統、要穩、要輕」的預設</h3>
<p>XFCE 的定位是輕量而傳統：它給你熟悉的桌面隱喻（工作列、選單、系統匣），資源佔用在這幾個裡最低，且以穩定少變著稱——它不追新，多年來介面與行為變動小。老硬體、低階 VM、或「我只要一個不吵不鬧、能穩定工作的桌面」的場景，XFCE 是可靠預設。</p>
<p>它的取捨是現代感與顯示協定：XFCE 目前仍以 X11 為主，Wayland 化在進行但尚未是預設，所以想要 Wayland 的分數效益（見下節）目前要往別的方案找。客製自由度中等——比 GNOME 開放、但沒有 KDE 那種深度設定，也沒有 Hyprland 那種完全重組的自由。</p>
<h3 id="cinnamon給要-windows-式熟悉感的轉移者">Cinnamon：給「要 Windows 式熟悉感」的轉移者</h3>
<p>Cinnamon 出身 Linux Mint，定位是把傳統桌面隱喻做得順手好上手——底部工作列、開始選單式的應用選單、系統匣，對從 Windows 轉來的人幾乎零學習曲線。它比 XFCE 現代一點、視覺完整度高一些，整合度也高（自帶檔案管理員 Nemo、設定中心、特效）。</p>
<p>代價與 XFCE 類似：以 X11 為主，資源比 XFCE 略高。它適合「要一台立刻上手、像 Windows 但是 Linux」的工作機，不適合追求 Wayland 或極致輕量的場景。附帶一提，Cinnamon 的檔案管理員 Nemo 假設 Cinnamon 桌面服務在旁邊，把它單獨裝進裸 window manager 會拖進整套 Cinnamon 元件——這正是<a href="../gui-file-manager-dependencies/">加圖形檔案管理員那篇</a>講的桌面環境耦合。</p>
<h3 id="hyprland不是-de是你自己組一個桌面">Hyprland：不是 DE，是你自己組一個桌面</h3>
<p>Hyprland 嚴格說不是桌面環境，是一個平鋪式（tiling）Wayland compositor——它只負責畫面合成與視窗排列，面板、啟動器、鎖屏、通知、桌布、音量控制全部不含，要你自己挑元件接上去。選它意味著你接受「從零組裝一個桌面」這件事，換來的是最高的客製自由（每個元件都你選、佈局規則完全你定）和最低的裸資源佔用。</p>
<p>它適合「把配置桌面當成一種投入、想要一套完全長成自己樣子的環境」的人，不適合「只想裝好開始工作」的人。組裝過程本身有相當的學習曲線與維護成本——這也是為什麼本系列用一整個 <a href="/blog/linux/dotfile/06-rice-design/" data-link-title="模組六：桌面 Rice 設計" data-link-desc="Hyprland 桌面從能用到好看好用 — 狀態列、啟動器、通知、鎖屏、配色系統的設計與配置">Rice 設計模組</a>談「選了 Hyprland 之後怎麼把它組起來」。如果你還在「要不要走這條路」的階段，這篇就是那個模組的上游：先確認你要的是組裝自由、而不是開箱即用。</p>
<h2 id="wayland-vs-x11選型時避不開的底層判斷">Wayland vs X11：選型時避不開的底層判斷</h2>
<p>顯示協定是選型時的一條隱形軸線，因為它決定了一部分未來相容性。Wayland 是較新的顯示協定，設計上更安全、對高 DPI 與多螢幕不同刷新率支援更好，是 Linux 桌面的方向；X11 是沿用數十年的舊協定，相容性最廣但架構老舊、社群維護逐漸收斂到維持模式。GNOME、KDE Plasma、Hyprland 都已預設或原生 Wayland；XFCE、Cinnamon 目前仍以 X11 為主。</p>
<p>實務判讀：如果你用 NVIDIA 專有驅動、或依賴某些只支援 X11 的老工具（部分螢幕錄製、遠端桌面、自動化工具），X11 方案目前可能更少驚喜；如果你要高 DPI 筆電、多螢幕混合刷新率、或想跟上長期方向，優先選 Wayland 方案。這不是非此即彼的道德選擇，是看你的硬體與工具鏈落在哪邊。</p>
<h2 id="依情境選從你的處境倒推">依情境選：從你的處境倒推</h2>
<p>選型的最後一步是把上面的定位對回你自己的處境，不是背「哪個最好」：</p>
<ul>
<li><strong>剛從 Windows/macOS 轉來、只想要能用</strong>：KDE Plasma（熟悉隱喻 + 之後可深調）或 GNOME（接受新工作流、要最省心）。要極致熟悉感就 Cinnamon。</li>
<li><strong>老硬體 / 低階 VM / 要穩定不折騰的工作機</strong>：XFCE。資源最低、變動最少。</li>
<li><strong>想把桌面調成完全自己的樣子、願意投入組裝</strong>：Hyprland（或其他 WM）。先讀 <a href="/blog/linux/dotfile/06-rice-design/" data-link-title="模組六：桌面 Rice 設計" data-link-desc="Hyprland 桌面從能用到好看好用 — 狀態列、啟動器、通知、鎖屏、配色系統的設計與配置">Rice 設計模組</a> 確認你要的是這條路。</li>
<li><strong>要高整合又要大量客製、不想從零組裝</strong>：KDE Plasma，是這兩個需求的平衡點。</li>
<li><strong>硬體是 NVIDIA 或依賴 X11 工具</strong>：優先 X11 成熟的方案（XFCE / Cinnamon），或確認你的 Wayland 方案在該硬體上的狀況再決定。</li>
</ul>
<p>判準是把「我願意花多少時間在桌面本身、我對客製的需求有多強、我的硬體與工具落在 Wayland 還是 X11」三個問題答清楚，選項自然收斂。沒有一個 DE 對所有人最好——選錯最常見的原因是拿別人的推薦套自己不同的處境。</p>
<h2 id="桌面環境的擴充生態">桌面環境的擴充生態</h2>
<p>選好 DE 之後，各方案還有自己的擴充路徑，這是「選項之下還有選項」的一層：</p>
<ul>
<li><strong>GNOME</strong>：透過 GNOME Extensions 加面板、工作流、狀態列元件，但要注意 extension 綁 GNOME 版本、大版本更新可能失效。</li>
<li><strong>KDE Plasma</strong>：內建的 widget（plasmoid）、全域主題、視窗規則系統，多數擴充不需要離開設定介面。</li>
<li><strong>XFCE / Cinnamon</strong>：panel plugin、applet、主題，擴充幅度中等但穩定。</li>
<li><strong>Hyprland</strong>：因為本來就是自己組，擴充等於換元件——換 bar（waybar/其他）、換啟動器、換通知 daemon，自由度最高也最需要自己維護。這一整套怎麼組，是 <a href="/blog/linux/dotfile/06-rice-design/" data-link-title="模組六：桌面 Rice 設計" data-link-desc="Hyprland 桌面從能用到好看好用 — 狀態列、啟動器、通知、鎖屏、配色系統的設計與配置">Rice 設計模組</a> 的主題。</li>
</ul>
<h2 id="下一步">下一步</h2>
<ul>
<li>選了 Hyprland、要開始組裝：<a href="/blog/linux/dotfile/06-rice-design/" data-link-title="模組六：桌面 Rice 設計" data-link-desc="Hyprland 桌面從能用到好看好用 — 狀態列、啟動器、通知、鎖屏、配色系統的設計與配置">Dotfile 管理：桌面 Rice 設計</a> 是「選了之後怎麼把它長成自己的樣子」的完整模組。</li>
<li>桌面選好、要裝檔案管理員這類 GUI app 時的相依判讀：<a href="../gui-file-manager-dependencies/">在 Hyprland 加圖形檔案管理員</a>。</li>
<li>純終端機環境不需要桌面環境、但需要對應的 CLI 工具：<a href="../../cli/">CLI 環境工具</a>。</li>
<li>桌面裝好後遇到顯示、鎖屏、服務層的問題怎麼診斷：<a href="../../../debug/">除錯與診斷</a>。</li>
</ul>
]]></content:encoded></item><item><title>Desktop client 簽章、公證與自動更新流程</title><link>https://tarrragon.github.io/blog/ci/desktop-client-deploy/signing-notarization-update-flow/</link><pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ci/desktop-client-deploy/signing-notarization-update-flow/</guid><description>&lt;p>Desktop client 發布流程的核心責任是讓多平台安裝包可信、可更新、可回復。桌面應用和 web 不同，使用者會下載 installer 或 package 到本機；CI/CD 需要處理平台差異、code signing、notarization、auto-update feed、delta package 與多版本共存。&lt;/p>
&lt;h2 id="流程定位">流程定位&lt;/h2>
&lt;p>Desktop client 的風險集中在作業系統信任鏈與更新通道。macOS、Windows、Linux 對簽章、安裝包格式與安全提示的要求不同；同一份 source 通常會產生多個平台 artifact，因此 workflow 要把平台 matrix、簽章 secret 與 &lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/release-channel/" data-link-title="Release Channel" data-link-desc="說明 stable、beta、internal 等發行通道如何控制 artifact 接觸到的使用者範圍">Release Channel&lt;/a> 拆清楚。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>階段&lt;/th>
 &lt;th>責任&lt;/th>
 &lt;th>判讀訊號&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Build&lt;/td>
 &lt;td>產生 &lt;code>.dmg&lt;/code>、&lt;code>.pkg&lt;/code>、&lt;code>.msi&lt;/code>、AppImage 等&lt;/td>
 &lt;td>平台 matrix 是否完整&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Signing&lt;/td>
 &lt;td>建立 OS 信任&lt;/td>
 &lt;td>certificate、timestamp、keychain&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Notarize&lt;/td>
 &lt;td>通過 macOS 公證或平台審查&lt;/td>
 &lt;td>staple、gatekeeper 是否通過&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Release&lt;/td>
 &lt;td>發布到 channel 或 download page&lt;/td>
 &lt;td>stable / beta / internal 分流&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Update&lt;/td>
 &lt;td>推送 &lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/update-feed/" data-link-title="Update Feed" data-link-desc="說明桌面與客戶端應用如何透過更新來源取得已簽章版本與回復路徑">Update Feed&lt;/a> 或 delta package&lt;/td>
 &lt;td>feed 簽章、版本相容、回退策略&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Recovery&lt;/td>
 &lt;td>hotfix、rollback channel、停用更新&lt;/td>
 &lt;td>是否能阻止錯誤版本擴散&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Build 階段負責產生平台專屬 artifact。Flutter Desktop、Electron 與 Tauri 的輸出格式不同，但共同要求是每個 artifact 都能追到 commit、workflow run 與 dependency lock。&lt;/p>
&lt;p>Signing 階段負責讓 OS 信任安裝包。Windows code signing certificate、macOS Developer ID、timestamp server 與 Linux package signing key 都是發布能力；secret 應放在受控環境，並限制能觸發 signing job 的分支與 reviewer。&lt;/p>
&lt;p>Notarize 階段負責處理 macOS 信任 gate。macOS app 即使完成簽章，也常需要 notarization 與 stapling；CI 要把 notarization log 保存下來，否則使用者看到 Gatekeeper 警告時很難回溯。&lt;/p>
&lt;p>Release 階段負責把 artifact 放到正確 &lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/release-channel/" data-link-title="Release Channel" data-link-desc="說明 stable、beta、internal 等發行通道如何控制 artifact 接觸到的使用者範圍">Release Channel&lt;/a>。Internal、beta、stable 與 enterprise channel 的 gate 不同；CI/CD 要避免未審核的 beta artifact 被 stable feed 取用。&lt;/p>
&lt;p>Update 階段負責維持升級路徑。&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/update-feed/" data-link-title="Update Feed" data-link-desc="說明桌面與客戶端應用如何透過更新來源取得已簽章版本與回復路徑">Update Feed&lt;/a>、delta package、signature、minimum supported version 與 rollback channel 要一起設計；更新壞掉時，使用者可能卡在需要人工修復的版本。&lt;/p>
&lt;p>Recovery 階段負責止血。桌面客戶端常用方式是撤下 update feed、發布 hotfix、切換 rollback channel、停用 remote feature 或要求最低版本；每種方式都依賴 app 內建相容支援。&lt;/p>
&lt;h2 id="平台差異判讀">平台差異判讀&lt;/h2>
&lt;p>平台差異判讀的責任是讓 CI matrix 對應真實發布風險。桌面發布除了確認「三平台都 build 成功」，還要確認每個平台的安裝、啟動、更新與卸載行為。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>平台&lt;/th>
 &lt;th>高風險點&lt;/th>
 &lt;th>驗證方向&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>macOS&lt;/td>
 &lt;td>Developer ID、notarization、universal binary&lt;/td>
 &lt;td>Gatekeeper、arm64 / x64 啟動&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Windows&lt;/td>
 &lt;td>Authenticode、SmartScreen、installer 權限&lt;/td>
 &lt;td>安裝、更新、卸載、權限提示&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Linux&lt;/td>
 &lt;td>AppImage、deb、rpm、repository key&lt;/td>
 &lt;td>dependency、desktop entry、sandbox&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>這張表的用途是避免平台細節被單一「desktop build」欄位抹平。每個 OS 的失敗代價不同，CI 應保留平台專屬 gate。&lt;/p></description><content:encoded><![CDATA[<p>Desktop client 發布流程的核心責任是讓多平台安裝包可信、可更新、可回復。桌面應用和 web 不同，使用者會下載 installer 或 package 到本機；CI/CD 需要處理平台差異、code signing、notarization、auto-update feed、delta package 與多版本共存。</p>
<h2 id="流程定位">流程定位</h2>
<p>Desktop client 的風險集中在作業系統信任鏈與更新通道。macOS、Windows、Linux 對簽章、安裝包格式與安全提示的要求不同；同一份 source 通常會產生多個平台 artifact，因此 workflow 要把平台 matrix、簽章 secret 與 <a href="/blog/ci/knowledge-cards/release-channel/" data-link-title="Release Channel" data-link-desc="說明 stable、beta、internal 等發行通道如何控制 artifact 接觸到的使用者範圍">Release Channel</a> 拆清楚。</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>責任</th>
          <th>判讀訊號</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Build</td>
          <td>產生 <code>.dmg</code>、<code>.pkg</code>、<code>.msi</code>、AppImage 等</td>
          <td>平台 matrix 是否完整</td>
      </tr>
      <tr>
          <td>Signing</td>
          <td>建立 OS 信任</td>
          <td>certificate、timestamp、keychain</td>
      </tr>
      <tr>
          <td>Notarize</td>
          <td>通過 macOS 公證或平台審查</td>
          <td>staple、gatekeeper 是否通過</td>
      </tr>
      <tr>
          <td>Release</td>
          <td>發布到 channel 或 download page</td>
          <td>stable / beta / internal 分流</td>
      </tr>
      <tr>
          <td>Update</td>
          <td>推送 <a href="/blog/ci/knowledge-cards/update-feed/" data-link-title="Update Feed" data-link-desc="說明桌面與客戶端應用如何透過更新來源取得已簽章版本與回復路徑">Update Feed</a> 或 delta package</td>
          <td>feed 簽章、版本相容、回退策略</td>
      </tr>
      <tr>
          <td>Recovery</td>
          <td>hotfix、rollback channel、停用更新</td>
          <td>是否能阻止錯誤版本擴散</td>
      </tr>
  </tbody>
</table>
<p>Build 階段負責產生平台專屬 artifact。Flutter Desktop、Electron 與 Tauri 的輸出格式不同，但共同要求是每個 artifact 都能追到 commit、workflow run 與 dependency lock。</p>
<p>Signing 階段負責讓 OS 信任安裝包。Windows code signing certificate、macOS Developer ID、timestamp server 與 Linux package signing key 都是發布能力；secret 應放在受控環境，並限制能觸發 signing job 的分支與 reviewer。</p>
<p>Notarize 階段負責處理 macOS 信任 gate。macOS app 即使完成簽章，也常需要 notarization 與 stapling；CI 要把 notarization log 保存下來，否則使用者看到 Gatekeeper 警告時很難回溯。</p>
<p>Release 階段負責把 artifact 放到正確 <a href="/blog/ci/knowledge-cards/release-channel/" data-link-title="Release Channel" data-link-desc="說明 stable、beta、internal 等發行通道如何控制 artifact 接觸到的使用者範圍">Release Channel</a>。Internal、beta、stable 與 enterprise channel 的 gate 不同；CI/CD 要避免未審核的 beta artifact 被 stable feed 取用。</p>
<p>Update 階段負責維持升級路徑。<a href="/blog/ci/knowledge-cards/update-feed/" data-link-title="Update Feed" data-link-desc="說明桌面與客戶端應用如何透過更新來源取得已簽章版本與回復路徑">Update Feed</a>、delta package、signature、minimum supported version 與 rollback channel 要一起設計；更新壞掉時，使用者可能卡在需要人工修復的版本。</p>
<p>Recovery 階段負責止血。桌面客戶端常用方式是撤下 update feed、發布 hotfix、切換 rollback channel、停用 remote feature 或要求最低版本；每種方式都依賴 app 內建相容支援。</p>
<h2 id="平台差異判讀">平台差異判讀</h2>
<p>平台差異判讀的責任是讓 CI matrix 對應真實發布風險。桌面發布除了確認「三平台都 build 成功」，還要確認每個平台的安裝、啟動、更新與卸載行為。</p>
<table>
  <thead>
      <tr>
          <th>平台</th>
          <th>高風險點</th>
          <th>驗證方向</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>macOS</td>
          <td>Developer ID、notarization、universal binary</td>
          <td>Gatekeeper、arm64 / x64 啟動</td>
      </tr>
      <tr>
          <td>Windows</td>
          <td>Authenticode、SmartScreen、installer 權限</td>
          <td>安裝、更新、卸載、權限提示</td>
      </tr>
      <tr>
          <td>Linux</td>
          <td>AppImage、deb、rpm、repository key</td>
          <td>dependency、desktop entry、sandbox</td>
      </tr>
  </tbody>
</table>
<p>這張表的用途是避免平台細節被單一「desktop build」欄位抹平。每個 OS 的失敗代價不同，CI 應保留平台專屬 gate。</p>
<h2 id="update-feed-契約">Update feed 契約</h2>
<p><a href="/blog/ci/knowledge-cards/update-feed/" data-link-title="Update Feed" data-link-desc="說明桌面與客戶端應用如何透過更新來源取得已簽章版本與回復路徑">Update Feed</a> 契約的責任是讓已安裝使用者安全升級。Auto-update 需要簽章、版本比較、channel、最低版本與回退策略共同成立，才能讓新版本 URL 進入 feed。</p>
<ol>
<li>Feed 只指向已簽章且已驗證的 artifact。</li>
<li>Stable feed 只接收 stable release，beta feed 只接收 beta release。</li>
<li>App 啟動時能處理 feed 暫時不可用。</li>
<li>Delta update 失敗時能 fallback 到 full installer。</li>
<li>錯誤版本要能從 feed 撤下，並讓未更新使用者停止取得。</li>
<li>已更新使用者要有 hotfix 或 rollback channel。</li>
</ol>
<p>這些條件讓更新通道具備操作性。若 app 只知道「看到新版就下載」，錯誤 feed 會把事故放大到所有啟動中的使用者。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>Desktop 部署總覽：回 <a href="../">Desktop Client 部署 CI/CD</a>。</li>
<li>App 發布通用觀念：讀 <a href="../../app-deploy/signing-store-rollout-flow/">App 簽章、商店審核與分批發布流程</a>。</li>
<li>簽章術語：讀 <a href="/blog/ci/knowledge-cards/app-signing/" data-link-title="App Signing" data-link-desc="說明行動與桌面應用的簽章憑證如何影響發布能力">App Signing</a>。</li>
</ul>
]]></content:encoded></item><item><title>圖形桌面工具</title><link>https://tarrragon.github.io/blog/linux/tools/gui/</link><pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/linux/tools/gui/</guid><description>&lt;p>有圖形環境時，桌面應用的選擇跟 CLI 工具是不同的判斷：同一個功能（檔案管理、桌面 shell）不同實作拖進來的相依可以差一個數量級，因為有些應用假設某個桌面環境的服務就在旁邊、有些刻意做成桌面無關的獨立程式。在 Hyprland 這類不預設桌面環境的 window manager 上，「加一個 GUI app 的真正成本是它的相依樹」這個判斷特別重要。&lt;/p>
&lt;p>這個系列講的不只是「有哪些桌面工具」，而是選它們時該看什麼：相依足跡、桌面環境耦合、功能相依（掛載 / 縮圖 / 網路這些側欄功能背後各是一個額外套件）。&lt;/p>
&lt;h2 id="文章">文章&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>文章&lt;/th>
 &lt;th>主題&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="desktop-environment-selection/">桌面環境選型：整合度與組裝自由度的取捨&lt;/a>&lt;/td>
 &lt;td>GNOME / KDE / Hyprland / XFCE / Cinnamon 的定位、資源與客製代價、Wayland 判斷&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="gui-file-manager-dependencies/">加圖形檔案管理員：依賴足跡與桌面環境耦合&lt;/a>&lt;/td>
 &lt;td>Thunar / PCManFM-Qt / Nemo 的相依樹實測對照、gvfs 與縮圖的功能相依、選型判準&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="相關">相關&lt;/h2>
&lt;ul>
&lt;li>純終端機下的檔案管理器（&lt;code>yazi&lt;/code> / &lt;code>broot&lt;/code> / &lt;code>ranger&lt;/code>）是另一條路，見 &lt;a href="../cli/">CLI 環境工具&lt;/a> 的檔案管理器段。&lt;/li>
&lt;li>桌面環境本身（GNOME / KDE / Hyprland）怎麼選、各自的擴充生態，見 &lt;a href="desktop-environment-selection/">桌面環境選型&lt;/a>；選了 Hyprland 之後怎麼組裝，見 &lt;a href="https://tarrragon.github.io/blog/linux/dotfile/06-rice-design/" data-link-title="模組六：桌面 Rice 設計" data-link-desc="Hyprland 桌面從能用到好看好用 — 狀態列、啟動器、通知、鎖屏、配色系統的設計與配置">Dotfile 管理：桌面 Rice 設計&lt;/a>。&lt;/li>
&lt;li>在圖形桌面上安裝這些工具前的環境與相依判讀，跟 &lt;a href="../../debug/">除錯與診斷&lt;/a> 的權威狀態紀律同源。&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>有圖形環境時，桌面應用的選擇跟 CLI 工具是不同的判斷：同一個功能（檔案管理、桌面 shell）不同實作拖進來的相依可以差一個數量級，因為有些應用假設某個桌面環境的服務就在旁邊、有些刻意做成桌面無關的獨立程式。在 Hyprland 這類不預設桌面環境的 window manager 上，「加一個 GUI app 的真正成本是它的相依樹」這個判斷特別重要。</p>
<p>這個系列講的不只是「有哪些桌面工具」，而是選它們時該看什麼：相依足跡、桌面環境耦合、功能相依（掛載 / 縮圖 / 網路這些側欄功能背後各是一個額外套件）。</p>
<h2 id="文章">文章</h2>
<table>
  <thead>
      <tr>
          <th>文章</th>
          <th>主題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="desktop-environment-selection/">桌面環境選型：整合度與組裝自由度的取捨</a></td>
          <td>GNOME / KDE / Hyprland / XFCE / Cinnamon 的定位、資源與客製代價、Wayland 判斷</td>
      </tr>
      <tr>
          <td><a href="gui-file-manager-dependencies/">加圖形檔案管理員：依賴足跡與桌面環境耦合</a></td>
          <td>Thunar / PCManFM-Qt / Nemo 的相依樹實測對照、gvfs 與縮圖的功能相依、選型判準</td>
      </tr>
  </tbody>
</table>
<h2 id="相關">相關</h2>
<ul>
<li>純終端機下的檔案管理器（<code>yazi</code> / <code>broot</code> / <code>ranger</code>）是另一條路，見 <a href="../cli/">CLI 環境工具</a> 的檔案管理器段。</li>
<li>桌面環境本身（GNOME / KDE / Hyprland）怎麼選、各自的擴充生態，見 <a href="desktop-environment-selection/">桌面環境選型</a>；選了 Hyprland 之後怎麼組裝，見 <a href="/blog/linux/dotfile/06-rice-design/" data-link-title="模組六：桌面 Rice 設計" data-link-desc="Hyprland 桌面從能用到好看好用 — 狀態列、啟動器、通知、鎖屏、配色系統的設計與配置">Dotfile 管理：桌面 Rice 設計</a>。</li>
<li>在圖形桌面上安裝這些工具前的環境與相依判讀，跟 <a href="../../debug/">除錯與診斷</a> 的權威狀態紀律同源。</li>
</ul>
]]></content:encoded></item><item><title>Desktop Client 部署 CI/CD</title><link>https://tarrragon.github.io/blog/ci/desktop-client-deploy/</link><pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ci/desktop-client-deploy/</guid><description>&lt;p>Desktop Client 部署 CI/CD 的核心責任是把可安裝客戶端安全交付到使用者裝置，並維持可更新與可回退能力。它和 web 發布不同，重點在安裝包簽章、公證、更新通道與多平台相容。&lt;/p>
&lt;h2 id="場域定位">場域定位&lt;/h2>
&lt;p>Desktop client 常見於 Flutter Desktop、Electron、Tauri。部署流程通常要分平台建置（macOS、Windows、Linux），並處理安裝體驗、&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/release-channel/" data-link-title="Release Channel" data-link-desc="說明 stable、beta、internal 等發行通道如何控制 artifact 接觸到的使用者範圍">Release Channel&lt;/a> 更新節奏與版本共存。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>面向&lt;/th>
 &lt;th>Desktop client 部署常見責任&lt;/th>
 &lt;th>判讀訊號&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Build&lt;/td>
 &lt;td>platform-specific bundle / installer&lt;/td>
 &lt;td>各平台產物是否可重現&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Signing&lt;/td>
 &lt;td>code signing、notarization、timestamp&lt;/td>
 &lt;td>安裝與啟動是否受信任&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Release&lt;/td>
 &lt;td>channel、staged rollout、notes&lt;/td>
 &lt;td>更新節奏是否可控&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Update&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/update-feed/" data-link-title="Update Feed" data-link-desc="說明桌面與客戶端應用如何透過更新來源取得已簽章版本與回復路徑">Update Feed&lt;/a>、delta package&lt;/td>
 &lt;td>升級是否穩定可回復&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Recovery&lt;/td>
 &lt;td>hotfix package、rollback channel&lt;/td>
 &lt;td>失敗時是否可快速回退&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="常見注意事項">常見注意事項&lt;/h2>
&lt;ul>
&lt;li>不同 OS 的簽章與公證流程需分開治理。&lt;/li>
&lt;li>Auto-update 要有版本相容策略與 fallback feed。&lt;/li>
&lt;li>崩潰回報與更新成功率應列為發布後 gate。&lt;/li>
&lt;li>若與 Flutter App 共用程式碼，要明確區分 mobile 與 desktop 的發布管線。&lt;/li>
&lt;/ul>
&lt;h2 id="學習路線">學習路線&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>章節&lt;/th>
 &lt;th>主題&lt;/th>
 &lt;th>核心責任&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="signing-notarization-update-flow/">Desktop client 簽章、公證與自動更新流程&lt;/a>&lt;/td>
 &lt;td>Signing, notarization and update&lt;/td>
 &lt;td>管理安裝包信任鏈、更新通道與回復&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;ul>
&lt;li>Desktop 發布主流程：讀 &lt;a href="signing-notarization-update-flow/">Desktop client 簽章、公證與自動更新流程&lt;/a>。&lt;/li>
&lt;li>行動與客戶端通用觀念：讀 &lt;a href="../app-deploy/">App 部署 CI/CD&lt;/a>。&lt;/li>
&lt;li>簽章治理：讀 &lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/app-signing/" data-link-title="App Signing" data-link-desc="說明行動與桌面應用的簽章憑證如何影響發布能力">App Signing&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">Secret Management&lt;/a>。&lt;/li>
&lt;li>失敗處理：讀 &lt;a href="../github-actions-failure-flow/">CI 失敗到修復發布流程&lt;/a>。&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>Desktop Client 部署 CI/CD 的核心責任是把可安裝客戶端安全交付到使用者裝置，並維持可更新與可回退能力。它和 web 發布不同，重點在安裝包簽章、公證、更新通道與多平台相容。</p>
<h2 id="場域定位">場域定位</h2>
<p>Desktop client 常見於 Flutter Desktop、Electron、Tauri。部署流程通常要分平台建置（macOS、Windows、Linux），並處理安裝體驗、<a href="/blog/ci/knowledge-cards/release-channel/" data-link-title="Release Channel" data-link-desc="說明 stable、beta、internal 等發行通道如何控制 artifact 接觸到的使用者範圍">Release Channel</a> 更新節奏與版本共存。</p>
<table>
  <thead>
      <tr>
          <th>面向</th>
          <th>Desktop client 部署常見責任</th>
          <th>判讀訊號</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Build</td>
          <td>platform-specific bundle / installer</td>
          <td>各平台產物是否可重現</td>
      </tr>
      <tr>
          <td>Signing</td>
          <td>code signing、notarization、timestamp</td>
          <td>安裝與啟動是否受信任</td>
      </tr>
      <tr>
          <td>Release</td>
          <td>channel、staged rollout、notes</td>
          <td>更新節奏是否可控</td>
      </tr>
      <tr>
          <td>Update</td>
          <td><a href="/blog/ci/knowledge-cards/update-feed/" data-link-title="Update Feed" data-link-desc="說明桌面與客戶端應用如何透過更新來源取得已簽章版本與回復路徑">Update Feed</a>、delta package</td>
          <td>升級是否穩定可回復</td>
      </tr>
      <tr>
          <td>Recovery</td>
          <td>hotfix package、rollback channel</td>
          <td>失敗時是否可快速回退</td>
      </tr>
  </tbody>
</table>
<h2 id="常見注意事項">常見注意事項</h2>
<ul>
<li>不同 OS 的簽章與公證流程需分開治理。</li>
<li>Auto-update 要有版本相容策略與 fallback feed。</li>
<li>崩潰回報與更新成功率應列為發布後 gate。</li>
<li>若與 Flutter App 共用程式碼，要明確區分 mobile 與 desktop 的發布管線。</li>
</ul>
<h2 id="學習路線">學習路線</h2>
<table>
  <thead>
      <tr>
          <th>章節</th>
          <th>主題</th>
          <th>核心責任</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="signing-notarization-update-flow/">Desktop client 簽章、公證與自動更新流程</a></td>
          <td>Signing, notarization and update</td>
          <td>管理安裝包信任鏈、更新通道與回復</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>Desktop 發布主流程：讀 <a href="signing-notarization-update-flow/">Desktop client 簽章、公證與自動更新流程</a>。</li>
<li>行動與客戶端通用觀念：讀 <a href="../app-deploy/">App 部署 CI/CD</a>。</li>
<li>簽章治理：讀 <a href="/blog/ci/knowledge-cards/app-signing/" data-link-title="App Signing" data-link-desc="說明行動與桌面應用的簽章憑證如何影響發布能力">App Signing</a> 與 <a href="/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">Secret Management</a>。</li>
<li>失敗處理：讀 <a href="../github-actions-failure-flow/">CI 失敗到修復發布流程</a>。</li>
</ul>
]]></content:encoded></item><item><title>Update Feed</title><link>https://tarrragon.github.io/blog/ci/knowledge-cards/update-feed/</link><pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ci/knowledge-cards/update-feed/</guid><description>&lt;p>Update Feed 的核心概念是「告訴已安裝客戶端該取得哪個版本」。它連接 &lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/release-channel/" data-link-title="Release Channel" data-link-desc="說明 stable、beta、internal 等發行通道如何控制 artifact 接觸到的使用者範圍">Release Channel&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/ci/knowledge-cards/app-signing/" data-link-title="App Signing" data-link-desc="說明行動與桌面應用的簽章憑證如何影響發布能力">App Signing&lt;/a>，讓自動更新具備信任與回復能力。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Update Feed 位在 signed artifact、release channel 與已安裝 app 之間，常包含版本號、下載 URL、signature、checksum、release notes 與最低支援版本。&lt;/p>
&lt;h2 id="可觀察訊號">可觀察訊號&lt;/h2>
&lt;ul>
&lt;li>客戶端需要自動偵測新版本。&lt;/li>
&lt;li>beta 與 stable 使用者需要看到不同版本。&lt;/li>
&lt;li>錯誤版本需要從更新來源撤下。&lt;/li>
&lt;/ul>
&lt;h2 id="接近真實服務的例子">接近真實服務的例子&lt;/h2>
&lt;p>Electron app 啟動時讀取 stable feed，取得最新 signed installer 與 signature。若新版本 crash rate 升高，團隊先撤下 feed 指向，讓未更新使用者停止取得錯誤版本。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Update Feed 要定義簽章驗證、channel 分流、版本比較、fallback installer、撤版策略與 telemetry，讓已安裝客戶端安全升級。&lt;/p></description><content:encoded><![CDATA[<p>Update Feed 的核心概念是「告訴已安裝客戶端該取得哪個版本」。它連接 <a href="/blog/ci/knowledge-cards/release-channel/" data-link-title="Release Channel" data-link-desc="說明 stable、beta、internal 等發行通道如何控制 artifact 接觸到的使用者範圍">Release Channel</a> 與 <a href="/blog/ci/knowledge-cards/app-signing/" data-link-title="App Signing" data-link-desc="說明行動與桌面應用的簽章憑證如何影響發布能力">App Signing</a>，讓自動更新具備信任與回復能力。</p>
<h2 id="概念位置">概念位置</h2>
<p>Update Feed 位在 signed artifact、release channel 與已安裝 app 之間，常包含版本號、下載 URL、signature、checksum、release notes 與最低支援版本。</p>
<h2 id="可觀察訊號">可觀察訊號</h2>
<ul>
<li>客戶端需要自動偵測新版本。</li>
<li>beta 與 stable 使用者需要看到不同版本。</li>
<li>錯誤版本需要從更新來源撤下。</li>
</ul>
<h2 id="接近真實服務的例子">接近真實服務的例子</h2>
<p>Electron app 啟動時讀取 stable feed，取得最新 signed installer 與 signature。若新版本 crash rate 升高，團隊先撤下 feed 指向，讓未更新使用者停止取得錯誤版本。</p>
<h2 id="設計責任">設計責任</h2>
<p>Update Feed 要定義簽章驗證、channel 分流、版本比較、fallback installer、撤版策略與 telemetry，讓已安裝客戶端安全升級。</p>
]]></content:encoded></item><item><title>GUI 應用的安裝驗證：拆包、首跑對話框與播放判讀</title><link>https://tarrragon.github.io/blog/linux/install/gui-apps-install-verify/</link><pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/linux/install/gui-apps-install-verify/</guid><description>&lt;p>GUI 應用的安裝驗證跟 CLI 工具走不同的判讀鏈：CLI 工具裝完 &lt;code>command -v&lt;/code> 加一次試跑就能定案，GUI 應用則有三個 CLI 沒有的失敗層——依賴鏈拆包（裝了本體、缺功能模組）、首跑同意對話框（程式要求使用者決策才繼續）、播放輸出鏈（視窗有了、聲音或畫面沒有）。這三層都有各自的權威判讀位置，本篇以一輪 VM 實測（檔案管理器、瀏覽器、媒體播放器、音樂串流）把它們走一遍。&lt;/p>
&lt;h2 id="拆包生態裝了本體不等於裝了功能">拆包生態：裝了本體不等於裝了功能&lt;/h2>
&lt;p>發行版為了控制依賴體積，會把一個應用的核心跟功能模組拆成多個套件，預設只裝核心。這個設計讓「安裝成功」跟「功能可用」變成兩件事，而缺件的症狀往往是靜默的：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>VLC 的解碼器是獨立 plugin&lt;/strong>：Arch 的 &lt;code>vlc&lt;/code> 本體開得起來、UI 完整，播 H.264 影片卻回報 &lt;code>Codec 'h264' is not supported&lt;/code>——解碼能力在 &lt;code>vlc-plugin-ffmpeg&lt;/code>（或整組 &lt;code>vlc-plugins-all&lt;/code>）。judgment 訊號是「應用正常啟動、特定格式失敗」，權威來源是應用自己的 log（&lt;code>vlc --verbose=2&lt;/code>）。&lt;/li>
&lt;li>&lt;strong>pipewire 的 session manager 是獨立套件&lt;/strong>：&lt;code>pipewire&lt;/code> 常被依賴鏈拉進來，但沒有 &lt;code>wireplumber&lt;/code> 就沒有人建立音訊 graph——daemon 在跑、&lt;code>wpctl status&lt;/code> 的 Sinks 段是空的、所有應用無聲且不報錯。補 &lt;code>wireplumber&lt;/code> + &lt;code>pipewire-pulse&lt;/code>（多數 GUI 應用走 PulseAudio API）後輸出裝置立即出現。&lt;/li>
&lt;li>&lt;strong>optional dependency 不會自動安裝&lt;/strong>：套件宣告的 optdepends 是「裝了會多什麼功能」的提示、不是安裝動作。影片縮圖、壓縮格式支援、硬體加速常落在這層，&lt;code>pacman -Qi &amp;lt;pkg&amp;gt;&lt;/code> 的 Optional Deps 段列出哪些沒裝。&lt;/li>
&lt;/ul>
&lt;p>判讀原則：GUI 應用「開得起來但某個功能不動」時，先查發行版有沒有把那個功能拆成獨立套件，再懷疑設定或相容性。&lt;/p>
&lt;h2 id="首跑同意對話框程式在等使用者決策">首跑同意對話框：程式在等使用者決策&lt;/h2>
&lt;p>不少 GUI 應用第一次啟動會彈出需要使用者決策的對話框，最典型的是 VLC 的「Privacy and Network Access Policy」：&lt;/p>
&lt;p>VLC 聲明自己不蒐集、不傳輸任何個人資料，但它能自動向第三方網路服務抓取播放清單裡媒體的中繼資料（封面圖、曲名、演出者）——這個行為等於把「你在播哪些檔案」暴露給第三方服務，所以 VLC 開發者要求使用者明示同意（Allow metadata network access 勾選框、預設勾選）後才允許自動連網。&lt;/p>
&lt;p>這個對話框的判讀是用途導向：拿 VLC 播本機影片、看下載的影片檔，中繼資料抓取沒有用處、取消勾選讓播放器完全離線工作；拿它管理音樂庫、想要自動補封面跟曲目資訊，才需要同意。同意與否都能在偏好設定（Privacy / Network Interaction）事後改。&lt;/p>
&lt;p>首跑對話框對自動化流程有一層額外影響：無人值守安裝驗證時，應用會停在對話框等輸入、腳本側只看到「程式起了但沒繼續」。VLC 把這兩個決策記在 &lt;code>~/.config/vlc/vlcrc&lt;/code> 的 &lt;code>qt-privacy-ask&lt;/code> 與 &lt;code>metadata-network-access&lt;/code> 兩個鍵——首跑後檔案才生成，而且 VLC 退出時會整檔重寫（幾千行的完整設定 dump），把它納入 dotfile 版控會持續產生無意義的 diff，比較合理的處理是讓首跑對話框留給人、或在自動化腳本裡預先寫入只含這兩鍵的最小 vlcrc。&lt;/p>
&lt;p>同型的首跑決策也出現在瀏覽器（預設瀏覽器詢問、錯誤回報同意）跟大型 GUI 應用（遙測同意）。它們的共通判讀：對話框問的是「要不要讓程式自動連外 / 回傳資料」，答案取決於這台機器的用途與隱私要求，安裝驗證流程要把「首跑會有互動」納入預期、不是當成故障。&lt;/p>
&lt;h2 id="播放驗證鏈三個權威位置">播放驗證鏈：三個權威位置&lt;/h2>
&lt;p>「有沒有真的在播」的驗證不靠肉眼跟喇叭，三個權威位置各管一段：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>驗證對象&lt;/th>
 &lt;th>權威來源&lt;/th>
 &lt;th>工具與判準&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>視窗存在&lt;/td>
 &lt;td>compositor 的視窗表&lt;/td>
 &lt;td>&lt;code>hyprctl clients&lt;/code> 有該應用的 class 條目&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>音訊真的在出&lt;/td>
 &lt;td>音訊伺服器 graph&lt;/td>
 &lt;td>&lt;code>wpctl status&lt;/code> Streams 段有該應用的 stream 且 &lt;code>[active]&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>失敗的原因&lt;/td>
 &lt;td>程式自己的 log&lt;/td>
 &lt;td>&lt;code>vlc --verbose=2&lt;/code>、瀏覽器 &lt;code>--enable-logging=stderr&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>把「管線通不通」跟「應用會不會播」拆開驗證能大幅縮短歸因：先用本機音檔 &lt;code>pw-play &amp;lt;file&amp;gt;&lt;/code> 打通音訊路徑（stream 出現 &lt;code>[active]&lt;/code> 代表 guest 側無誤），再測應用層；應用層失敗就跟管線無關，往解碼器、DRM、應用 log 查。串流再多拆一層：先用無 DRM 的串流（一般影音網站）確立網路串流基線，DRM 內容（Spotify、Netflix 類）的失敗才能歸因到 DRM 層——DRM 在非 x86_64 架構的可用性判讀見 &lt;a href="../platform-divergence-map/">平台與發行版差異的判讀地圖&lt;/a> 的套件存在性段。&lt;/p>
&lt;h2 id="vm-特有硬體解碼回退">VM 特有：硬體解碼回退&lt;/h2>
&lt;p>在 VM 裡播放影片，第一次開檔常會閃一個錯誤對話框（&lt;code>failed to create video output&lt;/code>）然後正常播放——這是硬體解碼回退的痕跡：播放器預設先嘗試硬體加速解碼（VDPAU / VAAPI），虛擬 GPU（如 virtio-gpu）沒有視訊解碼能力，嘗試失敗後回退軟體解碼重建輸出。log 上的特徵是一次性的 decoder error 加上之後穩定的 &lt;code>avcodec decoder&lt;/code> 軟體解碼行；實體機器有 GPU 解碼時不會出現。VM 裡想要乾淨啟動，在播放器偏好設定停用 hardware-accelerated decoding 即可——這是機器特性設定，適合留在該機器本機、不進共用 dotfile。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;ul>
&lt;li>套件在這個平台 / 架構存不存在、名字叫什麼：&lt;a href="../platform-divergence-map/">平台與發行版差異的判讀地圖&lt;/a>&lt;/li>
&lt;li>音訊、行程、服務狀態的權威判讀：&lt;a href="../../debug/">Linux 除錯與診斷&lt;/a>&lt;/li>
&lt;li>GUI 應用清單怎麼進 bootstrap：&lt;a href="https://tarrragon.github.io/blog/linux/dotfile/08-sync-bootstrap/bootstrap-script-packages/" data-link-title="Bootstrap Script 與套件清單管理" data-link-desc="寫 dotfile 的 install script、或整理「這台機器裝了什麼」的套件清單時回來讀">模組八：Bootstrap script 設計&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>GUI 應用的安裝驗證跟 CLI 工具走不同的判讀鏈：CLI 工具裝完 <code>command -v</code> 加一次試跑就能定案，GUI 應用則有三個 CLI 沒有的失敗層——依賴鏈拆包（裝了本體、缺功能模組）、首跑同意對話框（程式要求使用者決策才繼續）、播放輸出鏈（視窗有了、聲音或畫面沒有）。這三層都有各自的權威判讀位置，本篇以一輪 VM 實測（檔案管理器、瀏覽器、媒體播放器、音樂串流）把它們走一遍。</p>
<h2 id="拆包生態裝了本體不等於裝了功能">拆包生態：裝了本體不等於裝了功能</h2>
<p>發行版為了控制依賴體積，會把一個應用的核心跟功能模組拆成多個套件，預設只裝核心。這個設計讓「安裝成功」跟「功能可用」變成兩件事，而缺件的症狀往往是靜默的：</p>
<ul>
<li><strong>VLC 的解碼器是獨立 plugin</strong>：Arch 的 <code>vlc</code> 本體開得起來、UI 完整，播 H.264 影片卻回報 <code>Codec 'h264' is not supported</code>——解碼能力在 <code>vlc-plugin-ffmpeg</code>（或整組 <code>vlc-plugins-all</code>）。judgment 訊號是「應用正常啟動、特定格式失敗」，權威來源是應用自己的 log（<code>vlc --verbose=2</code>）。</li>
<li><strong>pipewire 的 session manager 是獨立套件</strong>：<code>pipewire</code> 常被依賴鏈拉進來，但沒有 <code>wireplumber</code> 就沒有人建立音訊 graph——daemon 在跑、<code>wpctl status</code> 的 Sinks 段是空的、所有應用無聲且不報錯。補 <code>wireplumber</code> + <code>pipewire-pulse</code>（多數 GUI 應用走 PulseAudio API）後輸出裝置立即出現。</li>
<li><strong>optional dependency 不會自動安裝</strong>：套件宣告的 optdepends 是「裝了會多什麼功能」的提示、不是安裝動作。影片縮圖、壓縮格式支援、硬體加速常落在這層，<code>pacman -Qi &lt;pkg&gt;</code> 的 Optional Deps 段列出哪些沒裝。</li>
</ul>
<p>判讀原則：GUI 應用「開得起來但某個功能不動」時，先查發行版有沒有把那個功能拆成獨立套件，再懷疑設定或相容性。</p>
<h2 id="首跑同意對話框程式在等使用者決策">首跑同意對話框：程式在等使用者決策</h2>
<p>不少 GUI 應用第一次啟動會彈出需要使用者決策的對話框，最典型的是 VLC 的「Privacy and Network Access Policy」：</p>
<p>VLC 聲明自己不蒐集、不傳輸任何個人資料，但它能自動向第三方網路服務抓取播放清單裡媒體的中繼資料（封面圖、曲名、演出者）——這個行為等於把「你在播哪些檔案」暴露給第三方服務，所以 VLC 開發者要求使用者明示同意（Allow metadata network access 勾選框、預設勾選）後才允許自動連網。</p>
<p>這個對話框的判讀是用途導向：拿 VLC 播本機影片、看下載的影片檔，中繼資料抓取沒有用處、取消勾選讓播放器完全離線工作；拿它管理音樂庫、想要自動補封面跟曲目資訊，才需要同意。同意與否都能在偏好設定（Privacy / Network Interaction）事後改。</p>
<p>首跑對話框對自動化流程有一層額外影響：無人值守安裝驗證時，應用會停在對話框等輸入、腳本側只看到「程式起了但沒繼續」。VLC 把這兩個決策記在 <code>~/.config/vlc/vlcrc</code> 的 <code>qt-privacy-ask</code> 與 <code>metadata-network-access</code> 兩個鍵——首跑後檔案才生成，而且 VLC 退出時會整檔重寫（幾千行的完整設定 dump），把它納入 dotfile 版控會持續產生無意義的 diff，比較合理的處理是讓首跑對話框留給人、或在自動化腳本裡預先寫入只含這兩鍵的最小 vlcrc。</p>
<p>同型的首跑決策也出現在瀏覽器（預設瀏覽器詢問、錯誤回報同意）跟大型 GUI 應用（遙測同意）。它們的共通判讀：對話框問的是「要不要讓程式自動連外 / 回傳資料」，答案取決於這台機器的用途與隱私要求，安裝驗證流程要把「首跑會有互動」納入預期、不是當成故障。</p>
<h2 id="播放驗證鏈三個權威位置">播放驗證鏈：三個權威位置</h2>
<p>「有沒有真的在播」的驗證不靠肉眼跟喇叭，三個權威位置各管一段：</p>
<table>
  <thead>
      <tr>
          <th>驗證對象</th>
          <th>權威來源</th>
          <th>工具與判準</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>視窗存在</td>
          <td>compositor 的視窗表</td>
          <td><code>hyprctl clients</code> 有該應用的 class 條目</td>
      </tr>
      <tr>
          <td>音訊真的在出</td>
          <td>音訊伺服器 graph</td>
          <td><code>wpctl status</code> Streams 段有該應用的 stream 且 <code>[active]</code></td>
      </tr>
      <tr>
          <td>失敗的原因</td>
          <td>程式自己的 log</td>
          <td><code>vlc --verbose=2</code>、瀏覽器 <code>--enable-logging=stderr</code></td>
      </tr>
  </tbody>
</table>
<p>把「管線通不通」跟「應用會不會播」拆開驗證能大幅縮短歸因：先用本機音檔 <code>pw-play &lt;file&gt;</code> 打通音訊路徑（stream 出現 <code>[active]</code> 代表 guest 側無誤），再測應用層；應用層失敗就跟管線無關，往解碼器、DRM、應用 log 查。串流再多拆一層：先用無 DRM 的串流（一般影音網站）確立網路串流基線，DRM 內容（Spotify、Netflix 類）的失敗才能歸因到 DRM 層——DRM 在非 x86_64 架構的可用性判讀見 <a href="../platform-divergence-map/">平台與發行版差異的判讀地圖</a> 的套件存在性段。</p>
<h2 id="vm-特有硬體解碼回退">VM 特有：硬體解碼回退</h2>
<p>在 VM 裡播放影片，第一次開檔常會閃一個錯誤對話框（<code>failed to create video output</code>）然後正常播放——這是硬體解碼回退的痕跡：播放器預設先嘗試硬體加速解碼（VDPAU / VAAPI），虛擬 GPU（如 virtio-gpu）沒有視訊解碼能力，嘗試失敗後回退軟體解碼重建輸出。log 上的特徵是一次性的 decoder error 加上之後穩定的 <code>avcodec decoder</code> 軟體解碼行；實體機器有 GPU 解碼時不會出現。VM 裡想要乾淨啟動，在播放器偏好設定停用 hardware-accelerated decoding 即可——這是機器特性設定，適合留在該機器本機、不進共用 dotfile。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>套件在這個平台 / 架構存不存在、名字叫什麼：<a href="../platform-divergence-map/">平台與發行版差異的判讀地圖</a></li>
<li>音訊、行程、服務狀態的權威判讀：<a href="../../debug/">Linux 除錯與診斷</a></li>
<li>GUI 應用清單怎麼進 bootstrap：<a href="/blog/linux/dotfile/08-sync-bootstrap/bootstrap-script-packages/" data-link-title="Bootstrap Script 與套件清單管理" data-link-desc="寫 dotfile 的 install script、或整理「這台機器裝了什麼」的套件清單時回來讀">模組八：Bootstrap script 設計</a></li>
</ul>
]]></content:encoded></item></channel></rss>