niri 布局配置完全指南:用 `layout {}` 精确控制窗口的定位、尺寸与外观

发布时间:2026/9/10 14:03:25
niri 布局配置完全指南:用 `layout {}` 精确控制窗口的定位、尺寸与外观 niri 布局配置完全指南用layout {}精确控制窗口的定位、尺寸与外观【免费下载链接】niriA scrollable-tiling Wayland compositor.项目地址: https://gitcode.com/GitHub_Trending/ni/nirilayout {}是 niri 配置中最核心的区块之一它决定了窗口如何被摆放和缩放这一滚动平铺布局的基本行为从窗口之间的间隙gaps、列宽与窗高的预设比例、焦点指示focus ring / border、窗口阴影、标签指示器到插入提示与屏幕边缘 struts。本文基于 niri 仓库的官方配置文档docs/wiki/Configuration:-Layout.md与其源码实现niri-config/src/layout.rs、niri-config/src/appearance.rs、resources/default-config.kdl完整梳理该区块的全部配置项、默认值与底层实现并给出可直接粘贴到~/.config/niri/config.kdl使用的实战示例。读完本文你将能够按输出比例或固定逻辑像素精确设定列宽与窗高自定义焦点环、边框、阴影、渐变与标签指示器的外观通过 struts 模拟内/外间隙并控制工作区边缘行为。一、layout {}区块总览所有影响窗口定位与尺寸的设置都收敛在layout {}节点内。以下是该区块的完整面貌省略号处为可在下文对应小节找到的更细配置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 } tab-indicator { on hide-when-single-tab place-within-column gap 5 width 4 length total-proportion1.0 position right gaps-between-tabs 2 corner-radius 8 active-color red inactive-color gray urgent-color blue } insert-hint { on color #ffc87f80 } struts { // left 64 // right 64 // top 64 // bottom 64 } }自版本 25.11 起这些设置还可以针对特定 输出outputs 和 命名工作区named workspaces 进行局部覆盖实现不同显示器/不同工作区使用不同布局参数。从源码看niri-config/src/layout.rs 中的Layout结构体完整承载了这些字段其Default实现给出了所有默认值gaps为 16preset_column_widths与preset_window_heights默认均为 1/3、1/2、2/3 三档default_column_width默认为Proportion(0.5)center_focused_column默认为Neverdefault_column_display默认为Normal背景色为默认的灰调[0.25, 0.25, 0.25, 1]。解析时LayoutPart通过 knuffel 反序列化配置树并由merge_with把配置片段与默认值合并layout.rs因此你可以只写出想改动的项其余保持默认。二、窗口间隙gapsgaps设置窗口周围内侧与外侧的间隙单位为逻辑像素layout { gaps 16 }三个值得注意的细节支持小数自 0.1.7 起值会按每个输出的 scale 因子取整到物理像素。例如在scale 2的输出上设置gaps 0.5得到的将是 1 物理像素宽的间隙。因此想要一个物理像素的精致细线时可以用gaps 0.5配合高倍率输出。可模拟内/外间隙自 0.1.8 起用负的struts值与gaps搭配可以把内间隙与外间隙区分开具体见下文 struts 小节。取值范围从源码的FloatOrInt0, 65535可见gaps只接受 0 到 65535 之间的数值layout.rs。在布局引擎中gaps直接参与窗口位置与尺寸计算例如x x self.options.layout.gaps / 2.src/layout/scrolling.rs列间距离累加col_x col_w self.options.layout.gapsscrolling.rs。这也解释了为何proportion预设宽度考虑了 gaps——比例是基于扣除间隙后的工作区计算的。三、焦点时列的居中行为center-focused-column与always-center-single-column滚动平铺下切换焦点时视口如何移动由center-focused-column决定可选三个值never默认不做特殊居中。聚焦一个屏幕外的列时会把它滚动到屏幕的左边缘或右边缘。always聚焦的列始终被居中。on-overflow只有目标列与先前聚焦的列无法同时放进屏幕时才将其居中能同时容纳则正常滚动。layout { center-focused-column always }在源码中这一分支逻辑位于 src/layout/scrolling.rs 的compute_new_view_offset_for_columnAlways直接走居中计算OnOverflow会取目标列左/右邻居作为源列估算两列总宽度含gaps * 2.若总宽度 working_area.size.w则走普通适配否则居中Never则始终走贴合边缘路径。也就是说on-overflow在窄屏多列场景下能最大限度减少视口无谓跳动而always适合单列为主的用法。always-center-single-column自 0.1.9 起是独立开关只要工作区里只有一列无论center-focused-column设为何值都将其居中layout { always-center-single-column }两者结合可以做到单列时居中、多列时按需滚动的理想体验。四、工作区管理empty-workspace-above-first与background-colorempty-workspace-above-first默认情况下niri 只在末尾追加一个空工作区开启该选项后会在最开头也始终保留一个空工作区自 25.01 起layout { empty-workspace-above-first }这在源码中有大量配套逻辑工作区索引的偏移计算src/layout/monitor.rs、防止删除首工作区monitor.rs、以及切换时的边界处理monitor.rs等都针对第一个工作区必须为空这一约束做了专门处理。如果你习惯把所有工作放在最左端、希望左侧永远有一个空位来停下这个选项会很有用。background-color自 25.05 起可以设置 niri 为工作区绘制的默认背景色。它只在没有使用 swaybg 之类的背景工具时可见layout { background-color #003300 }源码中的默认值是Color::from_array_unpremul([0.25, 0.25, 0.25, 1.])niri-config/src/appearance.rs即中等灰、完全不透明。颜色同样支持在 输出配置 中按输出单独覆盖。五、列显示模式default-column-display自 25.02 起可以设置新建列的默认显示模式取值为normal或tabbed// 让所有新列默认以标签页tabbed形式显示。 layout { default-column-display tabbed // 通常还会顺便隐藏只有一个窗口时的标签指示器。 tab-indicator { hide-when-single-tab } }tabbed模式把同一列中的多个窗口折叠成标签页配合下方tab-indicator的样式定制可以在不损失窗口数量上限的前提下大幅节省屏幕空间。列显示模式在 IPC 类型中由ColumnDisplay枚举表达normal/tabbed并随Layout一并解析进运行时选项niri-config/src/layout.rs。六、列宽与窗高预设preset-column-widths、default-column-width、preset-window-heightspreset-column-widthsModR 循环的列宽档位设置switch-preset-column-width动作默认绑定ModR所循环切换的宽度档位自 25.08 起还可用switch-preset-column-width-back默认绑定ModShiftR反向循环见 resources/default-config.kdl 与 niri-config/src/binds.rs。proportion宽度为输出宽度的一个比例已计入 gaps。例如设置proportion 0.25无论 gaps 多大都能在输出上恰好并排放下四个窗口。fixed以逻辑像素精确指定窗口宽度。默认档位为输出的 1/3、1/2、2/3。layout { // 在输出的 1/3、1/2、2/3 与固定 1280 逻辑像素之间循环。 preset-column-widths { proportion 0.33333 proportion 0.5 proportion 0.66667 fixed 1280 } }源码中PresetSize只有Proportion(f64)与Fixed(i32)两种变体layout.rs并转换为 IPC 的SizeChange比例会被乘以 100 作为SetProportion固定值作为SetFixed发送layout.rs。default-column-width新窗口的初始宽度语法与preset-column-widths完全一致设置新建窗口的默认宽度layout { // 新窗口默认占输出的 1/3。 default-column-width { proportion 0.33333; } }也可以把括号留空让窗口自己决定初始宽度layout { // 新窗口自己决定初始宽度。 default-column-width {} }[!NOTE]default-column-width {}会让 niri 在初始 configure 请求中发送(0, H)尺寸。这一行为在 Wayland 协议中定义得有些含糊个别客户端可能误解。因此default-column-width {}更适合以 window rule 的形式针对特定窗口使用——仓库默认配置中就为 WezTerm 的初始 configure bug 设置了window-rule { match app-idr#^org\.wezfurlong\.wezterm$# default-column-width {} }resources/default-config.kdl。preset-window-heightsModCtrlShiftR 循环的窗高档位自 0.1.9 起可用设置switch-preset-window-height动作默认绑定ModCtrlShiftR循环的高度档位自 25.08 起新增反向动作switch-preset-window-height-back默认未绑定。proportion高度为输出高度的一个比例已计入 gaps。fixed以逻辑像素精确指定高度。默认档位同样是输出的 1/3、1/2、2/3layout { // 在输出的 1/3、1/2、2/3 与固定 720 逻辑像素之间循环。 preset-window-heights { proportion 0.33333 proportion 0.5 proportion 0.66667 fixed 720 } }若把preset-column-widths或preset-window-heights配置为空列表merge_with会自动回退到默认档位layout.rs无需担心意外清空。七、焦点指示focus-ring与border焦点环与边框都围绕窗口绘制用于指示活动窗口二者选项几乎相同。关键区别是focus ring只围绕活动窗口绘制不影响窗口尺寸border围绕所有窗口绘制并参与布局——窗口会缩小以给边框腾出空间。[!TIP] 默认情况下焦点环与边框是渲染在窗口背后的一个实心背景矩形因此会透过半透明窗口显示出来因为使用客户端装饰 CSD 的窗口形状可以任意。如果你不喜欢这一点应取消顶层配置中prefer-no-csd的注释niri 会改为在同意省略 CSD的窗口周围绘制焦点环与边框也可以用draw-border-with-backgroundwindow rule 逐窗口覆盖。两者的完整配置骨架layout { // focus-ring 有完全相同的选项。 border { // 取消注释这行以禁用边框。 // off // 边框厚度逻辑像素。 width 4 active-color #ffc87f inactive-color #505050 // 请求你注意的窗口周围的边框颜色。 urgent-color #9b0000 // active-gradient from#ffbb66 to#ffc880 angle45 relative-toworkspace-view // inactive-gradient from#505050 to#808080 angle45 relative-toworkspace-view insrgb-linear } }宽度边框/焦点环的粗细单位逻辑像素。自 0.1.7 起支持小数并按输出 scale 取整到物理像素——width 0.5在scale 2输出上就是 1 物理像素layout { border { width 2 } }源码中宽度的取值范围为FloatOrInt0, 65535appearance.rs。颜色颜色有多种写法CSS 命名颜色redRGB 十六进制#rgb、#rgba、#rrggbb、#rrggbbaaCSS 风格记号rgb(255, 127, 0)、rgba()、hsl()等active-color是活动窗口周围焦点环/边框的颜色inactive-color是其余窗口的颜色。注意焦点环只画在每个显示器上的活动窗口周围因此单显示器时永远看不到它的inactive-color多显示器时才会在其他显示器上看到。还有一套已废弃的语法用四个数字表示 R、G、B、Aactive-color 127 200 255 255。从源码看Color的解码器同时支持单字符串参数与四参数 RGBA两种形式字符串形式走 CSS 颜色解析csscolorparser否则回退到 RGBA 数字appearance.rs。渐变与颜色类似可以设置active-gradient和inactive-gradient它们优先于纯色生效。渐变渲染与 CSSlinear-gradient(angle, from, to)一致angle可选默认180自上而下你可以用任何 CSS linear-gradient 在线工具来调出想要的渐变。layout { focus-ring { active-gradient from#80c8ff to#bbddff angle45 } }渐变默认是相对每个窗口单独着色的设置relative-toworkspace-view后则相对整个工作区视图着色。区别如下layout { border { active-gradient from#ffbb66 to#ffc880 angle45 relative-toworkspace-view inactive-gradient from#505050 to#808080 angle45 relative-toworkspace-view } }自 0.1.8 起还可以用insrgb-linear、inoklch longer hue这样的语法指定渐变的插值色彩空间。支持的空间srgb默认srgb-linearoklaboklch配合shorter hue、longer hue、increasing hue或decreasing hue它们与 CSS 的渲染结果一致例如active-gradient from#f00f to#0f05 angle45 inoklch longer hue等价于 CSS 的linear-gradient(45deg in oklch longer hue, #f00f, #0f05)layout { border { active-gradient from#f00f to#0f05 angle45 inoklch longer hue } }源码层面GradientInterpolation的字符串解析只接受上述四种色彩空间且只有oklch允许后接shorter/longer/increasing/decreasing hue否则会直接报错appearance.rs。默认值方面focus ring 的默认宽度为 4、活动色#7fc8ff、非活动色#505050、紧急色#9b0000border 默认关闭off: true但开启后的默认活动色为#ffc87fappearance.rs。八、窗口阴影shadow自 25.02 起可以为窗口绘制阴影。核心参数与 CSS box-shadow 一一对应on启用阴影默认关闭。softness阴影的柔和程度/尺寸逻辑像素等价于 CSS box-shadow 的 blur radius设为0得到硬阴影。spread把窗口矩形向外扩展的距离逻辑像素等价于 CSS box-shadow spread自 25.05 起可以为负。offset阴影相对窗口的位移逻辑像素如offset x2 y2表示向右下各移 2。draw-behind-window设为true让阴影绘制在窗口背后而非仅在其周围。color阴影颜色与透明度。inactive-color覆盖非活动窗口的阴影颜色默认使用一个更透明的color。// 启用阴影。 layout { shadow { on } } // 同时让窗口省略客户端装饰避免它们再绘制自己的阴影。 prefer-no-csd关于draw-behind-window需要理解它的由来niri 无法得知 CSD 窗口的圆角半径只能假设窗口是方角这会在 CSD 圆角内部产生阴影伪影。draw-behind-window true通过把阴影画到窗口背后修复这些伪影。但更推荐的做法是设置prefer-no-csd和/或geometry-corner-radiuswindow rule这样 niri 能知道圆角半径并正确绘制阴影同时还能去掉窗口自带如果有的话的客户端阴影。阴影绘制会跟随geometry-corner-radius设置的圆角半径。但注意一个限制当前阴影绘制只支持四角半径相同如果geometry-corner-radius给了四个值则阴影只使用第一个左上角的半径。源码中默认值onfalse、offset (0, 5)、softness 30、spread 5、color #00000077不透明度约 47%appearance.rs。九、标签指示器tab-indicator自 25.02 起tab-indicator控制 tabbed 显示模式下列旁边标签指示器的外观off隐藏标签指示器。hide-when-single-tab当 tabbed 列只有一个窗口时隐藏指示器。place-within-column把指示器放进列内部而非外部使其参与列尺寸计算避免压到相邻列。gap指示器与窗口之间的间隙逻辑像素可为负负值会把指示器叠到窗口上。width指示器厚度逻辑像素。length指示器长度。total-proportion属性表示标签整体占窗口长度的比例默认是窗口尺寸的一半即length total-proportion0.5。position指示器相对窗口的位置可取left、right、top、bottom。gaps-between-tabs各标签之间的间隙逻辑像素。为 0 时只有首尾标签带圆角否则所有标签都带。corner-radius标签圆角半径逻辑像素。active-color、inactive-color、urgent-color、active-gradient、inactive-gradient、urgent-gradient与 border / focus ring 的颜色、渐变语义完全相同。标签颜色的选取优先级从上到下来自tab-indicatorwindow rule的颜色若设置来自这里tab-indicatorlayout 选项的颜色若设置两者都没设置时niri 自动取当前生效的窗口边框或焦点环的颜色。// 让指示器更宽并贴合窗口高度同时放到顶部且位于列内。 layout { tab-indicator { width 8 gap 8 length total-proportion1.0 position top place-within-column } }源码默认值为gap 5、width 4、length total_proportion 0.5、position Left、gaps_between_tabs 0、corner_radius 0颜色全部为空由上述优先级自动决定appearance.rs。十、插入位置提示insert-hint自 0.1.10 起insert-hint控制交互式移动窗口时的插入位置提示即拖动窗口到某列之间时显示的高亮条off完全禁用插入提示。color/gradient设置提示颜色语法与 border / focus ring 的颜色和渐变相同。layout { insert-hint { // off color #ffc87f80 gradient from#ffbb6680 to#ffc88080 angle45 relative-toworkspace-view } }默认颜色为#7fc8ff且 alpha 约 50%127, 200, 255, 128appearance.rs与默认 focus ring 的配色保持一致。十一、屏幕边缘收缩strutsStruts 会收缩窗口可占用的区域效果类似 layer-shell 面板——可以把它们理解为一种外间隙单位为逻辑像素left/rightstruts 会让旁边的那一列窗口总是探出一点头方便用滚动或聚焦操作快速访问屏幕外的列top/bottomstruts 则纯粹在 layer-shell 面板与常规 gaps 之外再增加外间隙。layout { struts { left 64 right 64 top 64 bottom 64 } }自 0.1.7 起支持小数同样按 scale 取整到物理像素自 0.1.8 起支持负值——负 struts 会把窗口向外推甚至推出屏幕边缘。最实用的组合是用负 struts 匹配的 gaps模拟内/外间隙例如只要内间隙、不要外间隙layout { gaps 16 struts { left -16 right -16 top -16 bottom -16 } }源码中Struts四个方向的取值范围为FloatOrInt-65535, 65535layout.rs并在 src/layout/scrolling.rs 中通过compute_working_area参与工作区计算——struts 会先于 gaps 被扣除这也是它能作为外间隙存在的原因。十二、按输出与按工作区覆盖自 25.11 起layout {}中的设置可以针对特定输出与命名工作区局部覆盖语法参考 Configuration:-Outputs.md#layout-config-overrides 与 Configuration:-Named-Workspaces.md#layout-config-overrides。这一机制复用了LayoutPart的合并逻辑layout.rs使得同一套全局配置可以按场景微调例如笔记本内屏用大 gaps外接显示器用零 gaps。十三、默认值速查表以下默认值均取自源码Default实现niri-config/src/layout.rs、niri-config/src/appearance.rs配置项默认值gaps16center-focused-columnneveralways-center-single-column关闭empty-workspace-above-first关闭default-column-displaynormalpreset-column-widths1/3、1/2、2/3default-column-widthproportion 0.5preset-window-heights1/3、1/2、2/3focus ring开启width 4active#7fc8ffinactive#505050urgent#9b0000border关闭开启后width 4active#ffc87finactive#505050urgent#9b0000shadow关闭offset (0, 5)、softness 30、spread 5、color #00000077tab-indicator开启gap 5、width 4、length 0.5、position left、无标签间隙、无圆角insert-hint开启color #7fc8ff80struts四方向均为 0background-color灰色[0.25, 0.25, 0.25, 1]十四、实战组合示例把以上要点组合起来一个兼顾精确布局 精致外观的layout {}区块示例layout { // 双列工作流1/2 档快速并排1/3 档给三列场景留余地。 preset-column-widths { proportion 0.5 proportion 0.33333 proportion 0.66667 } default-column-width { proportion 0.5; } // 单列居中多列按需滚动。 always-center-single-column center-focused-column on-overflow // 默认以标签页收纳窗口但单窗口时隐藏指示器。 default-column-display tabbed tab-indicator { hide-when-single-tab place-within-column gap 6 width 5 length total-proportion1.0 position top corner-radius 6 } // 用渐变边框替代默认焦点环并配合无 CSD 获得干净的绘制效果。 focus-ring { off } border { on width 3 active-gradient from#80c8ff to#bbddff angle45 relative-toworkspace-view inactive-color #404040 } // 轻量阴影提升层次感。 shadow { on softness 20 spread 4 offset x0 y4 color #00000050 } // 左右各留出 48 逻辑像素的探出头空间。 struts { left 48 right 48 } } // 让窗口配合无客户端装饰以获得干净的外边框绘制。 prefer-no-csd修改配置后可通过niri msg action reload-config或重启 niri热重载生效若配置解析出错niri 会给出带行列号的诊断信息并保留上一份有效配置。各配置项的具体取值边界如宽度、间隙、圆角的数值范围以本文各小节标注的源码约束为准。【免费下载链接】niriA scrollable-tiling Wayland compositor.项目地址: https://gitcode.com/GitHub_Trending/ni/niri创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询