按键绑定
概述#
按键绑定在配置文件的 binds {} 配置段中声明。
Note
这是少数几个如果省略,不会自动填充默认配置的部分之一,因此请确保从默认配置中复制它。
每个绑定都由一个快捷键和一个用花括号括起来的动作组成。 例如:
快捷键由 + 号分隔的修饰键组成,末尾带一个触发键。
触发键可以是 XKB 按键名称,或Since: next release一个修饰键。
有效的修饰键有:
Ctrl或Control;Shift;Alt;Super或Win;ISO_Level3_Shift或Mod5——在某些布局下这是 AltGr 键;ISO_Level5_Shift:可以与 xkb lv5 选项(如lv5:caps_switch)一起搭配使用;Mod。
Mod 是一个特殊的修饰键,当 niri 在 TTY 中运行时,它等同于 Super;当 niri 作为嵌套的 winit 窗口运行时,它等同于 Alt。
这样的话,您就可以在窗口中测试 niri,而不会与宿主机合成器的按键绑定产生太多冲突。
因此,大部分默认快捷键都使用了 Mod 修饰键。
像 Alt_L 或 Alt_R 这样具体的左或右修饰键可以用作触发键,但不能用作修饰键:
binds {
// 有效:
Ctrl+Alt_L { spawn "alacritty"; }
// 无效:
// Alt_L+Ctrl { spawn "alacritty"; }
// 另外,这等价于只写 Alt_L,
// 因为 Alt_L 已经隐含了 Alt 修饰键:
Alt+Alt_L { spawn "the Alt here is unnecessary but allowed"; }
// 这与下面这行相同:
// Alt_L { spawn "alacritty"; }
}
Since: next release 像 Shift 或 Alt 这样的通用修饰键也可以用作触发键。
仅由通用修饰键组成的绑定不依赖您按下的先后顺序:
binds {
// 先按 Alt 再按 Shift,以及先按 Shift 再按 Alt,都会触发。
Alt+Shift { spawn "alacritty"; }
// 这里的触发键不是通用修饰键,因此
// 您需要最后按下它。只有先按 Ctrl 再按左 Shift 才会生效。
Ctrl+Shift_L { spawn "alacritty"; }
}
Since: 25.05 您可以在配置文件的 input 配置段中自定义 Mod 键。
Tip
要查找特定键的 XKB 名称,您可以使用像 wev 这类程序。
在终端中打开它,然后按下您想要检测的键。 在终端中,您会看到类似这样的输出:
[14: wl_keyboard] key: serial: 757775; time: 44940343; key: 113; state: 1 (pressed)
sym: Left (65361), utf8: ''
[14: wl_keyboard] key: serial: 757776; time: 44940432; key: 113; state: 0 (released)
sym: Left (65361), utf8: ''
[14: wl_keyboard] key: serial: 757777; time: 44940753; key: 114; state: 1 (pressed)
sym: Right (65363), utf8: ''
[14: wl_keyboard] key: serial: 757778; time: 44940846; key: 114; state: 0 (released)
sym: Right (65363), utf8: ''
在这里,请看 sym: Left 和 sym: Right:这些就是按键名称。
在这个例子中,我按下的是左键和右键。
请注意,绑定某个键时,需要写出输入该字符时按住的修饰键。
因此,按住 Shift 输入的符号,其对应的绑定需要带上 Shift 修饰键。
例如,在美式 QWERTY 布局中,< 位于 Shift + , 上,因此要绑定它,您需要写成类似 Mod+Shift+Less 或 Mod+Shift+Comma 的内容(只写 Mod+Less 是不行的)。
再举一个例子,如果您配置了法语服 BÉPO XKB 布局,您的 < 位于 AltGr + « 上。
AltGr 是 ISO_Level3_Shift,或等效的 Mod5,因此要绑定它,您需要写成类似 Mod+Mod5+Less 或 Mod+Mod5+guillemotleft 的内容。
在解析 ASCII(拉丁)键时,niri 会搜索第一个配置了该 ASCII 键的 XKB 布局。 所以举个例子,如果同时配置了美式 Colemak 和俄语 (RU) 布局,那么 ASCII 绑定将使用美式 Colemak 布局来解析。
不过,来自当前布局的按键具有更高的优先级。
例如,如果您同时配置了美式 QWERTY 和俄语布局,并同时绑定了 Mod+Z 和 Mod+Cyrillic_ya,那么在俄语布局下会触发 Mod+Cyrillic_ya 绑定,而在美式布局下会触发 Mod+Z 绑定。
另外,直接指定最终输入字符的绑定,优先级高于指定未按 Shift 时的原始键位。
例如,在美式 QWERTY 布局下,如果两者都配置了,Mod+Shift+At 的优先级高于 Mod+Shift+2。
Since: next release 以往配置快捷键时,必须写出触发键未按下 Shift 时的原始键位。
例如在美式 QWERTY 布局下绑定 < 只能写 Mod+Shift+Comma(因为该键位的原字符是 ,)。
现在已不再受此限制,两种写法均受支持。
Since: 0.1.8 绑定默认会重复(即按住绑定键会使其重复触发)。
您可以使用 repeat=false 为特定绑定禁用此功能:
绑定也可以设置冷却时间,这将限制绑定的触发速率,防止其过快地重复触发。
这主要用于滚动类的绑定。
按下与释放绑定#
Since: next release
您可以设置绑定在按键按下时、按键释放时,或两者都发生时触发。
默认情况下,绑定在按键按下时触发。
您可以使用 press {} 和 release {} 块来改变这一点:
binds {
// 在按下时触发(默认行为)。
Mod+T { spawn "alacritty"; }
// 在释放时触发。
// 单独按下并释放 Mod 键来打开概览。
Mod {
release { toggle-overview; }
}
// 在按下和释放时分别触发不同的动作。
//
// 如果按下动作执行了,那么释放动作必定会执行,
// 无论您以何种方式释放按键。
// 您可以放心地把这种绑定用于对讲(push-to-talk)之类的场景。
Control_R {
press { spawn "notify-send" "Enable push-to-talk"; }
release { spawn "notify-send" "Disable push-to-talk"; }
}
// 只有在中间没有按下其他按键时,释放绑定才会触发。
// 因此,像这样的 Alt+Shift 绑定仍然不会妨碍您
// 在应用程序中使用 Alt+Shift+方向键等快捷键。
Alt+Shift {
release { switch-layout "next"; }
}
}
当您想绑定一个修饰键时,释放绑定尤其有用。 普通的按下绑定实际上会让您无法再拥有任何包含该修饰键的其他绑定。
仅释放绑定只有在按住它期间没有按下其他任何键时才会触发。
如果您有上面示例中的仅释放 Mod 绑定,并在按住 Mod 时按下了其他任意按键或鼠标键,那么该绑定不会触发(概览不会打开)。
在同时具有按下和释放的绑定中,只要按下动作触发了,释放动作就必定会触发。 因此,无论您以何种方式释放按键,您的对讲(push-to-talk)按下-释放绑定都不会卡在按下状态。
默认情况下,任何同时含有按下和释放动作的绑定都不会重复。
如有需要,您可以显式设置 repeat=true:
binds {
// 不会自动重复,
// 因为它含有 release {} 段。
Mod+Shift+Q repeat=true {
press { spawn "notify-send" "Pressed (repeating)"; }
release { spawn "notify-send" "Released"; }
}
}
默认情况下,已被捕获绑定的按键按下与释放事件不会透传给应用程序。
若希望应用程序依然能接收到该按键事件,可设置 pass-through=true:
binds {
// 让应用程序接收到 Alt 键的按下/释放事件。
Alt pass-through=true {
press { spawn "notify-send" "Pressed"; }
release { spawn "notify-send" "Released"; }
}
}
不过,键盘上的“仅释放”绑定默认会将事件透传出去。
若不需要此行为,可在对应绑定上设置 pass-through=false:
binds {
// 不把 Mod 的按下/释放事件透传给应用程序。
//(但它们仍然会收到修饰键状态变化事件。)
Mod pass-through=false {
release { toggle-overview; }
}
}
滚动绑定#
您可以使用以下语法来绑定鼠标滚轮的滚动事件。
这些绑定的方向会根据 natural-scroll 设置而改变。
binds {
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
Mod+WheelScrollRight { focus-column-right; }
Mod+WheelScrollLeft { focus-column-left; }
}
类似地,您可以绑定触摸板滚动“刻度”。 触摸板的滚动是连续的,因此对于这些绑定,它会根据移动的距离分成离散的间隔。
这些绑定也受触摸板的 natural-scroll 影响,因此这些示例绑定是“反向”的,因为 niri 默认为触摸板启用了 natural-scroll。
binds {
Mod+TouchpadScrollDown { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02+"; }
Mod+TouchpadScrollUp { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02-"; }
}
当鼠标滚轮和触摸板滚动绑定的修饰键被按下时,应用程序将无法接收到任何滚动事件。
例如,假设您有一个 Mod+WheelScrollDown 绑定,那么在按住 Mod 时,所有鼠标滚轮滚动都将被 niri 捕获。
Since: next release niri 会按滚动轴分别拦截鼠标滚轮事件。
如果您只绑定了 Mod+WheelScrollDown 并按住了 Mod,niri 只会拦截垂直滚动,而水平滚动依然会正常传递给应用程序。
鼠标点击绑定#
您可以使用以下语法来绑定鼠标点击。
binds {
Mod+MouseLeft { close-window; }
Mod+MouseRight { close-window; }
Mod+MouseMiddle { close-window; }
Mod+MouseForward { close-window; }
Mod+MouseBack { close-window; }
}
鼠标点击操作的是点击的那一刻已获得焦点的窗口,而不是您正在点击的窗口。
请注意,绑定 Mod+MouseLeft 或 Mod+MouseRight 将覆盖相应的手势操作(移动或调整窗口大小)。
数位板笔按钮绑定#
Since: next release
您可以使用以下语法来绑定数位板的笔按钮。
binds {
Mod+TabletStylusButton1 { close-window; }
Mod+TabletStylusButton2 { close-window; }
Mod+TabletStylusButton3 { close-window; }
}
自定义快捷键悬浮窗标题#
快捷键悬浮窗(即重要快捷键对话框)会显示一个硬编码的绑定列表。
您可以使用 hotkey-overlay-title 属性来自定义此列表。
要将一个绑定添加到悬浮窗里,请将该属性设置为您想要显示的标题:
带有自定义标题的快捷键会列在硬编码快捷键之后,以及未自定义的 Spawn 快捷键之前。
要从快捷键悬浮窗中移除硬编码的绑定,请将该属性设置为 null:
Tip
当多个按键组合绑定到同一操作时: - 如果其中任何一个绑定具有自定义的悬浮窗标题,niri 将显示该绑定。 - 否则,如果其中任何一个绑定标题为 null,则 niri 将隐藏该绑定。 - 否则,niri 将显示第一个按键组合。
自定义标题支持 Pango 标记语言:
binds {
Mod+Shift+S hotkey-overlay-title="<b>切换</b> <span foreground='red'>深色</span>/浅色样式" { spawn "some-script.sh"; }
}
动作#
您可以绑定的每个动作,也都可通过 niri msg action 命令以编程方式调用。
运行 niri msg action 可获取一份包含所有动作及其简短描述的完整列表。
以下是一些需要更多解释的动作。
spawn#
启动一个程序。
spawn 接受程序二进制文件的路径作为第一个参数,随后是程序的参数。
例如:
binds {
// 启动 alacritty。
Mod+T { spawn "alacritty"; }
// 启动 `wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.1+`。
XF86AudioRaiseVolume { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1+"; }
}
Tip
Spawn 绑定有一个特殊的 allow-when-locked=true 属性,使其即使在会话锁定时也能工作:
对于 spawn,niri 不会 通过 Shell 来运行命令,这意味着您需要手动分隔参数。
有关使用 Shell 的动作,请参阅下面的 spawn-sh。
binds {
// 正确:每个参数都用独立的引号括起来。
Mod+T { spawn "alacritty" "-e" "/usr/bin/fish"; }
// 错误:这会将整个 `alacritty -e /usr/bin/fish` 字符串解释为二进制文件路径。
Mod+D { spawn "alacritty -e /usr/bin/fish"; }
// 错误:这会将 `-e /usr/bin/fish` 作为单个参数传递,alacritty 将无法理解。
Mod+Q { spawn "alacritty" "-e /usr/bin/fish"; }
}
这也意味着您无法展开环境变量或 ~。
如果需要这类功能,您可以手动通过运行 Shell 来执行命令。
binds {
// 错误:此处没有 shell 展开。这些字符串将按原样传递给程序。
Mod+T { spawn "grim" "-o" "$MAIN_OUTPUT" "~/screenshot.png"; }
// 正确:手动通过 shell 运行此命令,以便它可以展开参数。
// 请注意,整个命令是作为 单个 参数传递的,
// 因为 shell 将根据自己的规则按空格分隔参数。
Mod+D { spawn "sh" "-c" "grim -o $MAIN_OUTPUT ~/screenshot.png"; }
// 您还可以使用 shell 运行多个命令,
// 使用管道、进程替换等。
Mod+Q { spawn "sh" "-c" "notify-send clipboard \"$(wl-paste)\""; }
}
作为一种特殊情况,niri 只会在程序名称的开头将 ~ 扩展到主目录。
spawn-sh#
通过 shell 运行命令。
其参数是一个直接传递给 sh 的字符串。
您可以使用 shell 变量、管道、~ 展开以及所有其他期望的所有功能。
binds {
// 适用于 spawn-sh:所有参数在同一字符串中。
Mod+D { spawn-sh "alacritty -e /usr/bin/fish"; }
// 适用于 spawn-sh:shell 变量($MAIN_OUTPUT)、~ 展开。
Mod+T { spawn-sh "grim -o $MAIN_OUTPUT ~/screenshot.png"; }
// 适用于 spawn-sh:进程替换。
Mod+Q { spawn-sh "notify-send clipboard \"$(wl-paste)\""; }
// 适用于 spawn-sh:多个命令。
Super+Alt+S { spawn-sh "pkill orca || exec orca"; }
}
spawn-sh "some command" 等同于 spawn "sh" "-c" "some command" ——这只是一个更不易令人混淆的简写。
请注意,与直接 spawn 某个二进制文件相比,通过 shell 启动则会产生微小的性能开销。
使用 sh 是硬编码的,这与其他合成器一致。
如果您想要不同的 shell,请使用 spawn 写出来,例如 spawn "fish" "-c" "某个 fish 命令"。
quit#
退出 niri,但会先显示确认对话框以避免意外触发。
如果您想跳过确认对话框,请按如下方式设置参数:
do-screen-transition#
短暂冻结屏幕,然后淡入到新内容。
此动作主要用于从更改系统主题或样式(例如在深色和浅色之间切换)的脚本中触发。 它使诸如窗口逐个更改样式之类的过渡看起来平滑且同步。
例如,使用 GNOME 颜色方案设置:
niri msg action do-screen-transition
dconf write /org/gnome/desktop/interface/color-scheme "\"prefer-dark\""
默认情况下,屏幕会冻结 250 毫秒以给窗口时间重绘,然后进行淡入淡出。 您可以像这样设置此延迟:
或者,在脚本中:
toggle-window-rule-opacity#
切换聚焦窗口的不透明度窗口规则。 只有当窗口的不透明度规则已设置为半透明时,此操作才有效。
screenshot, screenshot-screen, screenshot-window#
用于截取屏幕截图的动作。
screenshot:打开内置的交互式截图界面。screenshot-screen,screenshot-window:分别对聚焦的屏幕或窗口进行截图。
截图会根据 screenshot-path 选项同时存储到剪贴板和保存到磁盘。
Since: 25.02 您可以使用 write-to-disk=false 属性为特定绑定禁用保存到磁盘:
binds {
Ctrl+Print { screenshot-screen write-to-disk=false; }
Alt+Print { screenshot-window write-to-disk=false; }
}
在交互式截图界面中,按下 CtrlC 可以将截图复制到剪贴板,而不写入磁盘。
Since: 25.05 您可以使用 show-pointer=false 属性在截图中隐藏鼠标指针:
binds {
// 指针将默认隐藏
//(您仍然可以按 P 显示它)。
Print { screenshot show-pointer=false; }
// 指针将在截图中隐藏。
Ctrl+Print { screenshot-screen show-pointer=false; }
}
Since: 26.04 您可以通过 show-pointer=true 属性在窗口截图中显示鼠标指针。
仅当窗口当前正在接收指针输入时(通常这意味着指针位于窗口上方)才会包含指针。
toggle-keyboard-shortcuts-inhibit#
一些应用程序,如远程桌面客户端和软件 KVM 切换器,可能会请求 niri 停止处理自身的键盘快捷键,以便它们能够(比如说)将按键按原样转发到远程机器。
toggle-keyboard-shortcuts-inhibit 是一个切换抑制器的逃生舱口。
最好为其绑定一个快捷键,这样有问题的应用程序就无法劫持您的会话。
您还可以使用 allow-inhibiting=false 属性使某些绑定忽略抑制。
它们将始终由 niri 处理,永远不会传递给窗口。
toggle-touchpad#
Since: next release
在运行时开启或关闭触摸板。 这样您无需编辑配置文件,就能快速禁用触摸板。
开关状态会与配置中的 off 设置叠加生效:配置与开关都必须允许使用触摸板,触摸板才会启用。
开关状态在 niri 重启后会重置,并且同样适用于后续新接入(热插拔)的触摸板。