niri Waybar集成教程:工作区状态与系统信息显示配置

niri Waybar集成教程:工作区状态与系统信息显示配置

【免费下载链接】niri A scrollable-tiling Wayland compositor. 【免费下载链接】niri 项目地址: https://gitcode.com/GitHub_Trending/ni/niri

引言

你是否还在为Wayland环境下工作区状态无法实时同步而烦恼?是否希望将系统监控与窗口管理器状态无缝融合?本文将带你通过10分钟配置,实现niri compositor与Waybar的深度集成,打造兼顾美观与实用的桌面状态监控中心。

读完本文你将获得:

  • 实时工作区状态显示(含活动窗口数量、聚焦状态)
  • 低资源占用的事件驱动更新机制
  • 系统资源监控与工作区状态的一体化展示
  • 自适应明暗主题的UI设计方案

前置准备

环境要求

组件最低版本安装方式
niri≥0.1.9cargo install --git https://gitcode.com/GitHub_Trending/ni/niri
Waybar≥0.9.20各发行版官方仓库或源码编译
jq≥1.6系统包管理器安装
socat≥1.7.4系统包管理器安装

架构概览

mermaid

工作区状态模块配置

1. 基础数据采集脚本

创建~/.config/waybar/scripts/niri-workspaces.py

#!/usr/bin/env python3
import json
import os
import subprocess
import sys
from typing import Dict, List

def get_workspaces() -> List[Dict]:
    result = subprocess.run(
        ["niri", "msg", "--json", "workspaces"],
        capture_output=True,
        text=True
    )
    return json.loads(result.stdout)["Ok"]["Workspaces"]

def format_workspace(ws: Dict) -> str:
    icon = "●" if ws["is_focused"] else "○"
    return f"<span color='{ws['color']}'>{icon}</span>"

def main():
    workspaces = get_workspaces()
    output = {
        "text": " ".join(format_workspace(ws) for ws in workspaces),
        "class": "workspaces",
        "tooltip": "\n".join(f"Workspace {ws['index']}: {ws['window_count']} windows" for ws in workspaces)
    }
    print(json.dumps(output))

if __name__ == "__main__":
    main()

赋予执行权限:

chmod +x ~/.config/waybar/scripts/niri-workspaces.py

2. Waybar模块配置

~/.config/waybar/config中添加:

{
  "modules-left": ["custom/workspaces"],
  "custom/workspaces": {
    "exec": "~/.config/waybar/scripts/niri-workspaces.py",
    "interval": 1,
    "return-type": "json",
    "format": " {} ",
    "on-click": "niri msg action focus-workspace {button}",
    "tooltip": true
  }
}

3. 事件驱动优化

创建~/.config/waybar/scripts/niri-event-listener.sh

#!/bin/bash
socat - UNIX-CONNECT:"$NIRI_SOCKET" <<EOF
"Subscribe"
{"EventStream": {}}
EOF | while read -r event; do
    if echo "$event" | jq -e '.Ok.Event.WorkspaceChanged' > /dev/null; then
        pkill -RTMIN+8 waybar
    fi
done

修改Waybar模块为信号触发模式:

"custom/workspaces": {
  "exec": "~/.config/waybar/scripts/niri-workspaces.py",
  "signal": 8,
  "return-type": "json"
}

~/.config/systemd/user/waybar.service中添加事件监听器:

[Service]
ExecStartPre=/bin/sh -c '~/.config/waybar/scripts/niri-event-listener.sh &'
ExecStart=/usr/bin/waybar

系统信息集成

1. 混合模块配置

扩展Waybar配置,添加系统监控模块:

{
  "modules-right": ["custom/ipc-cpu", "custom/ipc-memory", "battery", "clock"],
  "custom/ipc-cpu": {
    "exec": "~/.config/waybar/scripts/niri-system-info.py cpu",
    "interval": 2,
    "return-type": "json"
  },
  "custom/ipc-memory": {
    "exec": "~/.config/waybar/scripts/niri-system-info.py memory",
    "interval": 5,
    "return-type": "json"
  }
}

2. 系统信息采集脚本

创建~/.config/waybar/scripts/niri-system-info.py

#!/usr/bin/env python3
import json
import sys
import psutil

def get_cpu_usage():
    return {
        "text": f"CPU {psutil.cpu_percent()}%",
        "class": "cpu",
        "percentage": psutil.cpu_percent()
    }

def get_memory_usage():
    mem = psutil.virtual_memory()
    return {
        "text": f"MEM {mem.percent}%",
        "class": "memory",
        "percentage": mem.percent
    }

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(json.dumps({"error": "Missing argument"}))
        sys.exit(1)
    
    if sys.argv[1] == "cpu":
        data = get_cpu_usage()
    elif sys.argv[1] == "memory":
        data = get_memory_usage()
    else:
        data = {"error": "Invalid argument"}
    
    print(json.dumps(data))

