<?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>Wofi on Tarragon</title><link>https://tarrragon.github.io/blog/tags/wofi/</link><description>Recent content in Wofi on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 29 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/wofi/index.xml" rel="self" type="application/rss+xml"/><item><title>桌面 Shell 元件：狀態列、啟動器與通知</title><link>https://tarrragon.github.io/blog/linux/dotfile/06-rice-design/desktop-shell-components/</link><pubDate>Mon, 29 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/linux/dotfile/06-rice-design/desktop-shell-components/</guid><description>&lt;p>完整桌面環境（GNOME、KDE）把這些元件整合在一起出貨。平鋪式 WM 的桌面是拼裝的——每個位置自己選工具：&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>Waybar, Eww, AGS&lt;/td>
 &lt;td>JSON/JSONC, Yuck, JS&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>啟動器&lt;/td>
 &lt;td>Wofi, Rofi (wayland), Fuzzel&lt;/td>
 &lt;td>CSS + 設定檔&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>通知&lt;/td>
 &lt;td>Mako, Dunst, SwayNC&lt;/td>
 &lt;td>INI/TOML&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>鎖屏&lt;/td>
 &lt;td>Hyprlock, Swaylock&lt;/td>
 &lt;td>自定義格式&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>桌布&lt;/td>
 &lt;td>Hyprpaper, Swww, Mpvpaper&lt;/td>
 &lt;td>自定義格式&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>剪貼簿&lt;/td>
 &lt;td>wl-clipboard + Cliphist&lt;/td>
 &lt;td>CLI&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>螢幕截圖&lt;/td>
 &lt;td>Grimblast, Grim + Slurp&lt;/td>
 &lt;td>CLI&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Caelestia 這類「desktop shell 專案」做的就是把上述元件統一設計、統一配色、統一出貨，省去自己一個個挑的功夫。它用的是 Quickshell（QML 框架）把所有元件包成一套風格一致的桌面。本模組教的是自己組裝的方式——理解各元件的配置，之後要用 Caelestia 或自己拼都能做。&lt;/p>
