本文主要介绍Hyprland的基本配置。虽然Hyprland已经有了一个官方文档,但是和i3wm的文档相比,可读性还是差了很多。单看文档,不给一个配置范例的话,还是很难上手。很可惜的是,Hyprland的默认配置和Sway相比差远了,必须要一番折腾才堪用。

因此才有了这篇文章,一方面是分享一下我的配置,另一方面是分享一下踩的坑。本文只涵盖最基本的配置,由于我觉得Hyprland默认的特效已经很炫酷了,因此没有对特效做任何修改,本文也就不会包含任何与特效配置相关的内容。

我的Hyprland

为什么要用Hyprland?

特效?wlroots?平铺式布局?其实我也忘了我为什么要用Hyprland。当初觉得Gnome资源占用太高,就去用Sway。但是Sway的动画简陋而且不适配N卡,就试着使用了一下Hyprland,于是一路折腾过来,就用上了。不过没过多久,我还是回到了Gnome和Sway。日常使用Gnome,需要低占用就用Sway,似乎真的没有使用Hyprland的理由。

如果你不愿意使用臃肿DE、想要使用平铺式的WM、愿意使用Wayland、想要自己配置炫酷的特效、乐于折腾,那么Hyprland确实值得一试。如果你从未尝试过平铺式WM,那么我建议先尝试一下i3或者Sway,初次尝试可能会觉得不适应,但一旦习惯了平铺式WM,就会觉得传统的层叠式WM十分低效。

在ArchLinux上安装Hyprland

我个人不建议使用任何“一键安装脚本”进行安装,除非你很清楚脚本在做什么。如果读过别人写的bash脚本,就会知道这东西可读性极差,与其对脚本进行费时费脑的审查,不如直接手动装了。

Hyprland尚未进入Arch的官方仓库,因此得从AUR安装。

yay -S hyprland

安装完成后,理论上Hyprland就可以用了(实际上此时Hyprland使用的默认配置不仅丑,而且十分难用)。可以注销登录进Hyprland,看看配置前的Hyprland是什么样子的。

Hyprland本体的基本配置

打开$HOME/.config/hypr/hyprland.conf修改配置。要做的第一件事是把“自动生成”的标志给注释掉,否则每次启动Hyprland都会报警告。把下面这行注释掉:

autogenerated = 1 # remove this line to remove the warning

改为

#autogenerated = 1 # remove this line to remove the warning

键位绑定

我习惯把快捷键改得像Sway。如果有特殊的需要,可以自己修改。$mainMod键类似i3中的mod键,建议把所有和WM相关的快捷键都设置为以mod这个键开头,这样比较有条理。一般设Super键为$mainMod,因为大部分程序的快捷键都不涉及Super键。

$mainMod = SUPER # 用super键作为mod键

然后逐个绑定快捷键。绑定快捷键的语法如下:

bind=MODS,key,dispatcher,params

MODS表示快捷键中的“模式键”,譬如SUPER、SHIFT、CTRL等等。key则表示快捷键组合中最后的那一个键。dispatcher则表示是Hyprland内置的命令,比如exec运行、movefocus移动焦点等等,详见Hyprland的wikiparams表示dispatcher的参数。

下面是我个人习惯使用的配置:

应用

bind = $mainMod, return, exec, kitty # 打开终端
bind = $mainMod SHIFT, return, exec, gnome-terminal # 有时我需要用gnome-terminal
bind = $mainMod SHIFT, q, killactive, # 关闭当前窗口
bind = $mainMod SHIFT, e, exit, # 注销
bind = $mainMod, n, exec, nautilus # 文件管理器,我习惯用nautilus
bind = $mainMod, p, exec, firefox # 浏览器,我习惯用firefox
bind = $mainMod, space, togglefloating, # 切换悬浮模式,悬浮的窗口和层叠式WM中的窗口行为类似,会浮动在平铺的窗口上面
#bind = $mainMod, tab, exec, wofi --show drun # 使用wofi选择应用
bind = $mainMod, tab, exec, rofi -show drun # 使用rofi选择应用,之后解释
bind = $mainMod, x, exec, hyprland-interactive-screenshot # 截图,之后解释