样式美化

1. 基础样式定义

~/.config/waybar/style.css中添加:

/* 工作区模块基础样式 */
#custom-workspaces {
    background: rgba(30, 30, 46, 0.8);
    padding: 0 10px;
    border-radius: 8px;
    margin: 4px 0;
}

/* 工作区状态指示 */
#custom-workspaces span {
    font-size: 12px;
    padding: 0 2px;
}

/* 系统信息模块 */
#custom-ipc-cpu, #custom-ipc-memory {
    padding: 0 8px;
    margin: 0 4px;
}

/* 资源占用警告样式 */
#custom-ipc-cpu.percentage-high, 
#custom-ipc-memory.percentage-high {
    color: #f38ba8;
}

2. 动态样式适配

修改系统信息脚本,添加动态样式类:

def get_cpu_usage():
    usage = psutil.cpu_percent()
    return {
        "text": f"CPU {usage}%",
        "class": "cpu" + (" percentage-high" if usage > 80 else ""),
        "percentage": usage
    }

高级配置

1. 多显示器工作区同步

mermaid

添加多显示器支持到工作区脚本:

def get_workspaces():
    result = subprocess.run(
        ["niri", "msg", "--json", "outputs"],
        capture_output=True,
        text=True
    )
    outputs = json.loads(result.stdout)["Ok"]["Outputs"]
    workspace_data = []
    for output in outputs:
        ws_result = subprocess.run(
            ["niri", "msg", "--json", f"workspaces --output {output['name']}"],
            capture_output=True,
            text=True
        )
        workspace_data.extend(json.loads(ws_result.stdout)["Ok"]["Workspaces"])
    return workspace_data

2. 窗口标题显示优化

添加窗口标题模块到Waybar配置:

"custom/window-title": {
  "exec": "~/.config/waybar/scripts/niri-window-title.py",
  "signal": 9,
  "return-type": "json"
}

窗口标题脚本:

#!/usr/bin/env python3
import json
import subprocess

def get_focused_window():
    result = subprocess.run(
        ["niri", "msg", "--json", "focused-window"],
        capture_output=True,
        text=True
    )
    return json.loads(result.stdout)["Ok"]["FocusedWindow"]

if __name__ == "__main__":
    window = get_focused_window() or {"title": "", "app_id": ""}
    text = window["title"] or window["app_id"]
    print(json.dumps({"text": text[:50] + "..." if len(text) > 50 else text}))

故障排除

常见问题解决

问题现象可能原因解决方案
工作区状态不更新事件监听器未运行systemctl --user restart waybar
JSON解析错误niri版本不匹配niri --version 确认≥0.1.9
Waybar崩溃脚本权限不足chmod +x 所有Python脚本
高CPU占用轮询间隔过短改用事件驱动模式

调试工具

# 监控niri事件流
niri msg --json event-stream | jq .

# 检查Waybar日志
waybar -l debug 2> ~/.waybar.log

# 验证IPC连接
socat STDIO "$NIRI_SOCKET"

总结与展望

通过本教程,我们构建了一个基于niri IPC事件流的高效工作区监控系统,实现了:

  • 微秒级响应的工作区状态更新
  • 模块化的系统资源监控设计
  • 自适应主题的UI展示方案

未来可能的扩展方向:

  • 集成窗口预览缩略图
  • 添加工作区切换动画效果
  • 实现基于机器学习的窗口自动分类

建议收藏本文,并关注项目GitCode仓库获取最新更新。如有疑问,欢迎在项目issue区提交反馈。

附录:完整配置文件

Waybar配置文件

{
  "height": 32,
  "modules-left": ["custom/workspaces", "custom/window-title"],
  "modules-right": ["custom/ipc-cpu", "custom/ipc-memory", "battery", "clock"],
  
  "custom/workspaces": {
    "exec": "~/.config/waybar/scripts/niri-workspaces.py",
    "signal": 8,
    "return-type": "json",
    "format": " {} "
  },
  
  "custom/window-title": {
    "exec": "~/.config/waybar/scripts/niri-window-title.py",
    "signal": 9,
    "return-type": "json",
    "max-length": 60
  },
  
  "custom/ipc-cpu": {
    "exec": "~/.config/waybar/scripts/niri-system-info.py cpu",
    "interval": 2,
    "return-type": "json"
  },
  
  "custom/ipc-memory": {
    "exec": "~/.config/waybar/scripts/niri-system-info.py memory",
    "interval": 5,
    "return-type": "json"
  }
}

【免费下载链接】niri A scrollable-tiling Wayland compositor. 【免费下载链接】niri 项目地址: https://gitcode.com/GitHub_Trending/ni/niri

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值