---
title: Quickshell 桌面外壳
url: https://doc.liz6.com/tools/hyprland/03-quickshell
locale: zh
area: tools
tags:
- tools
- hyprland
date: null
modified: 2026-06-30
description: 基于 illogical-impulse 的 Quickshell 外壳 —— 七万行别人的 rice,我要知道的是它怎么分层、颜色从哪来。
---

# Quickshell 桌面外壳

顶栏、侧栏、控制中心、通知这些"壳",用 [Quickshell](https://quickshell.outfoxxed.me) 写——它让你拿 QML 描述 Wayland 桌面组件。我这套基于 [illogical-impulse](https://github.com/end-4/dots-hyprland)(end-4 的 dots,目录代号 `ii`),在它上面改。

先把话说清楚:这是七万行 QML、九百多个文件,大半不是我写的。所以对我(和看这篇的人)真正有用的不是逐文件讲解,而是两件事——它怎么分层、颜色从哪来,知道这两点,要改哪个组件顺着找就行。

先说 Quickshell 本身给你什么:它把 **QML**(Qt 的声明式 UI 语言)接到 Wayland 的 layer-shell 上,于是你能用"属性绑定 + 信号"这套声明式写法,描述顶栏、悬浮窗、锁屏这些桌面层组件。好处是**响应式**——某个值变了,绑定它的界面自动重画,不用手写刷新逻辑。

在这之上,ii 的结构就是 services 取数据、modules 画界面两层:

- **services** 把系统状态封成 QML 单例对象:PipeWire(音量/设备)、NetworkManager(网络)、UPower(电量)、MPRIS(正在播放)这些,各自暴露成可绑定的属性。
- **modules** 声明式地把这些状态画成面板和控件,交互(点了、拖了)再回调回 service。

```qml
// 大意:一个跟着系统音量走的小条
Slider {
    value: Pipewire.defaultSink.volume       // 绑定 service 的属性
    onMoved: Pipewire.defaultSink.volume = value  // 交互回写
}
```

所以想给顶栏加个小组件,套路是固定的:在 modules 里写段 QML,从对应 service 拿数据绑上去——不用碰那九百个文件里的大半。要改现成组件,顺着"它读哪个 service"往回找就行。

颜色它自己不定义,读 matugen 生成的 `~/.local/state/quickshell/user/generated/colors.json`,所以换壁纸时整个壳和 [Ghostty](../ghostty.md)、锁屏一起变色([matugen](04-waybar-theming.md) 那篇)。

它由 Hyprland 开机拉起常驻。因为是跟着上游 rice 走的大件,我没把它塞进 [chezmoi](../chezmoi.md)——跟上游更新 + 本地改几处,比自己扛着七万行省心。