窗口和工作区

bind = $mainMod, d, pseudo, # dwindle # 伪平铺,后面解释
bind = $mainMod, V, togglesplit, # 修改划分方式(切换纵横向切分)
bind = $mainMod, S, togglegroup, # 切换编组(打开编组模式后,同组的窗口会叠在一起)
bind = $mainMod CTRL, l, changegroupactive # 切换编组中的窗口
bind = $mainMod SHIFT, f, fullscreen # 切换全屏
bind = $mainMod, H, movefocus, l # 选中左边的窗口
bind = $mainMod, L, movefocus, r # 选中右边的窗口
bind = $mainMod, K, movefocus, u # 选中上面的窗口
bind = $mainMod, J, movefocus, d # 选中下面的窗口,这四个快捷键受vim启发
bind = $mainMod, 1, workspace, 1 # 选中工作区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 SHIFT, 1, movetoworkspace, 1 # 把窗口移动到工作区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, mouse_down, workspace, e+1 # 鼠标滚轮切换工作区,下面同理
bind = $mainMod, mouse_up, workspace, e-1
bind = $mainMod ALT, h, workspace, -1 # 键盘切换到上一个工作区
bind = $mainMod ALT, l, workspace, +1 # 键盘切换到下一个工作区
bind = $mainMod ALT, left, workspace, -1
bind = $mainMod ALT, right, workspace, +1

鼠标

bindm = $mainMod, mouse:272, movewindow # 按住mod用鼠标左键拖动窗口
bindm = $mainMod, mouse:273, resizewindow # 按住mod用鼠标右键拖动窗口

音量和亮度控制

bind = , xf86audioraisevolume, exec, amixer set Master 5%+ # 调大音量
bind = , xf86audiolowervolume, exec, amixer set Master 5%- # 调小音量
bind = , xf86monbrightnessdown, exec, brightnessctl set 5%- # 调高亮度
bind = , xf86monbrightnessup, exec, brightnessctl set 5%+ # 调低亮度

可以根据需要再加入其他的X绑定功能键(XBindKeys)

窗口规则

可以强制让一些窗口默认悬浮。比如rofi、QQ的图片查看器。

windowrulev2 = float, title:rofi.*
windowrulev2 = float, title:Lutris
windowrulev2 = float, title:QQ
windowrulev2 = float, title:图片查看器

输入法

在Hyprland启动的时候,顺便启动fcitx5。

exec-once=fcitx5 -d

一些必装的工具

完成上面的配置之后,Hyprland勉强算是可以用了,但是体验会非常糟糕。要想日常使用,下面这些工具基本上是必装的。

壁纸:swaybg

swaybg没有花里胡哨的功能,就单纯是显示一张静态壁纸,对我来说已经很够用了。如果需要自动切换壁纸,可以用swww;如果需要花里胡哨的动态壁纸,可以试试mpvpaper

首先安装swaybg

# pacman -S swaybg

然后在hyprland.conf中调用它(就是在Hyprland启动后顺便执行swaybg)。记得把"$HOME/Pictures/wallpaper/brown-mountain.jpg"改成你壁纸的路径。

exec-once=swaybg -i "$HOME/Pictures/wallpaper/brown-mountain.jpg"

状态栏:Waybar

状态栏有很多种选择,我使用最保守的waybar。Hyprland的文档中建议使用定制版的waybar,也就是AUR上的waybar-hyprland-git

# yay -S waybar-hyprland-git

然后对它进行配置。配置文件有两个,默认都在.config/waybar/下:

  1. config:用JSON格式描述的状态栏结构。
  2. style.css:CSS样式,用于调整布局的细节。

整体配置起来就像在写一个网页。

我个人比较喜欢像GNOME的状态栏,配置如下。