&lt;h2 id="waybar狀態列">Waybar：狀態列&lt;/h2>
&lt;p>Waybar 是 Hyprland 桌面最常用的狀態列。配置在 &lt;code>~/.config/waybar/&lt;/code>，分兩個檔案：&lt;code>config.jsonc&lt;/code>（結構和模組）和 &lt;code>style.css&lt;/code>（外觀）。&lt;/p>
&lt;h3 id="結構配置">結構配置&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-jsonc" data-lang="jsonc">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1">// ~/.config/waybar/config.jsonc
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;layer&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;top&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;position&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;top&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;height&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">36&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;spacing&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> &lt;span class="c1">// 左中右三區塊各放哪些模組
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nt">&amp;#34;modules-left&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;hyprland/workspaces&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;hyprland/window&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;modules-center&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;clock&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;modules-right&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;pulseaudio&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;network&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;cpu&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;memory&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;battery&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;tray&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> &lt;span class="c1">// 各模組設定
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nt">&amp;#34;hyprland/workspaces&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;format&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;{id}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;on-click&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;activate&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;clock&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;format&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;{:%H:%M}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">20&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;format-alt&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;{:%Y-%m-%d %H:%M}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">21&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;tooltip-format&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;tt&amp;gt;{calendar}&amp;lt;/tt&amp;gt;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">22&lt;/span>&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">23&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;battery&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">24&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;format&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;{capacity}% {icon}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">25&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;format-icons&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">26&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;states&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">27&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;warning&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">30&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">28&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;critical&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">15&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">29&lt;/span>&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">30&lt;/span>&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">31&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;network&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">32&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;format-wifi&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;{essid} ({signalStrength}%)&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">33&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;format-ethernet&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;{ifname}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">34&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;format-disconnected&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Disconnected&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">35&lt;/span>&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">36&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;pulseaudio&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">37&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;format&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;{volume}%&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">38&lt;/span>&lt;span class="cl"> &lt;span class="nt">&amp;#34;on-click&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;pavucontrol&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">39&lt;/span>&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">40&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>format&lt;/code> 欄位裡的 icon 字元來自 Nerd Font——&lt;a href="https://tarrragon.github.io/blog/linux/dotfile/03-terminal-ecosystem/" data-link-title="模組三：終端機與編輯器" data-link-desc="終端機相關工具的配置檔散落在不同位置、不確定哪些該進 dotfile repo 時回來讀">終端機與編輯器&lt;/a>提到的字型安裝是這裡正常顯示的前提。&lt;/p>
&lt;h3 id="外觀-css">外觀 CSS&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-css" data-lang="css">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c">/* ~/.config/waybar/style.css */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="o">*&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> &lt;span class="k">font-family&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;MesloLGS Nerd Font&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">monospace&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> &lt;span class="k">font-size&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">13&lt;/span>&lt;span class="kt">px&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="nt">window&lt;/span>&lt;span class="p">#&lt;/span>&lt;span class="nn">waybar&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> &lt;span class="k">background-color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">rgba&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">30&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">30&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">46&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.85&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> &lt;span class="k">color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mh">#cdd6f4&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">&lt;span class="p">#&lt;/span>&lt;span class="nn">workspaces&lt;/span> &lt;span class="nt">button&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl"> &lt;span class="k">padding&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="mi">8&lt;/span>&lt;span class="kt">px&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl"> &lt;span class="k">color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mh">#6c7086&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl"> &lt;span class="k">border-radius&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">6&lt;/span>&lt;span class="kt">px&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl">&lt;span class="p">#&lt;/span>&lt;span class="nn">workspaces&lt;/span> &lt;span class="nt">button&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nc">active&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">20&lt;/span>&lt;span class="cl"> &lt;span class="k">color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mh">#cdd6f4&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">21&lt;/span>&lt;span class="cl"> &lt;span class="k">background&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">rgba&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">137&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">180&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">250&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">0.2&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">22&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">23&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">24&lt;/span>&lt;span class="cl">&lt;span class="p">#&lt;/span>&lt;span class="nn">clock&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="p">#&lt;/span>&lt;span class="nn">battery&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="p">#&lt;/span>&lt;span class="nn">network&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="p">#&lt;/span>&lt;span class="nn">pulseaudio&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">25&lt;/span>&lt;span class="cl"> &lt;span class="k">padding&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="kt">px&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">26&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">27&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">28&lt;/span>&lt;span class="cl">&lt;span class="p">#&lt;/span>&lt;span class="nn">battery&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nc">warning&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">29&lt;/span>&lt;span class="cl"> &lt;span class="k">color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mh">#f9e2af&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">30&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">31&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">32&lt;/span>&lt;span class="cl">&lt;span class="p">#&lt;/span>&lt;span class="nn">battery&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nc">critical&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">33&lt;/span>&lt;span class="cl"> &lt;span class="k">color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mh">#f38ba8&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">34&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>CSS 裡的色碼（&lt;code>#cdd6f4&lt;/code>、&lt;code>#89b4fa&lt;/code>、&lt;code>#f38ba8&lt;/code>）來自配色方案（這個範例用的是 Catppuccin Mocha）。統一使用同一套色碼是 rice 視覺協調的基礎。&lt;/p>
&lt;p>Config 裡的字族名必須跟系統實際安裝的字族逐字相符。Nerd Font 的圖示落在專屬碼位範圍，只有對應的那支字帶這些 glyph——指定一個沒裝的字族名，文字排版引擎找不到 glyph 就會顯示豆腐方塊。確認實裝字族名的方式：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">fc-list &lt;span class="p">|&lt;/span> grep -i meslo
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c1"># MesloLGSNerdFont-Regular.ttf: &amp;#34;MesloLGS Nerd Font&amp;#34;:style=Regular&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>引號內的字串是 config 該填的字族名。&lt;/p>
&lt;p>同一份 Waybar config 能同時服務筆電、桌機與 VM，靠的是模組對缺少硬體的自動退化：&lt;code>battery&lt;/code> 在沒有電池的機器直接隱藏該模組、不報錯也不留空位；&lt;code>pulseaudio&lt;/code> 在沒有音訊服務時顯示為空；&lt;code>network&lt;/code> 顯示當下實際在用的介面。不必為不同機器維護多份 config——把可能用到的模組都列上，用不到的那台自己消失。&lt;/p></description><content:encoded><![CDATA[<p>完整桌面環境（GNOME、KDE）把這些元件整合在一起出貨。平鋪式 WM 的桌面是拼裝的——每個位置自己選工具：</p>
<table>
  <thead>
      <tr>
          <th>功能</th>
          <th>常見工具</th>
          <th>配置格式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>狀態列</td>
          <td>Waybar, Eww, AGS</td>
          <td>JSON/JSONC, Yuck, JS</td>
      </tr>
      <tr>
          <td>啟動器</td>
          <td>Wofi, Rofi (wayland), Fuzzel</td>
          <td>CSS + 設定檔</td>
      </tr>
      <tr>
          <td>通知</td>
          <td>Mako, Dunst, SwayNC</td>
          <td>INI/TOML</td>
      </tr>
      <tr>
          <td>鎖屏</td>
          <td>Hyprlock, Swaylock</td>
          <td>自定義格式</td>
      </tr>
      <tr>
          <td>桌布</td>
          <td>Hyprpaper, Swww, Mpvpaper</td>
          <td>自定義格式</td>
      </tr>
      <tr>
          <td>剪貼簿</td>
          <td>wl-clipboard + Cliphist</td>
          <td>CLI</td>
      </tr>
      <tr>
          <td>螢幕截圖</td>
          <td>Grimblast, Grim + Slurp</td>
          <td>CLI</td>
      </tr>
  </tbody>
</table>
<p>Caelestia 這類「desktop shell 專案」做的就是把上述元件統一設計、統一配色、統一出貨，省去自己一個個挑的功夫。它用的是 Quickshell（QML 框架）把所有元件包成一套風格一致的桌面。本模組教的是自己組裝的方式——理解各元件的配置，之後要用 Caelestia 或自己拼都能做。</p>
<h2 id="waybar狀態列">Waybar：狀態列</h2>
<p>Waybar 是 Hyprland 桌面最常用的狀態列。配置在 <code>~/.config/waybar/</code>，分兩個檔案：<code>config.jsonc</code>（結構和模組）和 <code>style.css</code>（外觀）。</p>
<h3 id="結構配置">結構配置</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" data-lang="jsonc"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// ~/.config/waybar/config.jsonc
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span><span class="p">{</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    <span class="nt">&#34;layer&#34;</span><span class="p">:</span> <span class="s2">&#34;top&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="nt">&#34;position&#34;</span><span class="p">:</span> <span class="s2">&#34;top&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="nt">&#34;height&#34;</span><span class="p">:</span> <span class="mi">36</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    <span class="nt">&#34;spacing&#34;</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="c1">// 左中右三區塊各放哪些模組
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"></span>    <span class="nt">&#34;modules-left&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;hyprland/workspaces&#34;</span><span class="p">,</span> <span class="s2">&#34;hyprland/window&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="nt">&#34;modules-center&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;clock&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="nt">&#34;modules-right&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;pulseaudio&#34;</span><span class="p">,</span> <span class="s2">&#34;network&#34;</span><span class="p">,</span> <span class="s2">&#34;cpu&#34;</span><span class="p">,</span> <span class="s2">&#34;memory&#34;</span><span class="p">,</span> <span class="s2">&#34;battery&#34;</span><span class="p">,</span> <span class="s2">&#34;tray&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">    <span class="c1">// 各模組設定
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="c1"></span>    <span class="nt">&#34;hyprland/workspaces&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">        <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{id}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">        <span class="nt">&#34;on-click&#34;</span><span class="p">:</span> <span class="s2">&#34;activate&#34;</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">    <span class="nt">&#34;clock&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">        <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{:%H:%M}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">        <span class="nt">&#34;format-alt&#34;</span><span class="p">:</span> <span class="s2">&#34;{:%Y-%m-%d %H:%M}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">        <span class="nt">&#34;tooltip-format&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;tt&gt;{calendar}&lt;/tt&gt;&#34;</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">    <span class="nt">&#34;battery&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">        <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{capacity}% {icon}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">        <span class="nt">&#34;format-icons&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">        <span class="nt">&#34;states&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl">            <span class="nt">&#34;warning&#34;</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl">            <span class="nt">&#34;critical&#34;</span><span class="p">:</span> <span class="mi">15</span>
</span></span><span class="line"><span class="ln">29</span><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="ln">30</span><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="ln">31</span><span class="cl">    <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">32</span><span class="cl">        <span class="nt">&#34;format-wifi&#34;</span><span class="p">:</span> <span class="s2">&#34;{essid} ({signalStrength}%)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl">        <span class="nt">&#34;format-ethernet&#34;</span><span class="p">:</span> <span class="s2">&#34;{ifname}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">34</span><span class="cl">        <span class="nt">&#34;format-disconnected&#34;</span><span class="p">:</span> <span class="s2">&#34;Disconnected&#34;</span>
</span></span><span class="line"><span class="ln">35</span><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="ln">36</span><span class="cl">    <span class="nt">&#34;pulseaudio&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">37</span><span class="cl">        <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{volume}%&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">38</span><span class="cl">        <span class="nt">&#34;on-click&#34;</span><span class="p">:</span> <span class="s2">&#34;pavucontrol&#34;</span>
</span></span><span class="line"><span class="ln">39</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">40</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p><code>format</code> 欄位裡的 icon 字元來自 Nerd Font——<a href="/blog/linux/dotfile/03-terminal-ecosystem/" data-link-title="模組三：終端機與編輯器" data-link-desc="終端機相關工具的配置檔散落在不同位置、不確定哪些該進 dotfile repo 時回來讀">終端機與編輯器</a>提到的字型安裝是這裡正常顯示的前提。</p>
<h3 id="外觀-css">外觀 CSS</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c">/* ~/.config/waybar/style.css */</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="o">*</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="k">font-family</span><span class="p">:</span> <span class="s2">&#34;MesloLGS Nerd Font&#34;</span><span class="p">,</span> <span class="kc">monospace</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="k">font-size</span><span class="p">:</span> <span class="mi">13</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="nt">window</span><span class="p">#</span><span class="nn">waybar</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="k">background-color</span><span class="p">:</span> <span class="nb">rgba</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">46</span><span class="p">,</span> <span class="mf">0.85</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="k">color</span><span class="p">:</span> <span class="mh">#cdd6f4</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="p">#</span><span class="nn">workspaces</span> <span class="nt">button</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">    <span class="k">padding</span><span class="p">:</span> <span class="mi">0</span> <span class="mi">8</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">    <span class="k">color</span><span class="p">:</span> <span class="mh">#6c7086</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">    <span class="k">border-radius</span><span class="p">:</span> <span class="mi">6</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="p">#</span><span class="nn">workspaces</span> <span class="nt">button</span><span class="p">.</span><span class="nc">active</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">    <span class="k">color</span><span class="p">:</span> <span class="mh">#cdd6f4</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">    <span class="k">background</span><span class="p">:</span> <span class="nb">rgba</span><span class="p">(</span><span class="mi">137</span><span class="p">,</span> <span class="mi">180</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="p">#</span><span class="nn">clock</span><span class="o">,</span> <span class="p">#</span><span class="nn">battery</span><span class="o">,</span> <span class="p">#</span><span class="nn">network</span><span class="o">,</span> <span class="p">#</span><span class="nn">pulseaudio</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">    <span class="k">padding</span><span class="p">:</span> <span class="mi">0</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl">
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="p">#</span><span class="nn">battery</span><span class="p">.</span><span class="nc">warning</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">29</span><span class="cl">    <span class="k">color</span><span class="p">:</span> <span class="mh">#f9e2af</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">31</span><span class="cl">
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="p">#</span><span class="nn">battery</span><span class="p">.</span><span class="nc">critical</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl">    <span class="k">color</span><span class="p">:</span> <span class="mh">#f38ba8</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>CSS 裡的色碼（<code>#cdd6f4</code>、<code>#89b4fa</code>、<code>#f38ba8</code>）來自配色方案（這個範例用的是 Catppuccin Mocha）。統一使用同一套色碼是 rice 視覺協調的基礎。</p>
<p>Config 裡的字族名必須跟系統實際安裝的字族逐字相符。Nerd Font 的圖示落在專屬碼位範圍，只有對應的那支字帶這些 glyph——指定一個沒裝的字族名，文字排版引擎找不到 glyph 就會顯示豆腐方塊。確認實裝字族名的方式：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">fc-list <span class="p">|</span> grep -i meslo
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"># MesloLGSNerdFont-Regular.ttf: &#34;MesloLGS Nerd Font&#34;:style=Regular</span></span></span></code></pre></div><p>引號內的字串是 config 該填的字族名。</p>
<p>同一份 Waybar config 能同時服務筆電、桌機與 VM，靠的是模組對缺少硬體的自動退化：<code>battery</code> 在沒有電池的機器直接隱藏該模組、不報錯也不留空位；<code>pulseaudio</code> 在沒有音訊服務時顯示為空；<code>network</code> 顯示當下實際在用的介面。不必為不同機器維護多份 config——把可能用到的模組都列上，用不到的那台自己消失。</p>
<h2 id="wofi--rofi啟動器">Wofi / Rofi：啟動器</h2>
<p>啟動器是按快捷鍵彈出的搜尋框，用來啟動應用程式、執行指令、搜尋檔案。</p>
<p>Wofi（Wayland 原生）配置：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># ~/.config/wofi/config</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="na">show</span><span class="o">=</span><span class="s">drun</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="na">width</span><span class="o">=</span><span class="s">600</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="na">height</span><span class="o">=</span><span class="s">400</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="na">prompt</span><span class="o">=</span><span class="s">Search...</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="na">insensitive</span><span class="o">=</span><span class="s">true</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="na">allow_markup</span><span class="o">=</span><span class="s">true</span></span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c">/* ~/.config/wofi/style.css */</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="nt">window</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    <span class="k">background-color</span><span class="p">:</span> <span class="mh">#1e1e2e</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="k">border</span><span class="p">:</span> <span class="mi">2</span><span class="kt">px</span> <span class="kc">solid</span> <span class="mh">#89b4fa</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="k">border-radius</span><span class="p">:</span> <span class="mi">12</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="p">#</span><span class="nn">input</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="k">background-color</span><span class="p">:</span> <span class="mh">#313244</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="k">color</span><span class="p">:</span> <span class="mh">#cdd6f4</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="k">border-radius</span><span class="p">:</span> <span class="mi">8</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">    <span class="k">margin</span><span class="p">:</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">    <span class="k">padding</span><span class="p">:</span> <span class="mi">8</span><span class="kt">px</span> <span class="mi">12</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="p">#</span><span class="nn">entry</span><span class="p">:</span><span class="nd">selected</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="k">background-color</span><span class="p">:</span> <span class="nb">rgba</span><span class="p">(</span><span class="mi">137</span><span class="p">,</span> <span class="mi">180</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>Rofi（需要 wayland fork rofi-lbonn-wayland）功能更豐富——支援多種 mode（drun、window、ssh、自定義 script）、主題系統更完整。如果需要進階功能（例如 emoji picker、密碼管理器整合），Rofi 是更好的選擇。</p>
<h2 id="mako--dunst通知">Mako / Dunst：通知</h2>
<p>Mako 是 Wayland 原生的通知 daemon，負責<strong>顯示</strong>通知——它監聽 D-Bus 的 <code>org.freedesktop.Notifications</code> 介面、把收到的通知畫出來。產生通知的是應用程式，透過 <code>libnotify</code> 送上 D-Bus。所以一套能用的通知鏈需要兩半：daemon（顯示）和 <code>libnotify</code>（產生與遞送）。缺了 <code>libnotify</code>，連命令列自測用的 <code>notify-send</code> 都沒有。套件清單要同時列 <code>mako</code> 和 <code>libnotify</code>。</p>
<p>配置簡潔：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># ~/.config/mako/config</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="na">font</span><span class="o">=</span><span class="s">MesloLGS Nerd Font 11</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="na">background-color</span><span class="o">=</span><span class="s">#1e1e2e</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="na">text-color</span><span class="o">=</span><span class="s">#cdd6f4</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="na">border-color</span><span class="o">=</span><span class="s">#89b4fa</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="na">border-radius</span><span class="o">=</span><span class="s">8</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="na">border-size</span><span class="o">=</span><span class="s">2</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="na">padding</span><span class="o">=</span><span class="s">12</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="na">default-timeout</span><span class="o">=</span><span class="s">5000</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="na">max-visible</span><span class="o">=</span><span class="s">3</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">[urgency=critical]</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="na">border-color</span><span class="o">=</span><span class="s">#f38ba8</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="na">default-timeout</span><span class="o">=</span><span class="s">0</span></span></span></code></pre></div><p>通知的視覺風格（圓角、配色、字型）要跟 waybar 和啟動器一致，這是整體 rice 不散的關鍵。</p>
<p>Nerd Font 的字符集只含 Latin、圖示與 Powerline 符號，不含中日韓。任何 CJK 文字（通知內文、視窗標題）若系統沒有 CJK 字型可 fallback 會變豆腐方塊。修法是安裝 CJK fallback（如 <code>noto-fonts-cjk</code>），fontconfig 會自動補字、不需改各工具的 config。另外，中途補裝字型後已在跑的 daemon 需重啟才看得到——<code>reload</code> 類指令只重讀設定檔、不重建記憶體中的字型快照（原理見 <a href="/blog/linux/dotfile/knowledge-cards/font-availability-at-startup/" data-link-title="字型的可用集合在 process 啟動時決定" data-link-desc="裝了字型但應用程式 / 狀態列 / 通知還是看不到、還是豆腐時回來讀">字型的可用集合在 process 啟動時決定</a>）。</p>
<h2 id="grim--slurp截圖">Grim + Slurp：截圖</h2>
<p>Grim 負責截圖、Slurp 負責框選區域，兩者搭配使用。截圖結果透過 <code>wl-copy</code> 送進剪貼簿時，需要明確指定 MIME 型別：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 全螢幕截圖到剪貼簿</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">grim - <span class="p">|</span> wl-copy --type image/png
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 框選區域截圖到剪貼簿</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">grim -g <span class="s2">&#34;</span><span class="k">$(</span>slurp<span class="k">)</span><span class="s2">&#34;</span> - <span class="p">|</span> wl-copy --type image/png
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="c1"># 全螢幕截圖存檔</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">grim ~/screenshot.png</span></span></code></pre></div><p><code>wl-copy</code> 不帶 <code>--type</code> 時會嘗試透過 <code>xdg-utils</code>（<code>xdg-mime</code>）推斷 stdin 的型別。最小安裝環境沒有 <code>xdg-utils</code> 的情況下，PNG bytes 會被誤標成 <code>text/plain</code>，貼進影像應用程式就拿不到圖。明確帶 <code>--type image/png</code> 讓行為不依賴環境是否安裝了 <code>xdg-utils</code>。確認剪貼簿內容型別：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">wl-paste --list-types
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"># 應顯示 image/png</span></span></span></code></pre></div><p>Hyprland keybind 範例：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="nb">bind</span> <span class="o">=</span> , Print, exec, grim - <span class="p">|</span> wl-copy --type image/png
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nb">bind</span> <span class="o">=</span> SHIFT, Print, exec, grim -g <span class="s2">&#34;</span><span class="k">$(</span>slurp<span class="k">)</span><span class="s2">&#34;</span> - <span class="p">|</span> wl-copy --type image/png</span></span></code></pre></div>]]></content:encoded></item></channel></rss>