前言

在经历了一系列的思想斗争、反复重装系统,在kde和niri中疯狂徘徊后,我还是选择了niri作为我的主要桌面环境,谁让我闲得没事干呢。

下面介绍一下目前我的所有配置。

xwayland-satellite 配置

这是niri用于兼容x11的方式,不整这个将无法打开vscode、chrome、qq等软件。

首先下载:

yay -S xwayland-satellite

下载完成后,去niri的配置文件中修改:

vim ~/.config/niri/config.kdl

在这里找个没被花括号包裹的地方写下面的内容就行。

niri的配置文件默认会有一个 spawn-at-startup "waybar",写一起好一点,也方便管理。

spawn-at-startup "xwayland-satellite"
environment {
    DISPLAY ":1"
}

图片-Whed.png

截图配置

很多截图软件似乎在wayland下无法运行,不过也是有毛坯房可以搭起来的。

我这里使用了grim和slurp的方式。

yay -S grim slurp

其中,grim用于截图,slurp用于选择框的大小。

如果命令行直接输入grim,那么会给你截全屏,然后保存到图片文件夹下面。

命令行直接输入slurp会有一个截图框的出现,选择区域后会返回对应的坐标信息。

那么这俩就可以打配合,实现正常截图工具可以完成的任务。

下面写一个脚本screenshot.sh:

# 定义截图目录
SCREENSHOT_DIR="$HOME/图片/Screenshots"
mkdir -p "$SCREENSHOT_DIR"

# 生成时间戳
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# 定义截图文件路径
FILE="$SCREENSHOT_DIR/screenshot_$TIMESTAMP.png"

# 判断截图模式
if [ "$1" == "full" ]; then
    MODE="全屏截图"
    # 使用 grim 进行全屏截图
    grim "$FILE"
else
    MODE="区域截图"
    # 使用 slurp 选择截图区域并使用 grim 进行截图
    grim -g "$(slurp)" "$FILE"
fi

# 检查截图是否成功
if [ $? -eq 0 ]; then
    # 复制截图到剪贴板
    wl-copy < "$FILE"

    # 发送截图完成通知
    notify-send "截图完成" "已保存至: $FILE 并已复制到剪贴板"
else
    notify-send "截图失败" "未能成功捕获屏幕"
fi

exit 0

那么只需要运行这个脚本就可以实现截图了。

接下来再设置快捷键:

vim ~/.config/niri/config.kdl

在”binds"下面,可以看到一堆由Mod+... {...}组成的配置,这里就是配置快捷键的地方。

找个地方写下你的配置:“快捷键” {spawn "执行命令";}

图片-mYeu.png

被qq毒害了,导致现在只会ctrl+alt+A

文件管理

首先,我认为niri默认的文件管理就是依托。

和kde的文件管理差远了。

但是如果你喜欢命令行和快捷的话(都玩平铺式了还不all in keyboard吗?)可以试试superfile。

yay -S superfile

命令行输入spf进入superfile界面。

图片-XIIb.png

效果 按键
进入父文件夹
进入子文件夹
选择文件 ↑ or ↓
创建文件 ctrl + N
编辑文件 E
重命名文件 ctrl + R

不得不说,这个图像预览还是很抽象的,命令行还真能预览啊。至少是能一眼认出来是啥。

图片-PWgE.png

waybar的配置

{  
    "layer": "top", // 状态栏层级:top(显示在窗口前)或 bottom(显示在窗口后):cite[1]
    "position": "top", // 状态栏位置:top, bottom, left, right:cite[1]
    "height": 30, // 状态栏高度(像素):cite[1]
    "margin-top": "5px", // 边距设置(支持 margin-top/right/bottom/left):cite[6]
    "spacing": 5, // 模块之间的间距(像素):cite[1]
    "modules-left": ["niri/workspaces", "niri/mode"],
    "modules-center": ["clock"],
    "modules-right": ["custom/powerProfile","backlight","custom/pipewire","cpu","memory","battery", "tray","custom/power"]
}

这是我朴实无华的布局。

先着重讲一下我功能配置,美化什么的算了罢。

屏幕亮度调节

需要下载插件 brightnessctl

yay -S brightnessctl

然后再修改 ~/.config/waybar/config

这里我使用了鼠标放到组件上滑动的方式来调节屏幕亮度。

重点是“on-scroll-down”和“on-scroll-up”这两个配置。

注意!屏幕亮度是可以降到0的,这时候眼睛瞎了、并且也没有绑定快捷键的话。。。

可以自己写脚本来调节,可以避免一下子调到0了。

    "backlight":{
	"format":"{icon}{percent: >3}%",
	"format-icons":["🌞"],
	"on-scroll-down":"brightnessctl -c backlight set 5%-",
	"on-scroll-up":"brightnessctl -c backlight set +5%",
	"on-click":""
    },

音量调节

custom开头的代表这是一个自定义组件。

显示的信息为"format"的内容,而{}指代为"exec"的输出(print),这里可以按你自己的想法写脚本。

    "custom/pipewire":{
        "exec":"~/.config/waybar/pipewire.sh",
	    "interval":1,
	    "format":"{}",
        "on-scroll-down":" wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-",
        "on-scroll-up":" wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+",
        "on-click":""
    },

其中wpctl是用来配置pipewire的设置的。

这里我写了个脚本,用于读取当前设备的音量:

pipe_status=$(wpctl status)
device=$(echo "$pipe_status" | sed -n '/Sinks:/,/Sources:/p' | head -n -1 | grep "*")
vol=$(echo "$device" | grep -oP '(?<=\[vol:)[^]]*(?=\])')
if [[ $vol =~ " MUTED" ]]; then
  percentage=$(awk -v num="${vol// MUTED/}" 'BEGIN {printf "%.0f", num * 100}')
  echo " ${percentage}%"