config中内容如下。主要是定义了启动应用、托盘、CPU内存占用、音量调整、亮度调整、工作区、网络显示、电量、日期时间这些内容。日期和时间默认只显示时间,鼠标悬停显示日期,右键单击用lunar-date显示农历。

{
    "layer": "top",
    "modules-left": ["custom/launcher","cpu","memory","tray","hyprland/window"],
    "modules-center": ["clock"],
    "modules-right": ["wlr/workspaces", "backlight", "pulseaudio", "network", "battery","custom/power"],
    
    "pulseaudio": {
        "tooltip": false,
        "scroll-step": 5,
        "format": "{icon} {volume}%",
        "format-muted": "{icon} {volume}%",
        "on-click": "pavucontrol",
        "format-icons": {
            "default": ["", "", ""]
        }
    },
    "hyprland/window": {
        "format": "<b>{}</b>",
        "max-length": 40
    },
    "wlr/workspaces": {
        "format": "{icon}",
        "on-click": "activate",
        "on-scroll-up": "hyprctl dispatch workspace e+1",
        "on-scroll-down": "hyprctl dispatch workspace e-1"
    },
    "network": {
        "tooltip": false,
        "format-wifi": " {essid}",
        "format-ethernet": "wired"
    },
    "backlight": {
        "tooltip": false,
        "format": " {}%",
        "interval":1,
        "on-scroll-up": "brightnessctl set 5%+",
        "on-scroll-down": "brightnessctl set 5%-"
    },
    "battery": {
            "states": {
                    "good": 95,
                    "warning": 40,
                    "critical": 20
            },
            "format": "{icon}  {capacity}%",
            "format-charging": " {capacity}%",
            "format-plugged": " {capacity}%",
            "format-alt": "{time} {icon}",
            "format-icons": ["", "", "", "", ""]
    },
    "tray":{
        "icon-size":18,
        "spacing": 10
    },
    "clock": {
        "format": "<b>{:%H:%M}</b>",
        "tooltip-format": "<big>{:%Y-%m-%d %A %Z}</big>",
        "on-double-click": "gnome-clocks",
        "on-click-right": "kitty --hold lunar-date `date +'%Y %m'`"
    },
    "cpu": {
        "interval": 15,
        "format": " {}%",
        "max-length": 10,
        "on-click": "kitty htop"
    },
    "memory": {
            "interval": 30,
        "format": " {}%",
        "max-length": 10
    },
    "custom/launcher":{
            "format": "",
            "on-click": "rofi -show drun",
            "on-click-right": "rofi -show run"
        },
}

style.css样式如下:

* {
    border: none;
    font-family: "Fira Sans Compressed", "Noto Sans CJK SC";
    font-size: 17px;
    min-height: 14px;
}

#waybar {
    background: rgba(20, 20, 20, 20);
    min-height: 20px;
    border-radius: 0px;
}

#window {
    margin: 6px;
    padding-left: 5px;
    padding-right: 5px;
    border-radius: 5px;
    transition: none;
    color: white;
    background: transparent;
    font-family: "Fira Sans SemiBold", "Noto Sans CJK SC";
}

#workspaces {
    color: #EEEEEE;
    background: rgba(50, 50, 50, 80);
    margin: 6px;
    font-family: "Liberation Mono";
    border-radius: 5px;
}
#workspaces button {
    margin: 2px;
    color: white;
    background: rgba(50, 50, 50, 80);
}
#workspaces button:hover {
    color: black;
    background: rgba(200, 200, 200, 80);
}

#network,
#pulseaudio,
#battery,
#backlight {
    margin: 6px;
    padding-left: 5px;
    padding-right: 5px;
    border-radius: 5px;
    transition: none;
    background: transparent;
    color: white;
}

#network:hover,
#pulseaudio:hover,
#battery:hover,
#backlight:hover
{
    background: rgba(50, 50, 50, 80);
}

#battery.charging, #battery.plugged {
    color: white;
}

#battery.critical:not(.charging) {
        animation-name: blink;
        animation-duration: 0.5s;
        animation-timing-function: linear;
        animation-iteration-count: infinite;
        animation-direction: alternate;
}

