i3
i3 是一款受 wmii 启发,主要面向开发者和高级用户的平铺窗口管理器。
i3 的既定目标包括清晰的文档、完善的多显示器支持、窗口树状结构以及类似 vim 的不同模式。
安装
还有一个 i3 软件包组。它包含了窗口管理器、屏幕锁定程序,以及两个通过 标准输出 (stdout) 向 i3bar 写入状态行的程序。
启动
从 tty
使用 xinit 运行 i3。
显示管理器
i3-wm 包含了 i3.desktop 作为 Xsession 文件来启动窗口管理器。i3-with-shmlog.desktop 则启用了日志记录(有助于调试)。
用法
键盘快捷键
在 i3 中,命令通过修饰键调用,称为 $mod。默认情况下它是 Alt (Mod1),Super (Mod4) 也是一种流行的选择。Super 键通常是键盘上带有 Windows 图标的键,在 Apple 键盘上则是 Command 键。
参见 i3 参考卡 和 使用 i3 获取默认设置。要添加新的快捷键,请参见 键盘绑定。
非 Qwerty 键盘布局的用户可能希望绕过“配置向导”,具体方法见下文。
如果需要在多个窗口管理器或桌面环境之间切换,请考虑使用 sxhkd 或其他与环境无关的程序来管理快捷键。更多信息可在 键盘快捷键#Xorg 中找到。
容器与布局
i3 以树状结构管理窗口,容器是其构建块。这种结构通过水平或垂直分割进行分支。容器默认平铺,但可以设置为标签式或堆叠式布局,也可以设为浮动(例如对话框窗口)。浮动窗口始终位于顶层。
应用程序启动器
i3 使用 dmenu 作为应用程序启动器,默认绑定到 $mod+d。由于它是可选依赖,在使用此功能前必须先安装 dmenu。
i3-wm 包含了 i3-dmenu-desktop,这是 dmenu 的一个 Perl 包装器,它利用 桌面条目 (desktop entries) 创建所有已安装应用程序的列表。或者,也可以使用 j4-dmenu-desktop。
rofi 是一个流行的 dmenu 替代品,它功能更强大且可以列出桌面条目。
在 KDE Plasma/i3 中将 KRunner 作为应用程序启动器
正如 KDE#使用不同的窗口管理器 中所述,可以在 KDE Plasma 下并行运行 i3。
当运行带有 KDEWM=/usr/bin/i3 的 Plasma 时,通过将以下内容添加到 i3 配置文件,可以将 KRunner 设置为 $mod+d 的替代应用程序启动器
~/.config/i3/config
set $menu --no-startup-id qdbus6 org.kde.krunner /App display bindsym $mod+d exec $menu
配置
详见 配置 i3。本文后续内容假设 i3 配置文件位于 ~/.config/ 文件夹中。
配置向导与替代键盘布局
当 i3 第一次启动时,它会提供运行配置向导 i3-config-wizard 的选项。此工具通过重写 /etc/i3/config.keycodes 中的模板配置文件来创建 ~/.config/i3/config。它对默认模板进行了两项修改:
- 要求用户选择默认修饰键,并将其作为一行添加到模板中,例如
set $mod Mod1;以及 - 将所有 bindcode 行替换为对应于用户当前键盘布局的 bindsym 行。
第 2 步旨在确保四个导航快捷键(在 Qwerty 键盘上为 j、k、l 和 ;)映射到位置相同的键位(keysym),例如在 Dvorak 键盘上映射到 h、t、n、s。这种魔法的副作用是多达十五个其他键位可能会被重新映射,从而破坏了助记符,使得 Dvorak 用户发现“重启”被绑定到 $mod1+p 而非 $mod1+r,“水平分割”被绑定到 $mod1+d 而非 $mod1+h,以此类推。
因此,希望拥有直观快捷键(与教程中的绑定相符)的替代键盘布局用户可能更倾向于绕过“配置向导”。这只需通过将 /etc/i3/config 复制到 ~/.config/i3/config(或 ~/.i3/config)并编辑该文件即可实现。
注意,基于键码(keycode)的配置也是可行的,例如对于那些经常在不同键盘布局间切换,但希望 i3 绑定保持不变的用户。
自启动
在 ~/.config/i3/config 文件中添加 exec 命令以在启动时运行命令。例如:
exec terminator
使用 exec_always 命令可以确保该命令在每次重启 i3 时也会被执行。
或者,你可以使用 XDG Autostart 的专用实现。
i3bar
除了显示工作区信息外,i3bar 还可以作为 i3status 或下一节中提到的替代品的输入端。例如:
~/.config/i3/config
bar {
output LVDS1
status_command i3status
position top
mode hide
workspace_buttons yes
tray_output none
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
colors {
background #000000
statusline #ffffff
focused_workspace #ffffff #285577
active_workspace #ffffff #333333
inactive_workspace #888888 #222222
urgent_workspace #ffffff #900000
}
}
详见 配置 i3bar。
i3bar 的替代品
一些用户可能更喜欢传统桌面环境提供的面板。这可以通过在 i3 启动时运行所选的面板应用程序来实现。
例如,若要使用 Xfce 面板 (xfce4-panel),请在 ~/.config/i3/config 的任意位置添加以下行
exec --no-startup-id xfce4-panel --disable-wm-check
可以通过注释掉 ~/.config/i3/config 中的 bar{ } 部分来禁用 i3bar,或者定义一个切换状态栏的快捷键
~/.config/i3/config
# bar toggle, hide or show bindsym $mod+m bar mode toggle
独立于桌面环境的替代品列表如下:
- polybar — 一款快速且易于使用的状态栏创建工具。
- excalibar — 用 C 语言编写的轻量级且可定制的状态栏。
i3status
将默认配置文件复制到主目录中
$ cp /etc/i3status.conf ~/.config/i3status/config
并非所有插件都在默认配置中定义,并且某些配置值对你的系统可能无效,因此需要进行相应更新。详见 i3status(1)。
i3status 的替代品
- bumblebee-status — 基于 Python 的可主题化状态栏生成器。
- goblocks — 用 Go 语言编写的快速、轻量级的 i3status 替代品。
- goi3bar — 用 Go 语言编写的 i3status 替代品。基于配置文件驱动,拥有多个插件、并发选项以及丰富的插件支持。
- i3blocks — 可通过 shell 脚本扩展。支持点击事件、中断以及按块定义刷新间隔。
- i3pystatus — 可扩展的 Python 3 状态栏,默认提供许多插件和配置选项。
- i3status-rust — 用 Rust 编写的高效且功能丰富的替代品。支持推送更新、独立更新间隔、主题设置和点击事件。
- j4status — 用 C 语言编写,通过插件提供状态行,且支持配置。
- ty3status — 用 Typescript 编写的 i3status 替代品。原生支持 javascript 块。
i3status 的包装器
- i3cat — 基于 Go 的包装器,可以将多个外部来源的输入合并。支持点击事件以及将用户指定的信号转发至其子进程。
- py3status — 用 Python 编写的可扩展 i3status 包装器。
- YaGoStatus — 另一个用 Go 语言编写的 i3status 替代品。
状态栏中的图标字体
- otf-font-awesome — 可缩放的矢量图标,可通过 CSS 定制。
- ttf-font-icons — Awesome 和 Ionicons 的混合体,尺寸一致且不重叠。这还避免了 DejaVu Sans 和 Awesome 之间轻微的重叠问题。
- ttf-ionicons — Ionic 框架的高级图标字体。
另请参见 Fonts#Emoji and symbols。
要组合字体,请在配置文件中定义字体回退顺序,并用 , 分隔字体,如下所示
~/.config/i3/config
bar {
...
font pango:DejaVu Sans Mono, Icons 8
...
}
根据 pango 语法,字体大小仅在逗号分隔的字体族列表末尾指定一次。为每个字体设置大小会导致除最后一个字体外的其他设置被忽略。
使用上面链接的速查表中给出的 unicode 编号,将图标添加到 ~/.config/i3status/config 的格式字符串中。输入方法在不同的文本编辑器中会有所不同。例如,要插入“心形”图标(unicode 编号为 f004)
- 在各种图形界面文本编辑器(如 gedit, Leafpad)和终端(如 GNOME Terminal, xfce4-terminal)中:
Ctrl+Shift+u,f004,Enter - 在 Emacs 中:
C-x,8,RET,f004,RET - 在 Vim 中(插入模式下):
Ctrl+v,uf004 - 在 urxvt 中:按住
Ctrl+Shift,输入f004
终端模拟器
默认情况下,按 $mod+Enter 会启动 i3-sensible-terminal,这是一个调用终端的脚本。关于终端调用的顺序,请参见 i3-sensible-terminal(1)。
若要启动指定的终端,请修改 ~/.config/i3/config 中的此行
bindsym $mod+Return exec i3-sensible-terminal
或者,设置 $TERMINAL 环境变量。
禁用标题栏点击
添加 bindsym button1 nop 可以实现在点击窗口标题栏时不选中该窗口。如果你的默认布局是标签式,并且经常误点标题栏而不是应用程序的内容,这会很有用。
技巧与提示
跳转到已打开的窗口
- i3ipc-python — 提供了
/usr/share/doc/python-i3ipc/examples/i3-cycle-focus.py脚本,为 i3 实现了Alt-Tab功能(详情查看该脚本中的注释)。
- quickswitch-i3 — Python 工具,用于在 i3 中快速切换和定位窗口。
- Rofi — 在窗口间切换。
- wmfocus — 对窗口进行对焦和选择。
跳转到紧急窗口
添加到 ~/.config/i3/config:[1]
bindsym $mod+x [urgent=latest] focus
保存与恢复窗口布局
i3-wm 提供了 i3-save-tree 脚本来保存和恢复工作区布局。使用它之前,请安装依赖 perl-anyevent-i3。
保存单个工作区的当前窗口布局
要保存当前窗口布局,请按照以下步骤操作
- 首先,执行各种命令以在首选工作区中打开窗口,并根据需要调整它们的大小。请务必记下为每个窗口执行的命令。
- 现在,在新的工作区中打开终端并运行以下命令
$ i3-save-tree --workspace N > ~/.config/i3/workspace_N.json
其中 N 是首选工作区的编号。这会将工作区 N 的当前布局保存到文件~/.config/i3/workspace_N.json中。 - 新创建的文件需要通过取消注释其中的注释行来进行编辑。这可以通过以下命令自动完成
$ sed -i 's|^\(\s*\)// "|\1"|g; /^\s*\/\//d' ~/.config/i3/workspace_N.json
恢复工作区的窗口布局
恢复工作区布局有两种方式:编写脚本,或者通过编辑 ~/.config/i3/config 自动加载布局。本节仅考虑第一种情况,第二种情况请参考 官方文档。
要恢复上一节中保存的布局,创建一个名为 load_layout.sh 的文件,内容如下
- 起始行
~/load_layout.sh
#!/bin/sh i3-msg "workspace --no-auto-back-and-forth M; append_layout ~/.config/i3/workspace_N.json"
其中 M 是你希望加载先前保存布局的工作区编号,N 是上一节中保存的工作区编号。
- 以及上一节中用于获取首选窗口的命令,但需括在圆括号中,并在最后的圆括号前添加一个“&”号。
例如,如果保存的布局包含三个 uxterm 窗口
~/load_layout.sh
#!/bin/sh # First we append the saved layout of workspace N to workspace M i3-msg "workspace --no-auto-back-and-forth M; append_layout ~/.config/i3/workspace_N.json" # And finally we fill the containers with the programs they had (uxterm &) (uxterm &) (uxterm &)
然后将该文件设置为可执行。最后,可以通过运行以下命令将工作区 N 的布局加载到工作区 M
$ ~/load_layout.sh
bindsym $mod+g exec ~/load_layout.sh 添加到 ~/.config/i3/config 并重启 i3,即可将 Mod+g 绑定为运行上述脚本。~/.config/i3/workspace_N.json 中的 swallows 部分。暂存容器 (Scratchpad)
默认情况下,暂存区 (scratchpads) 只包含单个窗口。然而,也可以将容器制作成暂存区。
创建一个新容器(例如 Mod+Enter),拆分它(Mod+v)并创建另一个容器。聚焦父级(Mod+a),向相反方向拆分(Mod+h),然后再次创建容器。
聚焦第一个容器(根据需要聚焦父级),使窗口变为浮动(Mod+Shift+Space),并将其移动到暂存区(Mod+Shift+-)。现在你可以根据喜好拆分容器了。
另请参见 [2] 关于多个暂存区的内容。
屏幕保护程序与电源管理
通过 Power management#xss-lock,你可以为 i3 会话注册一个屏幕锁定程序。配合 xautolock 使用 -time 选项可以在指定时间后锁定屏幕
xautolock -time 10 -locker "i3lock -i background_image.png" &
可以使用 systemd 服务文件在系统进入睡眠或休眠状态前锁定屏幕。参见 Power management/Suspend and hibernate#Custom systemd units。注意 i3lock 要求服务类型为 forking。
另请参见 DPMS。
另一个选项是结合使用 xidlehookAUR 和 betterlockscreenAUR 或任何其他屏幕保护程序。xidlehook 是一个用 Rust 编写的 xautolock 替代品,但带有一些额外功能。这包括在音频播放或屏幕全屏时禁用锁定的选项。--timer 选项以秒为单位
xidlehook --not-when-audio --not-when-fullscreen --timer 360 "betterlockscreen -l dim" "" &
关机、重启、锁屏
用于关机、重启和锁屏的按键组合可以添加到 ~/.config/i3/config 中。以下示例假设你安装了 polkit,以允许非特权用户执行 电源管理 命令。
set $Locker i3lock && sleep 1
set $mode_system System (l) lock, (e) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown
mode "$mode_system" {
bindsym l exec --no-startup-id $Locker, mode "default"
bindsym e exec --no-startup-id i3-msg exit, mode "default"
bindsym s exec --no-startup-id $Locker && systemctl suspend, mode "default"
bindsym h exec --no-startup-id $Locker && systemctl hibernate, mode "default"
bindsym r exec --no-startup-id systemctl reboot, mode "default"
bindsym Shift+s exec --no-startup-id systemctl poweroff -i, mode "default"
# back to normal: Enter or Escape
bindsym Return mode "default"
bindsym Escape mode "default"
}
bindsym $mod+Pause mode "$mode_system"
完成后,每当你按下 $mod+pause 时,都会出现一个提示。对于更复杂的行为,请使用单独的脚本,并在模式中引用它。[3]
有关屏幕锁定程序的列表,请参见 List of applications/Security#Screen lockers。
终端窗口吞噬 (Swallow)
类似于 dwm,i3 可以让当前的终端窗口被从其启动的新 GUI 窗口所“吞噬”(Swallow)。这可以通过 i3-swallow-gitAUR 软件包实现。
例如,要让 mpv 的窗口吞噬启动它的终端
$ swallow mpv video.mp4
或者,可以通过使用 标签式或堆叠式容器 来模拟终端吞噬,以便在不使用终端窗口时将其隐藏。但其缺点是容器顶部始终会有一个窗口列表。
外接显示器手动管理
得益于 xrandr,有很多种方法可以轻松管理系统显示器。以下示例将其集成到 i3 配置文件中,其行为方式与上述电源管理部分相同。
这里,一台同时拥有 VGA 和 HDMI 输出的笔记本电脑将通过菜单选择来开启/关闭它们
## Manual management of external displays
# Set the shortcuts and what they do
set $mode_display Ext Screen (v) VGA ON, (h) HDMI ON, (x) VGA OFF, (y) HDMI OFF
mode "$mode_display" {
bindsym v exec --no-startup-id xrandr --output VGA1 --auto --right-of LVDS1, mode "default"
bindsym h exec --no-startup-id xrandr --output HDMI1 --auto --right-of LVDS1, mode "default"
bindsym x exec --no-startup-id xrandr --output VGA1 --auto --off, mode "default"
bindsym y exec --no-startup-id xrandr --output HDMI1 --auto --off, mode "default"
# back to normal: Enter or Escape
bindsym Return mode "default"
bindsym Escape mode "default"
}
# Declare here the shortcut to bring the display selection menu
bindsym $mod+x mode "$mode_display"
任何在被关闭的显示器上仍然打开的窗口将自动回到剩余的活动显示器上。
确定设备名称的最简单方法是插入你想使用的设备并运行
$ xrandr --query
这将输出可用、已识别的设备及其系统内的名称,以便相应地设置你的配置文件。
请参考 xrandr 页面或 xrandr(1) 获取完整选项列表,并参考 i3 用户指南 和/或 Reddit 上的 i3 FAQ 获取更多信息。
标签式或堆叠式网页浏览
一些网页浏览器刻意不实现标签页,因为管理标签页被认为是窗口管理器的任务,而不是浏览器的任务。
要让 i3 管理你的无标签页网页浏览器(本例以 uzbl 为例),请将以下行添加到你的 ~/.config/i3/config
for_window [class="Uzbl-core"] focus child, layout stacking, focus
这是堆叠式网页浏览,意味着窗口将垂直显示。相比标签式浏览的优势在于,即使打开了许多浏览器窗口,窗口标题也是完全可见的。
如果你更喜欢标签式浏览(即窗口沿水平方向排列),请使用
for_window [class="Uzbl-core"] focus child, layout tabbed, focus
工作区变量
由于工作区在 i3 中会被多次定义,因此分配工作区变量会很有帮助。例如
set $WS1 term set $WS2 web set $WS3 misc set $WS4 media set $WS5 code
然后用匹配的变量替换工作区名称
bindsym $mod+1 workspace $WS1 ... bindsym $mod+Shift+1 move container to workspace $WS1
详见 更改命名工作区 获取更多信息。
正确处理浮动对话框
虽然对话框默认应以浮动模式打开 [6],但许多对话框仍以平铺模式打开。要更改此行为,请使用 xorg-xprop 检查对话框的 WM_WINDOW_ROLE,并将正确的规则添加到 ~/.i3/config(使用 pcre 语法)
for_window [window_role="About"] floating enable for_window [window_role="Organizer"] floating enable for_window [window_role="Preferences"] floating enable for_window [window_role="bubble"] floating enable for_window [window_role="page-info"] floating enable for_window [window_role="pop-up"] floating enable for_window [window_role="task_dialog"] floating enable for_window [window_role="toolbox"] floating enable for_window [window_role="webconsole"] floating enable for_window [window_type="dialog"] floating enable for_window [window_type="menu"] floating enable
你也可以使用标题规则和正则表达式
for_window [title="Preferences$"] floating enable
或者 WM_CLASS
for_window [class="(?i)mplayer"] floating enable
状态栏显示网络下载/上传速度
你可以使用此上游 脚本。如有必要,请更改 ifaces 变量,将脚本保存在合适的地方(例如 ~/.config/i3/),使其成为可执行文件,并将你的 status_command 指向它。
自动切换水平/垂直窗口分割方向
autotiling 软件包可用于自动切换水平/垂直窗口分割方向,从而产生类似于 bspwm 螺旋平铺的行为。安装后,将以下内容添加到你的 ~/.config/i3/config 并重载 i3。
exec_always --no-startup-id autotiling
故障排除
常规
在许多情况下,开发版本 i3-gitAUR 和 i3status-gitAUR 中已修复了错误,上游开发人员可能会要求用这些版本重现任何错误。[7] 另请参见 Debugging/Getting traces#Compilation options。
i3 消息栏中的按钮无效
i3-nagbar 中的“Edit config”等按钮会调用 i3-sensible-terminal,因此请确保你的 终端模拟器 能被 i3 识别。
平铺终端中错误的换行
i3 v4.3 及更高版本会忽略平铺窗口的尺寸增量提示 [8]。这可能会导致终端过早换行,以及其他问题。作为解决方法,请将受影响的窗口设为浮动,然后再将其恢复为平铺。
鼠标指针保持等待模式
启动不支持启动通知的脚本或应用程序时,鼠标指针会在 60 秒内保持繁忙/观察/时钟模式。
要为特定应用程序解决此问题,请使用 --no-startup-id 参数,例如
exec --no-startup-id ~/script bindsym $mod+d exec --no-startup-id dmenu_run
要全局禁用此动画,请参见 Cursor themes#Create links to missing cursors。
快捷键无响应
某些工具(如 scrot)在常规快捷键绑定(按键按下后执行)下可能无法正常工作。在这些情况下,请使用 --release 参数在按键释放后执行命令 [9]
bindsym --release Print exec --no-startup-id scrot bindsym --release Shift+Print exec --no-startup-id scrot -s
画面撕裂
i3 没有正确实现双重缓冲 [10],因此可能会出现画面撕裂或闪烁。请参见 picom,或 modesetting 驱动程序的 TearFree 选项。
托盘图标不可见
tray_output primary 指令可能要求通过 xrandr 设置一个主输出,明确指定输出或直接删除此指令。[11] 详见 Xrandr。自 i3 4.12 起,由 i3-config-wizard 创建的默认配置不再将此指令添加到配置中。
Spotify 的默认工作区
若要为 Spotify 窗口分配默认工作区,不能使用 assign 的标准路径,而应该使用 for_window 命令,例如
~/.config/i3/config
... for_window [class="Spotify"] move container to workspace $ws10
为确保 for_window 在窗口已经处于 $ws10 时不会移动它,可以使用 move --no-auto-back-and-forth。
参见
- 官方网站
- Funtoo:I3 Tiling Window Manager
- i3 源代码
- i3-extras - 脚本与补丁集合
- i3ipc-glib - i3 扩展库
- i3ipc-ruby - Ruby 语言下 i3 扩展的改进库
- j4tools - 为 i3 设计的非官方工具
- i3, i3status 在线配色配置器(非官方)
Arch Linux 论坛
- i3 讨论帖 - 关于 i3 的常规讨论
- i3 桌面截图与配置分享
屏幕录制