else
  percentage=$(awk -v num="${vol}" 'BEGIN {printf "%.0f", num * 100}')
  echo "  $percentage%"
fi
exit 0

关机键

"custom/power":{
	"format":"⏻ ",
	"on-click":"wlogout -p layer-shell",
	"tooltip":false
    },

下载wlogout就完了。

图片-Iyek.png

电源管理

下载 power-profiles-daemon

yay -S power-profiles-daemon
    "custom/powerProfile":{
	    "exec":"~/script/power/target/release/power",
	    "interval":100,
	    "format":"{}",
	    "on-click":"~/script/power/target/release/power toggle"
    }

脚本在这里:

use std::process::Command;
use std::env;
fn get_mode()->String{
    match Command::new("powerprofilesctl")
        .arg("get")
        .output() {
        Ok(output) => {
            if output.status.success() {
                let stdout = String::from_utf8_lossy(&output.stdout);
                return stdout.trim().to_string();
            } else {
                return "".to_string();
            }
        }
        Err(e) => {
            eprintln!("Error: {}", e);
            return "".to_string();
        }
    }
}
fn toggle(){
    let mode = get_mode();
    if mode.contains("performance"){
        Command::new("powerprofilesctl")
        .arg("set")
        .arg("balanced")
        .output()
        .expect("Failed to execute command");
    }else if mode.contains("balanced"){
        Command::new("powerprofilesctl")
        .arg("set")
        .arg("power-saver")
        .output()
        .expect("Failed to execute command");
    }else if mode.contains("power-saver"){
        Command::new("powerprofilesctl")
        .arg("set")
        .arg("performance")
        .output()
        .expect("Failed to execute command");
    }else{
        eprintln!("unknown mode");
        return
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() == 1 {
        println!("{}", get_mode());
    } else if args[1] == "toggle" {
        toggle();
    } else {
        eprintln!("Usage: {} [get|toggle]", args[0]);
    }
}

就一个查询当前的模式和点击切换模式而已,这个用sh写才是最佳选择。为什么用rust呢,因为我完全不会rust,打算all in rust一段时间。

蓝牙(开发中)

现在只会用bluetoothctl来连接,blueman会连接不上,不知道为什么,等我自己写一个窗口罢。

整体

{
    "layer": "top", // 状态栏层级:top(显示在窗口前)或 bottom(显示在窗口后):cite[1]
    "position": "top", // 状态栏位置:top, bottom, left, right:cite[1]
    "height": 30, // 状态栏高度(像素):cite[1]
    "margin-top": "5px", // 边距设置(支持 margin-top/right/bottom/left):cite[6]
    "spacing": 5, // 模块之间的间距(像素):cite[1]
    "modules-left": ["niri/workspaces", "niri/mode"],
    "modules-center": ["clock"],
    "modules-right": ["custom/powerProfile","backlight","custom/pipewire","cpu","memory","battery", "tray","custom/power"],
    "niri/workspaces":{
        "disable-scroll":true,
        "all-outputs":true,
        "format":"{icon}"
    },
    "clock": {
        "interval": 1, // 刷新间隔(秒)
        "format": "{:%Y-%m-%d %H:%M:%S}" // 显示格式
    },
    "battery": {
    	"bat": "BAT0", // 电池标识(通常是BAT0)
    	"interval": 30, // 检查间隔
    	"format": "{capacity}% {icon}", // 显示格式
    	"format-charging": "{capacity}% ﮣ", // 充电时的格式
    	"format-plugged": "{capacity}% ", // 接通电源时的格式
    	"states": {
            "warning": 30, // 警告状态阈值
            "critical": 15 // 严重状态阈值
    	}
    },
    "cpu": {
    	"interval": 5,
    	"format": "  {usage}%"
    },
    "memory": {
    	"interval": 5,
    	"format": "󰓅  {percentage}%"
    },
    "backlight":{
	"format":"{icon}{percent: >3}%",
	"format-icons":["🌞"],
	"on-scroll-down":"brightnessctl -c backlight set 5%-",
	"on-scroll-up":"brightnessctl -c backlight set +5%",
	"on-click":""
    },
    "custom/power":{
	"format":"⏻ ",
	"on-click":"wlogout -p layer-shell",
	"tooltip":false
    },
    "custom/pipewire":{
        "exec":"~/.config/waybar/pipewire",
	"interval":1,
	"format":"{}",
        "on-scroll-down":" wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-",
        "on-scroll-up":" wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+",
        "on-click":""
    },
    "custom/powerProfile":{
	    "exec":"~/script/power/target/release/power",
	    "interval":100,
	    "format":"{}",
	    "on-click":"~/script/power/target/release/power toggle"
    }
}



niri配置

删除窗口栏

你是否觉得niri默认的终端非常难看,带着一个大白边,和一辈子也点不了一次的x键。

现在进入 ~/.config/niri/config.kdl,在200多行的位置找到 //prefer-no-csd,然后取消它的注释。

窗口边框颜色设置。

还是在config,kdl里面,找到layout下的focus-ring,给它的 //off注释删了。

图片-PAiV.png

再在下面的border下,把 off注释了。顺便再调一下颜色。

图片-fXPx.png

终端透明度设置

打开 ~/.config/alacritty/alacritty.toml

[window]
opacity = 0.7  # 设置透明度,1.0为完全不透明

然后就结束了。

毕竟alacritty只是一个5mb大的轻量终端,随便配置一下得了。

要帅的去看看kitty。

最终效果

图片-WvBp.png