# 6.15 Hyprland

> **警告**
>
> 由于部分 DRM GPU 驱动尚未在 FreeBSD 上移植，目前在常见虚拟机中无法使用。
>
> 在使用 NVIDIA 显卡时不可用。
>
> 除软件包安装和系统重启操作外，本文中的所有命令应在非 root 用户权限下执行。

Hyprland 是基于 Wayland 的动态平铺式合成器（compositor），支持窗口透明、模糊、圆角等视觉特效，并且在动画效果方面表现良好。

Hyprland 的窗口焦点切换机制与传统桌面环境不同：鼠标光标停留在哪个窗口上，该窗口即获得焦点（无需点击），通常不使用 Alt+Tab 等快捷键进行切换。

![hyprland on FreeBSD](https://338876981-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCJR3FQGH1PkdRtOljuxb%2Fuploads%2Fgit-blob-4dd91cb32a2d73b7559d583c0e63bc6a85aa48e6%2Fhyprland.png?alt=media\&token=f4b0e4f3-bbde-4595-8dab-ca880aeac30d)

## 安装 Hyprland

### 使用 pkg 安装

```sh
# pkg ins hyprland waybar wofi qt6-base qt5-wayland qt6-wayland xdg-desktop-portal-hyprland hyprpicker swaybg mako nerd-fonts slurp grim swaylock kitty dolphin hyprpolkitagent
```

### 或者使用 Ports 安装

```sh
# cd /usr/ports/x11-wm/hyprland/ && make install clean
# cd /usr/ports/x11/waybar/ && make install clean
# cd /usr/ports/x11/wofi/ && make install clean
# cd /usr/ports/devel/qt6-base/ && make install clean
# cd /usr/ports/graphics/qt5-wayland/ && make install clean
# cd /usr/ports/graphics/qt6-wayland/ && make install clean
# cd /usr/ports/x11/xdg-desktop-portal-hyprland/ && make install clean
# cd /usr/ports/x11/hyprpicker/ && make install clean
# cd /usr/ports/x11/swaybg/ && make install clean
# cd /usr/ports/x11/mako/ && make install clean
# cd /usr/ports/x11-fonts/nerd-fonts/ && make install clean
# cd /usr/ports/x11/slurp/ && make install clean
# cd /usr/ports/x11/grim/ && make install clean
# cd /usr/ports/x11/swaylock/ && make install clean
# cd /usr/ports/x11-fm/dolphin/ && make install clean
# cd /usr/ports/x11/kitty/ && make install clean
# cd /usr/ports/sysutils/hyprpolkitagent/ && make install clean
```

### 解释软件包

> **注意**
>
> 作为依赖项，系统会自动安装 dbus 及 Wayland。

| 包名                            | 作用说明                                             |
| ----------------------------- | ------------------------------------------------ |
| `hyprland`                    | 动态平铺式 Wayland 合成器                                |
| `waybar`                      | 为 wlroots 合成器（如 Hyprland）设计的 GTK 状态栏             |
| `wofi`                        | 程序启动器（也可使用 rofi）                                 |
| `qt6-base`                    | Qt 6 的基础模块                                       |
| `qt5-wayland`                 | Qt 5 的 Wayland 支持模块，能让 Qt 5 应用程序在 Wayland 环境中运行。 |
| `qt6-wayland`                 | Qt 6 的 Wayland 支持模块，能让 Qt 6 应用程序在 Wayland 环境中运行。 |
| `xdg-desktop-portal-hyprland` | Hyprland 的 XDG Desktop Portal 实现，提供与其他应用程序的通信接口  |
| `hyprpicker`                  | 颜色选择器                                            |
| `swaybg`                      | 壁纸工具                                             |
| `mako`                        | 显示通知                                             |
| `nerd-fonts`                  | 图标字体，可以用来在配置文件中插入图案，显示在 waybar 等地方               |
| `slurp`                       | 屏幕选择工具，用来截屏                                      |
| `grim`                        | 屏幕截图工具                                           |
| `swaylock`                    | 锁屏工具                                             |
| `kitty`                       | 终端                                               |
| `dolphin`                     | 文件管理器                                            |
| `hyprpolkitagent`             | polkit 验证代理                                      |

## 启动服务

```sh
# service seatd enable   # 设置 seatd 服务开机自启动
# service dbus enable    # 设置 D-Bus 服务开机自启动
```

## 启动 Hyprland

### 设置 XDG\_RUNTIME\_DIR

先设置环境变量 `XDG_RUNTIME_DIR`，以避免启动时报错。

如果是默认 shell sh，将以下写入 `~/.profile`（对于 zsh，放入 `~/.zprofile`，下同）设置当前用户的 XDG 运行时目录：

```ini
export XDG_RUNTIME_DIR=/var/run/user/`id -u`
```

然后执行重启命令：`reboot`。

按快捷键 Ctrl+Alt+F2 进入 TTY，执行 `dbus-run-session Hyprland`，系统将在 `~/.config/hypr` 生成默认配置文件。

## 配置自动启动

如果需要在不使用登录管理器的前提下开机自动启动 Hyprland，请将下行写入 `~/.profile`：

```ini
dbus-run-session Hyprland
```

即在 D-Bus 会话中启动 Hyprland 窗口管理器。

也可以使用命令 `Hyprland -c <配置文件路径>` 来指定配置文件。

## 配置默认配置文件 `hyprland.conf`

Hyprland 默认配置文件的位置是 `~/.config/hypr/hyprland.conf`。

```sh
~/
├── .config/
│   ├── hypr/
│   │   └── hyprland.conf # Hyprland 主配置文件
│   ├── kitty/
│   │   └── kitty.conf # Kitty 终端配置文件
│   ├── waybar/
│   │   ├── config.jsonc # Waybar 配置文件
│   │   └── style.css    # Waybar 样式文件
│   └── swaylock/
│       └── config # swaylock 配置文件
├── .profile # 环境变量配置文件
└── .zprofile # Zsh 环境变量配置文件
```

注意：

* 启动后，Hyprland 默认在屏幕顶部显示一个黄色条带警告标识。可在配置文件中将其注释掉，找到 `autogenerated = 1` 这一行，在开头添加注释符号 `#`，或者直接删除整行。
* 默认将 Windows 徽标键（类 Unix 系统中称为 Super 键，下同）设置为 mod 键（可根据个人习惯改为 Alt 键等）：`$mainMod = SUPER`。
* 悬浮窗口的行为与传统桌面环境类似，可随意拖动到屏幕上的任意位置，并可使用鼠标调整窗口大小。在默认配置文件中，按住 mod 键并左键拖动悬浮窗口可移动窗口位置，按住右键拖动可调整窗口大小。可通过 `windowrulev2 = float, title:QQ` 设置默认悬浮窗口。
* 建议参考下方配置文件 `hyprland.conf`，其中 `swaybg` 用于设置壁纸，请将路径修改为你自己的图片文件所在位置。

## 任务栏：`exec-once=waybar`

* `hyprland.conf`

示例：

```ini
# 进入 Hyprland 后自动启动 fcitx5。该命令已被注释，读者在安装 fcitx5 后可自行取消注释
#exec-once=fcitx5
# 设置壁纸，请将路径修改为自己的图片文件位置
#exec-once=swaybg -i "$HOME/Pictures/Wallpapers/壁纸.jpg"
# 任务栏
exec-once=waybar
# swaylock 锁屏
exec-once=swayidle -w timeout 300 'swaylock'

# autogenerated = 1 # 移除或者注释这一行以消除屏幕顶部警告标识。

# See https://wiki.hyprland.org/Configuring/Monitors/
monitor=,preferred,auto,auto

# See https://wiki.hyprland.org/Configuring/Keywords/ for more

# Source a file (multi-file configs)
# source = ~/.config/hypr/myColors.conf

# Some default env vars.
env = XCURSOR_SIZE,24

# For all categories, see https://wiki.hyprland.org/Configuring/Variables/
input {
    kb_layout = us
    kb_variant =
    kb_model =
    kb_options =
    kb_rules =

    follow_mouse = 1

    touchpad {
        natural_scroll = no
    }

    sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
}

general {
    # See https://wiki.hyprland.org/Configuring/Variables/ for more

    gaps_in = 5
    gaps_out = 20
    border_size = 2
    col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg
    col.inactive_border = rgba(595959aa)

    layout = dwindle
}

animations {
    enabled = yes

    # Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more

    bezier = myBezier, 0.05, 0.9, 0.1, 1.05

    animation = windows, 1, 7, myBezier
    animation = windowsOut, 1, 7, default, popin 80%
    animation = border, 1, 10, default
    animation = borderangle, 1, 8, default
    animation = fade, 1, 7, default
    animation = workspaces, 1, 6, default
}

dwindle {
    # See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
    pseudotile = yes # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
    preserve_split = yes # you probably want this
}

gestures {
    # See https://wiki.hyprland.org/Configuring/Variables/ for more
    workspace_swipe = off
}

# 窗口规则
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
windowrulev2 = float, title:rofi.*
windowrulev2 = float, title:QQ
windowrulev2 = float, title:图片查看器


# See https://wiki.hyprland.org/Configuring/Keywords/ for more
$mainMod = SUPER # 使用 Windows 徽标键作为 mainMod 键
$shiftMod=SUPER_SHIFT
$altMod=SUPER_ALT
$alt=ALT
$shift=SHIFT

# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
bind = $mainMod, Q, exec, kitty # 打开终端
bind = $mainMod, C, killactive,  # 关闭窗口
bind = $mainMod, M, exit, # 注销
bind = $mainMod, E, exec, dolphin # 文件管理器
bind = $mainMod, V, togglefloating,  # 切换为悬浮窗口，可拖动
bind = $mainMod, R, exec, wofi --show drun # 软件启动器，类似菜单
bind = $mainMod, P, pseudo, # 允许焦点窗口（光标所在窗口）在平铺窗口原占区域内自由调节大小和位置
bind = $mainMod, J, togglesplit, # 调整焦点窗口与相邻窗口的排列方向，可在上下或左右排列之间切换
### 截图
$screen_file=${HOME}/screen_shot_$(date + "%Y-%m-%d_%H-%M-%S").png
bind=$shiftMod, S, exec, grim -g "$(slurp)" - | wl-copy
bind=, Print,      exec, grim $screen_file
bind=$shift, Print,exec, grim -g "$(slurp)" $screen_file
bind=$alt, Print,  exec, grim - | wl-copy

# Move focus with mainMod + arrow keys
bind = $mainMod, left, movefocus, l
bind = $mainMod, right, movefocus, r
bind = $mainMod, up, movefocus, u
bind = $mainMod, down, movefocus, d

# Switch workspaces with mainMod + [0-9]
# 切换工作区 mainmod 键 + 数字键，1 到 0 对应 10 个工作区。
bind = $mainMod, 1, workspace, 1
bind = $mainMod, 2, workspace, 2
bind = $mainMod, 3, workspace, 3
bind = $mainMod, 4, workspace, 4
bind = $mainMod, 5, workspace, 5
bind = $mainMod, 6, workspace, 6
bind = $mainMod, 7, workspace, 7
bind = $mainMod, 8, workspace, 8
bind = $mainMod, 9, workspace, 9
bind = $mainMod, 0, workspace, 10

# Move active window to a workspace with mainMod + SHIFT + [0-9]
# 将窗口移动到别的工作区，例如 mainmod+Shift+2（win 键 +2 是查看工作区 1）
bind = $mainMod SHIFT, 1, movetoworkspace, 1
bind = $mainMod SHIFT, 2, movetoworkspace, 2
bind = $mainMod SHIFT, 3, movetoworkspace, 3
bind = $mainMod SHIFT, 4, movetoworkspace, 4
bind = $mainMod SHIFT, 5, movetoworkspace, 5
bind = $mainMod SHIFT, 6, movetoworkspace, 6
bind = $mainMod SHIFT, 7, movetoworkspace, 7
bind = $mainMod SHIFT, 8, movetoworkspace, 8
bind = $mainMod SHIFT, 9, movetoworkspace, 9
bind = $mainMod SHIFT, 0, movetoworkspace, 10

# 使用 mainMod + 鼠标滚轮滚动浏览现有工作区
bind = $mainMod, mouse_down, workspace, e+1
bind = $mainMod, mouse_up, workspace, e-1

# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = $mainMod, mouse:272, movewindow
bindm = $mainMod, mouse:273, resizewindow

```

## 配置 `kitty.conf`

* 配置文件位置：`~/.config/kitty/kitty.conf`。

示例：

```ini
# Look and feel

## Color
# include ./obsidian.color.conf

## 字体设置
font_family      Hasklug Nerd Font Mono
font_size 14.0
#font_features FiraCodeNerdFontCompleteM-Retina +ss02 +ss03 +ss04 +ss05 +ss07 +zero

## 文本光标设置
cursor_blink_interval      2.0
cursor_stop_blinking_after 5.0

## Scrollback
scrollback_lines -1

## 鼠标相关设置
copy_on_select yes    # 选中文本时复制
mouse_hide_wait 2.0   # 定时隐藏鼠标

## 提示 🔔
enable_audio_bell no
visual_bell_duration 0.3
bell_on_tab yes

## Tabs
tab_bar_edge top
tab_bar_style powerline
tab_powerline_style angled
active_tab_foreground   #111
active_tab_background   #eee
active_tab_font_style   bold
inactive_tab_foreground #666
inactive_tab_background #888
tab_bar_background #444
inactive_tab_font_style normal
tab_title_template "{fmt.fg.gray}{index}{fmt.fg.default}:{title}"
active_tab_title_template "{title}"

# Mechanics
input_delay 2
editor nvim
allow_remote_control no
allow_hyperlinks no
term xterm-256color
macos_option_as_alt yes
macos_quit_when_last_window_closed yes
strip_trailing_spaces smart
update_check_interval 72
hide_window_decorations titlebar-only

# Shortcuts
clear_all_shortcuts yes

## The defaults
map ctrl+a                pipe @text tab pbcopy
map ctrl+shift+c          copy_to_clipboard
map ctrl+shift+v          paste_from_clipboard
map ctrl+alt+j            scroll_page_up
map ctrl+alt+k            scroll_page_down
map ctrl+k                clear_terminal reset active

## 标签页管理
map ctrl+t                new_tab_with_cwd !neighbor
map alt+s                next_tab
map alt+a                previous_tab
map alt+q                close_tab
map ctrl+s                set_tab_title
map ctrl+shift+left       move_tab_backward
map ctrl+shift+right      move_tab_forward
map alt+1                goto_tab 1
map alt+2                goto_tab 2
map alt+3                goto_tab 3
map alt+4                goto_tab 4
map alt+5                goto_tab 5
map alt+6                goto_tab 6
map alt+7                goto_tab 7
map alt+8                goto_tab 8
map alt+9                goto_tab 9

# 文字大小调节
map ctrl+equal            change_font_size current +1.0
map ctrl+minus            change_font_size current -1.0
map ctrl+0                change_font_size current 0

#include ${ARCH}.conf
```

## 配置 waybar（任务栏）

waybar 的配置文件目录位于 `~/.config/waybar`，其中包含 `config.jsonc` 和 `style.css` 文件。可参考示例配置文件进行配置，示例中需要安装软件包 `noto-emoji` 才能正常显示，读者可根据需要修改为自己想要的图标。

`config.jsonc` 示例：

```json
{
    "position": "top",
    "layer": "top",
    "height": 16,
    "margin-top": 0,
    "margin-bottom": 0,
    "margin-left": 0,
    "margin-right": 0,
    "modules-left": ["custom/launcher", "wlr/workspaces", "custom/playerctl", "custom/playerlabel"],
    "modules-center": ["cpu", "memory", "disk"],
    "modules-right": ["tray", "custom/randwall", "network", "pulseaudio", "clock"],
	"clock": {
		"format": "⏰  {:%H:%M}",
		"tooltip": "true",
        	"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
        	"format-alt": "🗓️  {:%y/%m/%d}"
	},


	"wlr/workspaces": {
        "active-only": false,
        "all-outputs": true,
        "disable-scroll": false,
        "on-scroll-up": "hyprctl dispatch workspace -1",
        "on-scroll-down": "hyprctl dispatch workspace +1",
		"format": "{icon}",
		"on-click": "activate",
		"format-icons": {
			"urgent": "",
			"active": "🔴",
			"default": "🔵",
    "sort-by-number": true
    },
    },

    "custom/playerctl": {
      "format": "{icon}",
      "return-type": "json",
      "max-length": 64,
      "exec": "playerctl -a metadata --format '{\"text\": \"{{artist}} - {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F",
      "on-click-middle": "playerctl play-pause",
      "on-click": "playerctl previous",
      "on-click-right": "playerctl next",
      "format-icons": {
        "Playing": "<span foreground='#E5B9C6'>󰒮 󰐌 󰒭</span>",
        "Paused": "<span foreground='#928374'>󰒮 󰏥 󰒭</span>"
      },
    },

    "custom/playerlabel": {
      "format": "<span>{}</span>",
      "return-type": "json",
      "max-length": 48,
      "exec": "playerctl -a metadata --format '{\"text\": \"{{artist}} - {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F",
      "on-click-middle": "playerctl play-pause",
      "on-click": "playerctl previous",
      "on-click-right": "playerctl next",
      "format-icons": {
        "Playing": "<span foreground='#E5B9C6'>󰒮 󰐌 󰒭</span>",
        "Paused": "<span foreground='#928374'>󰒮 󰏥 󰒭</span>"
      },
    },

  "memory": {
    "format": "🌊 {}%",
    "format-alt": "🌊 {used}/{total} GiB",
    "interval": 5
  },

  "cpu": {
    "format": "📟 {usage}%",
    "format-alt": "📟 {avg_frequency} GHz",
    "interval": 5
  },

  "disk": {
    "format": "📦 {}%",
    "format-alt": "📦 {used}/{total} GiB",
    "interval": 5,
    "path": "/"
  },

	"network": {
        	//"format-ethernet": " {ifname}: {ipaddr}",
            "format-ethernet": " IP: {ipaddr}",
        	//"format-linked": " {ifname} (No IP)",
        	"format-disconnected": "󰤭",
        	//"format-alt": " {ifname}: {ipaddr}/{cidr}",
          "tooltip-format": "{essid}",
          "on-click-right": "nm-connection-editor"
	},

	"tray": {
		"icon-size": 16,
		"spacing": 5
	},

	"backlight": {
	"format": "{icon} {percent}%",
        "format-icons": ["", "", "", "", "", "", "", "", ""],
	},

	"pulseaudio": {
		"format": "{icon} {volume}%",
        	"format-muted": "🔇",
		"format-icons": {
			"default": ["🔈", "🔉", "🔊"]
		},
    "scroll-step": 5,
  },
  "custom/launcher": {
    "format": "🚀",
    "on-click": "wofi --show drun",
    "on-click-right": "wofi --show drun"
  },
}

```

`style.css` 示例：

```css
* {
    border: none;
    border-radius: 0px;
    /*font-family: VictorMono, Iosevka Nerd Font, Noto Sans CJK;*/
    font-family: Cascadia Code, FontAwesome, Noto Sans CJK, Microsoft YaHei UI, HarmonyOS Sans;
    font-size: 14px;
    font-style: normal;
    min-height: 0;
}

window#waybar {
    background: rgba(30, 30, 46, 0.5);
    border-bottom: 1px solid #282828;
    color: #f4d9e1
}

#workspaces {
	background: #282828;
	margin: 5px 5px 5px 5px;
  padding: 0px 5px 0px 5px;
	border-radius: 16px;
  border: solid 0px #f4d9e1;
  font-weight: normal;
  font-style: normal;
}
#workspaces button {
    padding: 0px 5px;
    border-radius: 16px;
    color: #928374;
}

#workspaces button.active {
    color: #f4d9e1;
    background-color: transparent;
    border-radius: 16px;
}

#workspaces button:hover {
	background-color: #E6B9C6;
	color: black;
	border-radius: 16px;
}

#custom-date, #clock, #battery, #pulseaudio, #network, #custom-randwall, #custom-launcher {
	background: transparent;
	padding: 5px 5px 5px 5px;
	margin: 5px 5px 5px 5px;
  border-radius: 8px;
  border: solid 0px #f4d9e1;
}

#custom-date {
	color: #D3869B;
}

#custom-power {
	color: #24283b;
	background-color: #db4b4b;
	border-radius: 5px;
	margin-right: 10px;
	margin-top: 5px;
	margin-bottom: 5px;
	margin-left: 0px;
	padding: 5px 10px;
}

#tray {
    background: #282828;
    margin: 5px 5px 5px 5px;
    border-radius: 16px;
    padding: 0px 5px;
    /*border-right: solid 1px #282738;*/
}

#clock {
    color: #E6B9C6;
    background-color: #282828;
    border-radius: 0px 0px 0px 24px;
    padding-left: 13px;
    padding-right: 15px;
    margin-right: 0px;
    margin-left: 10px;
    margin-top: 0px;
    margin-bottom: 0px;
    font-weight: bold;
    /*border-left: solid 1px #282738;*/
}


#battery {
    color: #9ece6a;
}

#battery.charging {
    color: #9ece6a;
}

#battery.warning:not(.charging) {
    background-color: #f7768e;
    color: #24283b;
    border-radius: 5px 5px 5px 5px;
}

#backlight {
    background-color: #24283b;
    color: #db4b4b;
    border-radius: 0px 0px 0px 0px;
    margin: 5px;
    margin-left: 0px;
    margin-right: 0px;
    padding: 0px 0px;
}

#network {
    color: #f4d9e1;
    border-radius: 8px;
    margin-right: 5px;
}

#pulseaudio {
    color: #f4d9e1;
    border-radius: 8px;
    margin-left: 0px;
}

#pulseaudio.muted {
    background: transparent;
    color: #928374;
    border-radius: 8px;
    margin-left: 0px;
}

#custom-randwall {
    color: #f4d9e1;
    border-radius: 8px;
    margin-right: 0px;
}

#custom-launcher {
    color: #e5809e;
    background-color: #282828;
    border-radius: 0px 24px 0px 0px;
    margin: 0px 0px 0px 0px;
    padding: 0 20px 0 13px;
    /*border-right: solid 1px #282738;*/
    font-size: 20px;
}

#custom-launcher button:hover {
    background-color: #FB4934;
    color: transparent;
    border-radius: 8px;
    margin-right: -5px;
    margin-left: 10px;
}

#custom-playerctl {
	background: #282828;
	padding-left: 15px;
  padding-right: 14px;
	border-radius: 16px;
  /*border-left: solid 1px #282738;*/
  /*border-right: solid 1px #282738;*/
  margin-top: 5px;
  margin-bottom: 5px;
  margin-left: 0px;
  font-weight: normal;
  font-style: normal;
  font-size: 16px;
}

#custom-playerlabel {
    background: transparent;
    padding-left: 10px;
    padding-right: 15px;
    border-radius: 16px;
    /*border-left: solid 1px #282738;*/
    /*border-right: solid 1px #282738;*/
    margin-top: 5px;
    margin-bottom: 5px;
    font-weight: normal;
    font-style: normal;
}

#window {
    background: #282828;
    padding-left: 15px;
    padding-right: 15px;
    border-radius: 16px;
    /*border-left: solid 1px #282738;*/
    /*border-right: solid 1px #282738;*/
    margin-top: 5px;
    margin-bottom: 5px;
    font-weight: normal;
    font-style: normal;
}

#custom-wf-recorder {
    padding: 0 20px;
    color: #e5809e;
    background-color: #1E1E2E;
}

#cpu {
    background-color: #282828;
    /*color: #FABD2D;*/
    border-radius: 16px;
    margin: 5px;
    margin-left: 5px;
    margin-right: 5px;
    padding: 0px 10px 0px 10px;
    font-weight: bold;
}

#memory {
    background-color: #282828;
    /*color: #83A598;*/
    border-radius: 16px;
    margin: 5px;
    margin-left: 5px;
    margin-right: 5px;
    padding: 0px 10px 0px 10px;
    font-weight: bold;
}

#disk {
    background-color: #282828;
    /*color: #8EC07C;*/
    border-radius: 16px;
    margin: 5px;
    margin-left: 5px;
    margin-right: 5px;
    padding: 0px 10px 0px 10px;
    font-weight: bold;
}

#custom-hyprpicker {
    background-color: #282828;
    /*color: #8EC07C;*/
    border-radius: 16px;
    margin: 5px;
    margin-left: 5px;
    margin-right: 5px;
    padding: 0px 11px 0px 9px;
    font-weight: bold;
}

```

## 配置 swaylock

swaylock 的配置文件在 `~/.config/swaylock/config` 文件中。

* 示例配置文件：

```ini
ignore-empty-password
font=Fira Sans Compressed

clock
timestr=%R
datestr=%a, %e of %B

screenshots

fade-in=0.2

effect-blur=20x2
#effect-greyscale
effect-scale=0.3

indicator
indicator-radius=360
indicator-thickness=60
indicator-caps-lock

key-hl-color=228833

separator-color=00000000

inside-color=00000099
inside-clear-color=ffd20400
inside-caps-lock-color=009ddc00
inside-ver-color=d9d8d800
inside-wrong-color=ee2e2400

ring-color=231f20D9
ring-clear-color=231f20D9
ring-caps-lock-color=231f20D9
ring-ver-color=231f20D9
ring-wrong-color=231f20D9

line-color=00000000
line-clear-color=ffd2000
line-caps-lock-color=009ddc00
line-ver-color=d9d8d800
line-wrong-color=ee2e2400

text-clear-color=ffd20400
text-ver-color=d9d8d800
text-wrong-color=ee2e2400

bs-hl-color=ee2e24FF
#caps-lock-key-hl-color=ffd204FF
#caps-lock-key-hl-color=ee2e24FF
#caps-lock-bs-hl-color=ee2e24FF
#disable-caps-lock-text
text-caps-lock-color=000000FF
```

## 故障排除与未竟事宜

### 启动失败/黑屏

请读者检查是否已将普通用户添加到 `video` 组，是否安装了显卡驱动，以及是否正确设置环境变量 `XDG_RUNTIME_DIR`，并确认上述设置已生效。

## 参考文献

* Bilibili. ArchLinux 下 Hyprland 配置指北\[EB/OL]. Bilibili 专栏, \[2026-03-25]. <https://www.bilibili.com/read/cv22707313/>. Bilibili 专栏提供的 Hyprland 窗口管理器详细配置中文教程。
* nth233. Hyprland 的配置\[EB/OL]. 个人博客, \[2026-03-25]. <https://nth233.top/posts/2023-02-26-Hyprland%E9%85%8D%E7%BD%AE>. Hyprland 窗口管理器配置详解与实践指南。
* Gentoo Wiki. Hyprland\[EB/OL]. \[2026-03-25]. <https://wiki.gentoo.org/wiki/Hyprland>. Gentoo 官方维基明确指出 Hyprland 启动命令应为 `dbus-run-session Hyprland`。
* Arch Linux Wiki. Hyprland\[EB/OL]. \[2026-03-25]. <https://wiki.archlinux.org/title/Hyprland>. Arch Linux 官方维基指出虚拟机需 3D 加速且依赖 DRM GPU，同时所有平台 NVIDIA 显卡均不被支持。

## 课后习题

1. 查找 Hyprland 合成器的 Port 源码，分析其与 wlroots 的技术关联，在真实硬件上构建最小化 Hyprland 环境并验证其 Wayland 会话行为。
2. 重构本文，全面增补重写。