@keyframes blink {
    to {
        background-color: #BF616A;
        color: #B5E8E0;
    }
}

#clock {
    margin: 6px;
    padding-left: 5px;
    padding-right: 5px;
    border-radius: 5px;
    transition: none;
    color: white;
    font-size: 22px;
    font-family: Fira Code;
    background: transparent;
}

#memory {
    margin: 6px;
    padding-left: 5px;
    padding-right: 5px;
    border-radius: 5px;
    transition: none;
    color: white;
    background: rgba(0, 0, 0, 80);
}
#cpu {
    margin: 6px;
    padding-left: 5px;
    padding-right: 5px;
    border-radius: 5px;
    transition: none;
    color: white;
    background: rgba(0, 0, 0, 80);
}

#tray {
    margin: 6px;
    padding-left: 5px;
    padding-right: 5px;
    border-radius: 5px;
    transition: none;
    background: transparent;
}

#custom-launcher {
    font-size: 24px;
    margin: 6px;
    padding-left: 5px;
    padding-right: 5px;
    border-radius: 5px;
    transition: none;
    color: rgb(134, 216, 231);
    background: rgb(22, 19, 32);
}

最后在hyprland中启用。

应用程序选择菜单:rofi或者wofi

如果没有rofi或者wofi这类启动器,纯WM的体验真的会很糟糕。这里我使用rofi。

# pacman -S rofi

在Hyprland一侧的配置刚才已经完整了,如果按照我上面的配置文件,按Mod+Tab打开rofi。如果觉得默认的rofi比较丑,可以自己安装主题,比如dracula

可以把.config/rofi/config.rasi中的show-icons设为true,这样rofi会自动显示图标。

通知:dunst

Hyprland默认没有显示通知的工具。要显示统治,dunst是不错的选择。

# pacman -S dunst

然后在hyprland.conf中调用。

exec-once=dunst

如果觉得dunst默认的主题太丑,也可以换主题,比如dracula

锁屏

WM在锁屏这方面一直没有太好的解决方案。我目前习惯超时直接挂起。用swayidle实现超时自动调用,下面的timeout可以自己改,单位是秒。

exec-once=swayidle -w timeout 1800 'systemctl suspend' 

swaylock也是不错的选择,但我觉得不好用。

# yay -S swaylock-effects-git

然后修改配置~/.config/swaylock/config

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-lcok-key-hl-color=ee2e24FF
#caps-lock-bs-hl-color=ee2e24FF
#disable-caps-lock-text
text-caps-lock-color=000000FF

然后在hyprland.conf中调用。

exec-once=swayidle -w timeout 1800 'swaylock' 

终端:kitty

我始终觉得kitty不如gnome-terminal和konsole好用(但是比起alacritty,还是好用很多的)。如果追求既简陋轻量又好看,可以用。

# pacman -S kitty

~/.config/kitty/kitty.conf

font_size 13.0
font_family Jetbrains Mono
background_opacity 0.80

# keybinds

kitty_mod ctrl+shift

map kitty_mod+c copy_to_clipboard
map kitty_mod+v paste_from_clipboard

include theme.conf

~/.config/kitty/theme.conf

background            #202020
foreground            #d0d0d0
cursor                #d0d0d0
selection_background  #d0d0d0
color0                #151515
color8                #505050
color1                #ac4142
color9                #ac4142
color2                #7e8d50
color10               #7e8d50
color3                #e5b566
color11               #e5b566
color4                #6c99ba
color12               #6c99ba
color5                #9e4e85
color13               #9e4e85
color6                #7dd5cf
color14               #7dd5cf
color7                #d0d0d0
color15               #f5f5f5
selection_foreground #202020

截图和录屏工具

我尝试过用grim+slurp截图,但是后面感觉这样用实在是太简陋了。我个人更推荐直接用hyprland-interactive-screenshot

# yay -S hyprland-interactive-screenshot-git

原理:Wayland桌面的架构

「之后填坑」