
niri一个用 Rust 编写的可滚动平铺 Wayland 合成器全面指南【免费下载链接】niriA scrollable-tiling Wayland compositor.项目地址: https://gitcode.com/GitHub_Trending/ni/niri导读niri 是一个从零为可滚动平铺scrollable tiling而构建的 Wayland 合成器窗口在无限延伸的水平条带上按列排布新窗口永远不会挤压已有窗口。本文以 niri 项目 README 为主体结合仓库内的 wiki 文档 与源码系统讲解其核心设计、功能特性、安装启动、配置体系与构建方式帮助你快速上手并深入理解这一滚动式窗口管理的实际用法。什么是 niriniri读作 niri是一个用 Rust 编写的 Wayland 合成器其核心设计理念是可滚动平铺scrollable tiling。与传统的平铺窗口管理器把窗口塞进有限屏幕不同niri 把窗口排列在一条无限向右延伸的条带上通过滚动视口来查看不同位置的窗口。这种布局方式带来了一个关键特性打开新窗口永远不会导致已有窗口被挤压或改变尺寸。窗口只是排在新列上视口滚动过去即可看到工作流完全围绕滚动而非缩放展开。niri 的设计灵感来自 [PaperWM]——一个运行在 GNOME Shell 之上的可滚动平铺扩展。项目作者在 README 中写道之所以决定自己编写合成器正是因为 PaperWM 作为 GNOME Shell 扩展必须对抗 Shell 的全局窗口坐标系来阻止窗口溢出相邻显示器。而在 niri 中多显示器隔离是从零设计的核心部分。从源码结构看niri 的主程序位于 src/采用模块化组织layout模块实现列、工作区与平铺逻辑input模块处理键盘、触控板与手势render_helpers负责着色器与渲染效果ipc模块提供niri msg命令所需的进程间通信niri-config与niri-ipc则是独立的配置解析与 IPC 库。仓库还包含完整的 视觉测试 与单元测试快照。核心设计无限条带、独立显示器与动态工作区README 的 About 部分概括了 niri 三大核心设计这些设计在 布局源码 与 Workspaces 文档 中有着具体体现。列与无限条带窗口在一条无限向右延伸的条带上按列排列。打开新窗口时它会在当前列的右侧创建新列已有窗口的尺寸与位置完全不受影响。当窗口超出屏幕范围时可以通过滚动或聚焦操作把视口移动到目标列。每台显示器拥有独立的窗口条带每个显示器monitor都有自己独立的窗口条带窗口永远不会溢出到相邻显示器。你可以在不同显示器上维护各自独立的列集合互不干扰。动态工作区工作区是动态的纵向排列每台显示器有一组独立的工作区显示器最底部始终存在一个空工作区当你在这个空工作区打开窗口时它下方会立即出现一个新的空工作区中间的空工作区在切换离开后会自动消失工作区在显示器断开/重连时会被保留断开时它们会移到另一台显示器重连时自动移回原显示器。工作区定位按索引与按名称niri 的focus-workspace 2、move-column-to-workspace 4等操作中的索引指的是当前恰好位于聚焦显示器该位置的工作区而不是一个固定编号。这与静态工作区系统有本质区别——工作区本身没有固定索引。若需要永久的工作区可以创建命名工作区或使用set-workspace-name动作。命名工作区即使变空也不会消失且可以按名称引用例如focus-workspace browser。示例工作流作者在 Workspaces.md 中分享了自己的使用习惯浏览器放在最上方工作区每个项目或事项一个工作区工作区内 1–2 个常切换的窗口偶尔需要的临时窗口放在视口外需要新的常驻窗口时放到新工作区然后通过move-workspace-up/down把它移到浏览器下方让一次focus-workspace-up/down就能到达目标。功能特性总览README 列出了 niri 的主要功能下面结合 wiki 文档 逐一展开说明其实际用法。从零构建的可滚动平铺这是 niri 最核心的特性如前所述体现在列式布局、无限条带与独立显示器设计上。类 GNOME 的动态工作区见上文动态工作区一节详细说明见 Workspaces.md。Overview总览视图niri 内置一个 Overview将工作区与窗口缩小展示方便快速定位与切换。相关配置位于顶层overview {}段Configuration:-Miscellaneous.mdoverview { zoom 0.5 backdrop-color #262626 workspace-shadow { // off softness 40 spread 10 offset x0 y10 color #00000050 } }zoom取值范围 0–0.75越小工作区缩得越小backdrop-color设置工作区背后的底色workspace-shadow控制总览中工作区后方的阴影其参数与布局中的shadow一致。内置截图 UIniri 自带交互式截图界面默认按键如下详见 Getting-Started.md按键功能PrtSc区域截图用鼠标框选区域按Space保存Escape取消AltPrtSc聚焦窗口截图存入剪贴板并保存到~/Pictures/Screenshots/CtrlPrtSc聚焦显示器截图同上截图保存路径可用顶层screenshot-path配置支持strftime(3)时间格式化设为null则只复制到剪贴板而不落盘screenshot-path ~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png屏幕录制xdg-desktop-portal-gnomeniri 通过 xdg-desktop-portal-gnome 支持显示器与窗口级别的屏幕录制并提供了两个特色能力block-out-from屏蔽敏感窗口通过窗口规则把密码管理器、聊天窗口等从录制中屏蔽为纯黑矩形动态录制目标录制目标可以在运行中切换所显示的内容。// 从屏幕录制中屏蔽密码管理器。 window-rule { match app-idr#^org\.keepassxc\.KeePassXC$# match app-idr#^org\.gnome\.World\.Secrets$# block-out-from screencast }需要说明的是block-out-from screencast只对 xdg-desktop-portal 的录制生效第三方截图工具仍可能拍到这些窗口若要彻底屏蔽应使用block-out-from screen-capture它会同时屏蔽自动截图动作内置交互式截图 UI 仍可使用。触控板与鼠标手势niri 支持触控板手势如三指滑动切换工作区与鼠标手势相关配置见 Gestures.md 与 Configuration:-Gestures.md。底层实现位于 input/scroll_swipe_gesture.rs 等输入模块。窗口标签页Tabs可以把多个窗口分组进同一列并切换显示形成类似浏览器标签页的体验。相关文档见 Tabs.md布局中的default-column-display可以设置新列的默认显示模式// 让所有新列默认以标签页模式显示。 layout { default-column-display tabbed tab-indicator { hide-when-single-tab } }可配置布局间隙、边框、struts、窗口尺寸布局配置集中在layout {}段Configuration:-Layout.md一个典型配置如下layout { gaps 16 center-focused-column never always-center-single-column empty-workspace-above-first default-column-display tabbed background-color #003300 preset-column-widths { proportion 0.33333 proportion 0.5 proportion 0.66667 } default-column-width { proportion 0.5; } preset-window-heights { proportion 0.33333 proportion 0.5 proportion 0.66667 } focus-ring { on width 4 active-color #7fc8ff inactive-color #505050 urgent-color #9b0000 } border { off width 4 active-color #ffc87f inactive-color #505050 urgent-color #9b0000 } shadow { off softness 30 spread 5 offset x0 y5 draw-behind-window true color #00000070 } struts { // left 64 // right 64 // top 64 // bottom 64 } }各选项要点gaps窗口内外的间隙逻辑像素支持小数会按各显示器缩放因子取整到物理像素center-focused-column切换焦点时何时居中列可选never默认靠边、always始终居中、on-overflow放不下时居中always-center-single-column工作区只有单列时始终居中empty-workspace-above-first除末尾外在最上方也保持一个空工作区preset-column-widths/preset-window-heightsswitch-preset-column-widthModR与switch-preset-window-heightModCtrlShiftR循环切换的尺寸档位proportion为输出宽度的比例已计入间隙fixed为精确的逻辑像素default-column-width新窗口的默认宽度空括号{}表示由窗口自己决定初始宽度struts收缩窗口占用区域类似外层间隙支持负值可用负 struts 配合gaps模拟仅内间隙效果。焦点环focus-ring与边框border两者的区别焦点环只画在活动窗口周围边框画在几乎所有窗口周围边框会占用窗口尺寸窗口缩小为其让位焦点环则不会。颜色支持多种写法CSS 命名色red、十六进制#rgb、#rrggbbaa等、CSS 函数式rgb(255, 127, 0)、hsl()等。还支持渐变layout { border { active-gradient from#ffbb66 to#ffc880 angle45 relative-toworkspace-view } }渐变渲染与 CSSlinear-gradient一致angle默认 180自上而下relative-toworkspace-view让渐变跨整个工作区视口而非单个窗口in...可指定插值颜色空间支持srgb默认、srgb-linear、oklab、oklch可配shorter/longer/increasing/decreasing hue。一个细节默认情况下焦点环/边框是画在窗口背后的实色矩形因此会透过半透明窗口显示出来因为 CSD 窗口形状任意。如果不喜欢可以启用顶层prefer-no-csdniri 会对同意去掉 CSD 的窗口把焦点环/边框画在窗口周围也可用draw-border-with-background窗口规则按窗口覆盖。阴影shadowshadow选项支持softness模糊半径、spread扩展量25.05 起可为负、offset偏移、color颜色与透明度、draw-behind-window画在窗口背后以规避 CSD 圆角伪影、inactive-color。阴影绘制会跟随geometry-corner-radius窗口规则设置的圆角。支持 Oklab / Oklch 的渐变边框如上所述渐变边框不仅支持普通 sRGB 插值还支持Oklab 与 Oklch颜色空间。从源码看niri-visual-tests 中包含 gradient_oklab.rs、gradient_oklch_longer.rs 等一系列针对这些颜色空间的渲染测试用例用于验证不同插值模式shorter/longer/increasing/decreasing hue与 alpha 通道的渲染结果。窗口与 layer-shell 表面的背景模糊niri 支持为窗口和 layer-shell 表面启用背景模糊Window-Effects.md并有高效的 xray 模糊模式。全局模糊参数在顶层blur {}段配置// 默认值如下 blur { // off passes 3 offset 3 noise 0.02 saturation 1.5 }passes双 Kawase 模糊的下采样/上采样次数越多越平滑但越耗 GPUoffset每遍的像素偏移倍数1是原始双 Kawase 模糊调大更平滑且不增加 GPU 开销但过大会出现伪影此时需增加passesnoise叠加噪点以减轻色带saturation背景饱和度大于 1 增强、小于 1 减弱off关闭全部模糊包括窗口主动请求的。窗口规则中的background-effect可按窗口覆盖 xray/blur/noise/saturation。注意非 xray 模糊目前是实验特性窗口打开/关闭动画期间不生效。支持自定义着色器的动画niri 内置弹簧/贝塞尔动画src/animation/并支持为窗口打开、关闭、调整大小等动画挂载自定义着色器。仓库中 src/render_helpers/shaders/ 提供了一组现成的 GLSL 着色器模板如close_prelude.frag、open_epilogue.frag、resize.frag、gradient_fade.frag等docs/wiki/examples/ 里还有可直接参考的close_custom_shader.frag、open_custom_shader.frag、resize_custom_shader.frag示例。配置热重载niri 的配置是实时重载的编辑并保存配置文件键位绑定、输出模式、窗口规则等所有变更会立即生效无需重启。详见下文配置体系。屏幕阅读器支持niri 支持无障碍屏幕阅读器相关说明见 Accessibility.mdDBus 实现位于 src/dbus/freedesktop_a11y.rs。状态与常见问题FAQ 式要点README 的 Status 部分回答了社区最关心的几个问题问题niri 的现状多显示器支持且是设计之初的核心部分混合 DPI 可用分数缩放支持且 niri 自身 UI 保持像素级完美NVIDIA看起来工作正常详见 Nvidia.md浮动窗口支持自 niri 25.01 起输入设备支持数位板可映射到指定显示器也可用 OpenTabletDriver、触控板、触摸屏有触控板手势暂无触摸屏手势wlr 协议支持大多数重要协议如 layer-shell、gamma-control、screencopy可在 wayland.app 各协议页面底部查看性能作者表示会留意性能开销据称有人在 2008 年的 Eee PC 900 上也能流畅运行Xwayland自 niri 25.08 起通过xwayland-satellite集成详见 Xwayland.mdREADME 强调niri 本身并不是一个完整的桌面环境。它稳定到可以日常使用但需要搭配桌面外壳如 [DankMaterialShell] 或 [Noctalia]或传统组件状态栏、启动器、通知守护进程等才能构成完整桌面相关软件清单见 Important-Software.md。安装与启动快速开始README 推荐的快速上手方式是安装发行版软件包并搭配 DankMaterialShellFedorasudo dnf copr enable avengemedia/dms sudo dnf install niri dms systemctl --user add-wants niri.service dmsArch Linuxsudo pacman -Syu niri xwayland-satellite xdg-desktop-portal-gnome xdg-desktop-portal-gtk alacritty dms-shell-niri matugen cava qt6-multimedia-ffmpeg systemctl --user add-wants niri.service dmsUbuntu 25.10sudo add-apt-repository ppa:avengemedia/danklinux sudo add-apt-repository ppa:avengemedia/dms sudo apt install niri dms安装后注销在显示管理器中选择 Niri登录若不使用显示管理器则在 TTY 上运行niri-session。注意默认 niri 配置会启动 Waybar如果同时使用 DMS 的栏可能会出现两个栏可用pkill waybar停掉并删除~/.config/niri/config.kdl中的spawn-at-startup waybar一行。其他发行版软件包还包括 Fedora COPR、NixOS Flake 等Debian 系还有 pacstall 包。完整的打包说明见 Packaging-niri.md。从 TTY 启动与嵌套窗口无显示管理器时从 TTY 运行niri-sessionsystemd/dinit或niri --session其他。--session会把环境变量全局导入系统管理器与 D-Bus 并启动 D-Bus 服务niri-session还会把 niri 作为 systemd/dinit 服务启动拉起图形会话 targetportal 等服务需要。也可以直接在已有桌面会话里运行niri它会以窗口形式打开。注意窗口模式主要面向开发调试略有瑕疵尤其是热键。常见启动问题NVIDIA 黑屏先更新驱动需支持 GBM 的较新 GPU/驱动并确保内核开启 modeset通常在内核命令行加nvidia-drm.modeset1。Asahi/ARM/kmsro 设备黑屏可能是主渲染设备检测错误。查看/dev/dri/下的设备然后在配置中手动指定debug { render-drm-device /dev/dri/renderD128 }NixOS注意系统 mesa 与 niri 的 mesa 版本需一致否则 TTY 启动可能黑屏Intel 显卡可能需要额外 workaround。虚拟机务必开启 3D 加速。默认热键速查在 TTY 上运行时Mod 键是Super在嵌套窗口运行时是Alt。总体规律某个热键负责切换焦点到某处那么加上Ctrl就变成把焦点窗口/列移动到某处。热键功能ModShift/显示重要热键列表ModT/ModD启动alacritty终端/fuzzel启动器SuperAltL启动swaylockModQ关闭聚焦窗口ModH/←、ModL/→聚焦左/右列ModJ/↓、ModK/↑聚焦列内下/上窗口ModCtrlH/L/J/K移动聚焦列/窗口ModShiftHJKL聚焦相邻显示器ModCtrlShiftHJKL移动列到相邻显示器ModU/PageDown、ModI/PageUp切换到下/上一个工作区ModCtrlU/I、ModShiftU/I移动列/工作区到下/上一个工作区Mod[/Mod]向左/右吞并或弹出聚焦窗口ModR/ModShiftR向前/向后切换预设列宽ModM/ModC最大化窗口 / 视口内居中列Mod-/Mod列宽减/增 10%ModShift-/ModShift窗口高减/增 10%ModCtrlR窗口高度重置为自动ModShiftF切换全屏ModV/ModShiftV窗口在浮动/平铺间移动 / 焦点在浮动与平铺间切换ModShiftE或CtrlAltDelete退出 niri完整热键与动作说明见 Configuration:-Key-Bindings.md。配置体系配置文件位置与加载niri 会按顺序查找$XDG_CONFIG_HOME/niri/config.kdl即通常的~/.config/niri/config.kdl回退到/etc/niri/config.kdl。若两者都不存在niri 会创建用户配置并把默认配置文件构建时嵌入二进制写进去。建议以默认配置为起点修改。配置实时重载保存即生效无需重启运行niri validate可解析配置并查看错误用--config/-c参数或环境变量$NIRI_CONFIG指定其他路径--config优先级更高路径无效则不加载配置。语法KDL配置使用 KDL 格式编写//开头是注释/-放在节点前可整段注释掉/-output eDP-1 { off }开关型选项是标志flag写出即启用省略或注释即禁用input { focus-follows-mouse // 启用 // focus-follows-mouse // 禁用 }大部分段不可重复例外如按设备名区分的段output eDP-1 {}、output HDMI-A-1 {}合法但同名输出重复出现不合法省略大部分段会使用默认值但binds {}不会自动填充默认值务必保留该段。配置段索引Configuration:-Introduction.md 按段列出了各专题文档input {}——键盘、鼠标、触控板、数位板等输入设备output eDP-1 {}——输出模式、缩放、变换、位置binds {}——键位绑定与动作switch-events {}layout {}——布局与窗口外观顶层选项——spawn-at-startup、prefer-no-csd、cursor、overview等window-rule {}——按窗口匹配的规则layer-rule {}——layer-shell 表面规则animations {}gestures {}recent-windows {}debug {}include other.kdl——引入其他配置文件。破坏性变更政策niri 遵循一条原则正式发布版本不应破坏已有配置文件例如 v0.1.0 的默认配置在 v25.02 上仍可解析。例外仅限解析 bug 的修复如曾经允许多个键绑定同一按键后改为解析失败。该政策只对正式发布生效发布之间的 git 提交可能临时破坏配置。深入窗口规则window-rule窗口规则是 niri 精细控制单个窗口行为的主要手段按配置文件中的出现顺序处理支持match与exclude指令窗口需匹配任一match且不匹配任何exclude才应用该规则。// 先给所有窗口设置 open-maximizedtrue…… window-rule { open-maximized true } // ……再对 Alacritty 覆盖回 false。 window-rule { match app-idAlacritty open-maximized false }常用匹配器包括title/app-id正则任意位置匹配、is-active、is-focused、is-active-in-column、is-floating、is-window-cast-target、is-urgent、at-startup启动后前 60 秒。正则建议使用 KDL 原始字符串如match app-idr#^org\.telegram\.desktop$#。窗口属性分为两类开窗时生效应用于初始 configure 请求default-column-width、default-window-height、open-on-output、open-on-workspace、open-maximized、open-maximized-to-edges、open-fullscreen、open-floating、open-focused持续生效block-out-from、opacity、variable-refresh-rate、default-column-display、default-floating-position、scroll-factor、draw-border-with-background、focus-ring/border/shadow/tab-indicator覆盖、geometry-corner-radius、clip-to-geometry、tiled-state、background-effect、popups以及min-width/max-width/min-height/max-height尺寸约束。一个实用的组合示例——为 Firefox 画中画窗口设置浮动、固定尺寸并停靠屏幕左下角window-rule { match app-idfirefox$ title^Picture-in-Picture$ open-floating true default-column-width { fixed 480; } default-window-height { fixed 270; } default-floating-position x32 y32 relative-tobottom-left }default-floating-position的坐标相对于工作区relative-to支持top-left、top-right、bottom-left、bottom-right、top、bottom、left、right坐标方向随基准变化如bottom-left时y向上为正。查看窗口的 title/app-id 可运行niri msg pick-window后点击目标窗口。键位绑定与动作binds {}段中每个绑定由热键加花括号动作构成binds { ModLeft { focus-column-left; } SuperAltL { spawn swaylock; } }热键由连接的修饰键加末尾的 XKB 键名组成。合法修饰键Ctrl/Control、Shift、Alt、Super/Win、ISO_Level3_Shift/Mod5AltGr、ISO_Level5_Shift以及特殊的ModTTY 下等于 Super嵌套窗口下等于 Alt自 25.05 起可在input段自定义。查找键名可用wev等工具。绑定还支持repeatfalse关闭按住连发默认连发cooldown-ms500限流防止过快重复触发常用于滚轮绑定滚动绑定ModWheelScrollDown/Up/Left/Right与ModTouchpadScrollDown/Up会随natural-scroll改变方向且按住修饰键时滚动事件会被 niri 消费、不再传给应用鼠标点击绑定25.01ModMouseLeft等作用于点击时聚焦的窗口而非被点击的窗口绑定ModMouseLeft/Right会覆盖对应的移动/调整大小手势热键总览自定义hotkey-overlay-title给绑定设置标题以显示在重要热键列表中或设为null隐藏硬编码绑定标题支持 Pango markup。关于spawn动作niri 不用 shell 执行命令参数必须逐项分开需要变量/管道/~展开时用spawn-sh25.08等价于spawn sh -c ...或手动包一层sh -c。唯一的特例是程序名开头的~会被展开。每个动作都可通过niri msg action以编程方式调用如niri msg action do-screen-transition触发主题切换的屏幕过渡动画运行niri msg action可列出全部动作。构建 niri从源码构建安装依赖Ubuntu 24.04 示例sudo apt-get install -y gcc clang libudev-dev libgbm-dev libxkbcommon-dev libegl1-mesa-dev libwayland-dev libinput-dev libdbus-1-dev libsystemd-dev libseat-dev libpipewire-0.3-dev libpango1.0-dev libdisplay-info-devFedora 对应包为gcc libudev-devel libgbm-devel libxkbcommon-devel wayland-devel libinput-devel dbus-devel systemd-devel libseat-devel pipewire-devel pango-devel cairo-gobject-devel clang libdisplay-info-devel。安装最新稳定版 Rusthttps://rustup.rs/构建cargo build --release特性列表见 Cargo.toml。例如用 dinit 替代 systemdcargo build --release --no-default-features --features dinit,dbus,xdp-gnome-screencast警告不要用--all-features构建部分特性仅用于开发例如某个特性会开启无上限增长的内存 profiling 缓冲区。NixOS / Nix社区维护的 flake 提供带全部依赖的 devshell用nix build构建后运行./results/bin/niri非 NixOS 可能需要 NixGLnix run --impure github:guibou/nixGL -- ./results/bin/niri手动安装文件位置不通过包管理器安装时建议按以下位置放置文件需确保niri.service中的 niri 路径正确默认/usr/bin/niri文件目标目录target/release/niri/usr/local/bin/resources/niri-session/usr/local/bin/resources/niri.desktop/usr/local/share/wayland-sessions/resources/niri-portals.conf/usr/local/share/xdg-desktop-portal/resources/niri.servicesystemd/etc/systemd/user/resources/niri-shutdown.targetsystemd/etc/systemd/user/resources/dinit/niridinit/etc/dinit.d/user/resources/dinit/niri.targetdinit/etc/dinit.d/user/这些资源文件在仓库中均可找到resources/niri-session、resources/niri.desktop、resources/niri-portals.conf、resources/niri.service等。生态与周边桌面外壳niri 本身不是完整桌面环境可搭配 DankMaterialShell、Noctalia 等 Quickshell 外壳或 LXQt官方支持 niri、XFCE 组件、COSMIC 会话通过cosmic-ext-extra-sessions社区资源awesome-niri 汇总了 niri 相关的链接与项目主沟通渠道是 Matrix 频道另有社区 Discord同类项目README 列举了其他实现类似工作流的项目——[PaperWM]GNOME Shell、[karousel]KDE、scroll 与 paperswaysway/i3、Hyprland 内置的 scrolling layout、Paneru 与 PaperWM.spoonmacOS贡献无论编程还是非编程方式都欢迎概览见 CONTRIBUTING.md。小结niri 用无限条带 独立显示器 动态纵向工作区的组合重新定义了平铺窗口管理的交互模型在保留传统平铺列内纵向堆叠、浮动窗口、标签页、工作区的实用功能的同时用滚动取代了挤压。它提供了热重载的 KDL 配置、可编程的窗口规则、内置截图与录制屏蔽、渐变边框/阴影/模糊等丰富的视觉效果并且从底层支持多显示器、混合 DPI 与分数缩放。无论你是想尝试一种全新的窗口管理方式还是想研究一个现代 Rust Wayland 合成器的完整实现niri 都是一个值得深入的项目。继续阅读Getting-Started.md 与配置入门 是两条最合适的后续路线README.md 中的各功能链接则指向全部专题文档。【免费下载链接】niriA scrollable-tiling Wayland compositor.项目地址: https://gitcode.com/GitHub_Trending/ni/niri创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考