yabai - Mac 的窗口平铺管理软件
窗口平铺管理软件,可以让多个窗口安装自己的配置在桌面平铺展开,且随着单个窗口大小的改变而自适应调整、保证桌面上窗口的平铺效果。
类似的软件还有 Amethyst ,不过相比于 Amethyst,yabai 的上手难度会更高一些,也会更加灵活和可定制化。
希望使用 yabai,总的来说有以下步骤:
- (可选)禁用 Mac 的 SIP
System Integrity Protection
,这会解锁 yabai 更多的功能 - 按照 yabai 并运行
- 配置自己的 yabai
- (可选)用例如 skhd 的软件控制 yabai 的快捷键;或用例如 Übersicht 的软件高亮正在使用的窗口
安装方法
安装并启动 yabai
首先通过 Homebrew 安装 yabai
brew install koekeishiya/formulae/yabai
在安装时,Homebrew 会有如下提示:
To start koekeishiya/formulae/yabai now and restart at login:
brew services start koekeishiya/formulae/yabai
Or, if you don't want/need a background service you can just run:
yabai
这里告诉我们两种启动 yabai 的方式,一种是让其一直在后台运行,一种是临时启动。
如果我们已经禁用了 Mac 的 SIP System Integrity Protection
,则可以在启动前先输入以下命令,可以启用更多 yabai 的功能;但也会让系统变得相对不安全:
# install the scripting addition
sudo yabai --install-sa
# if macOS Big Sur or Monterey, load the scripting addition manually; follow instructions below to automate on startup
sudo yabai --load-sa
这里我没有选择关闭 SIP,没有启用上面的功能。
我们希望 yabai 能总是在后台运行,因此我们输入 brew services start koekeishiya/formulae/yabai
。之后会提示 yabai 需要对应的权限,允许即可。
启动后你会发现没有任何不同,这是因为 yabai 需要我们有对应的 .yabairc
配置文件才会生效,默认是没有这个文件的,也就是 yabai 不会做任何处理。我们会在后面的「配置」部分讲到相关的内容。
卸载 yabai
如果希望卸载 yabai,则输入以下命令:
# stop yabai
brew services stop yabai
# uninstall the scripting addition
sudo yabai --uninstall-sa # 如果之前有启用才需要
# uninstall yabai
brew uninstall yabai
# these are logfiles that may be created when running yabai using brew services.
# path may differ if a custom brew prefix has been selected.
rm -rf /usr/local/var/log/yabai
# remove config and various temporary files
rm ~/.yabairc
rm /tmp/yabai_$USER.lock
rm /tmp/yabai_$USER.socket
rm /tmp/yabai-sa_$USER.socket
# unload the scripting addition by forcing a restart of Dock.app
killall Dock
配置 yabai
前面提到 yabai 刚启动时是没有任何不同的,这是因为我们没有对应的配置文件 .yabairc
,我们需要在 HOME 目录下生成 .yabairc
并增加可执行权限,然后通过 brew services restart yabai
重新启动 yabai 即可让配置文件生效。
yabai 配置比较简单,可以用 man yabai
和 项目中附带的 example 对照着看,可以先拷贝成自己的 ~/.yabairc
感受一下。文章末尾我也会贴上自己当前使用的配置。
配置 skhd
yabai 配置完成启动后便自动生效,往往我们希望通过快捷键来控制对应需要的行为。
例如,如果没有快捷键,yabai 中将窗口全屏,需要输入下面的终端指令:
yabai -m window --toggle zoom-fullscreen
通过如 skhd
这类软件,我们通过如下配置,就可以将 ctrl + alt - enter
和对应指令绑定了:
ctrl + alt - enter : yabai -m window --toggle zoom-fullscreen
首先安装 jq
和 koekeishiya/formulae/skhd
brew install jq
brew install koekeishiya/formulae/skhd
jq
是一个 json 的 cli 工具,用于在终端对 json 进行处理。通过它我们可以方便地进行一些 yabai 的相关配置,例如当前我使用的「快速关闭当前窗口」:
## Close active application (快速关闭窗口)
ctrl + alt - backspace : $(yabai -m window $(yabai -m query --windows --window | jq -re ".id") --close)
当然,我们也可以用其他的键盘映射工具来配置快捷键,例如 Karabiner;不过个人感觉他们对于命令行的配置没有 skhd 那样简洁直观。
同样的,和 yabai 一样,skhd 需要有 ~/.skhd
才生效,也可以看看 yabai 项目中附带的 example 学习一下。
需要额外说一下的是,运行 skhd 时会要求 Accessibility
权限,这里我们需要注意,终端软件也是需要一起开启对应权限的,否则不生效:
另外再分享两个 skhd 初配置时可能有用的东西:
- 如果
.skhdrc
有部分配置存在无法运行,那么整个.skhdrc
都不会生效- 我们可以先手动停止 skhd(
brew services stop skhd
),然后在终端运行skhd -V
或者skhd --verbose
,这会加载.skhdrc
并输出对应 debug 信息。 - 如果有不正确或者无法运行的,skhd 便会输出并提示(如下图)
- 我们可以先手动停止 skhd(
- skhd 配置时,有些键位我们不知道如何表示
- 可以在终端运行
skhd --observe
查看键盘上对应按键在 skhd 中对应的编码,例如下面用0x24
表示回车
- 可以在终端运行
## full screen / un-full screen(切换窗口全屏) 0x24 表示回车
ctrl + alt - 0x24 : yabai -m window --toggle zoom-fullscreen
.yabairc 和 .skhdrc
当前还没整到 GitHub 上,最后就在文章末尾贴一下我自己当前使用的 .yabairc
和 .skhdrc
,仅供各位参考。
.yabairc
#!/usr/bin/env sh
# 如果没有关闭 Mac 的 SIP,那么在 BigSur 及以上的系统中,更改配置文件后,需要手动加载过配置文件
# - https://github.com/koekeishiya/yabai/wiki/Installing-yabai-(latest-release)
# 如果已经关闭 Mac 的 SIP,那么通过下面命令就可以让 yabai 的配置文件热更新了
# sudo yabai --load-sa
# 也可以在该配置文件中增加这句,这样每次重启系统时不用自己输入
# yabai -m signal --add event=dock_did_restart action="sudo yabai --load-sa"
# ------------------------------------------------------------------------------------- #
# ------------------------------global settings---------------------------------------- #
# ------------------------------------------------------------------------------------- #
# 在多显示器情况下,新建的窗口默认在**哪个显示器**出现
# - default: 在创建窗口的显示器出现(mac 的默认行为)
# - focused: 在当前聚焦的显示器出现
# - cursor: 在鼠标指针所在的显示器出现
yabai -m config window_origin_display default
# 当前屏幕下,新窗口的出现在**屏幕的哪个位置**
# - first_child: (父节点模式)如果当前是 vertical split,则出现在*左侧*;如果是 horizontal split,则出现在*上方*
# - second_child: (子节点模式)如果当前是 vertical split,则出现在*右侧*;如果是 horizontal split,则出现在*下方*
yabai -m config window_placement second_child
# 浮动窗口是否置顶
yabai -m config window_topmost on
# 窗口阴影值
# - on: 总是展示
# - off: 总是关闭
# - float: 只有浮动窗口展示
yabai -m config window_shadow on
# 窗口不透明
# - on: 总是展示
# - off: 总是关闭
yabai -m config window_opacity off
# *激活*窗口的不透明度(仅当 window_opacity on 时才有效)
yabai -m config active_window_opacity 1.0
# *普通*窗口不透明度(仅当 window_opacity on 时才有效)
yabai -m config normal_window_opacity 0.90
# 激活窗口和普通窗口切换时,*不透明度的过渡时间*(仅当 window_opacity on 时才有效)
yabai -m config window_opacity_duration 0.0
# 窗口边框
# - on: 总是展示
# - off: 总是关闭
yabai -m config window_border off
# 窗口*边框宽度*(单位 px)
yabai -m config window_border_width 6
# 激活窗口的边框颜色
yabai -m config active_window_border_color 0xff775759
# 普通窗口的边框颜色
yabai -m config normal_window_border_color 0xff555555
yabai -m config insert_feedback_color 0xffd75f5f
# 所有窗口都使用相同比例的空间
# - on: 总是开启
# - off: 总是关闭
yabai -m config auto_balance off
# 分屏后*旧:新*窗口的比例(仅当 auto_balance off 时有效)
yabai -m config split_ratio 0.50
# ==================================================== #
# ====================鼠标相关======================== #
# ==================================================== #
# 窗口切换时,鼠标自动移动到当前使用窗口的中心
# - on: 总是开启
# - off: 总是关闭
yabai -m config mouse_follows_focus off
# 是否自动聚焦到鼠标所在窗口
# - off: 总是关闭
# - autoraise:
# - autofocus:
yabai -m config focus_follows_mouse off
# 按住对应修饰键时,yabai 不自动调整平铺(默认情况下调整窗口大小时,yabai 会自适应调整平铺);配置时通常会关闭 focus_follows_mouse
# - cmd
# - alt
# - shift
# - ctrl
# - fn
yabai -m config mouse_modifier fn
# modifier + 左键的行为
# - move
# - resize
yabai -m config mouse_action1 move
# modifier + 右键的行为
# - move
# - resize
yabai -m config mouse_action2 resize
# 在平铺管理情况下,拖动一个窗口到另一窗口位置时的操作
# - swap: 交换窗口位置
# - stack: 堆叠在旧窗口上
yabai -m config mouse_drop_action swap
# ------------------------------------------------------------------------------------- #
# ---------------------------general space settings------------------------------------ #
# ------------------------------------------------------------------------------------- #
# yabai 布局模式
# - bsp: 平铺
# - stack: 堆叠
# - float: 浮动
yabai -m config layout bsp
# 窗口和屏幕边缘的距离(优先级低于 gap)
yabai -m config top_padding 08
yabai -m config bottom_padding 08
yabai -m config left_padding 08
yabai -m config right_padding 08
# 窗口与窗口之间的间距(优先级高于 padding)
yabai -m config window_gap 05
# ------------------------------------------------------------------------------------- #
# ---------------------------------specific apps--------------------------------------- #
# ------------------------------------------------------------------------------------- #
# manage: 是否使用 yabai 管理
# - on
# - off
# sticky: 是否总是置顶
# - on
# - off
# layer:
# - below
# - normal
# - above
yabai -m rule --add app="^System Preferences$" manage=off
yabai -m rule --add app="^System Information$" sticky=on layer=above manage=off
yabai -m rule --add app="^Activity Monitor$" sticky=on layer=above manage=off
yabai -m rule --add app="^Finder$" sticky=on layer=above manage=off
yabai -m rule --add app="^Alfred Preferences$" sticky=on layer=above manage=off
yabai -m rule --add app="^飞书$" sticky=on layer=above manage=off
yabai -m rule --add app="^Feishu$" sticky=on layer=above manage=off
yabai -m rule --add app="^Lark$" sticky=on layer=above manage=off
yabai -m rule --add app="^Lark Meetings$" sticky=on layer=above manage=off
yabai -m rule --add app="^Seal$" sticky=on layer=above manage=off
yabai -m rule --add app="^AppCleaner$" sticky=off layer=above manage=off
yabai -m rule --add app="^Karabiner-Elements$" sticky=on layer=above manage=off
yabai -m rule --add app="^Karabiner-EventViewer$" sticky=on layer=above manage=off
yabai -m rule --add app="^Things$" manage=off
yabai -m rule --add app="^Spotify$" manage=off
yabai -m rule --add app="^Bartender 4$" manage=off
yabai -m rule --add app="^BetterTouchTool$" manage=off
yabai -m rule --add app="^Magnet$" manage=off
yabai -m rule --add app="^WeChat$" manage=off
yabai -m rule --add app="^微信$" manage=off
echo "yabai configuration loaded.."
.skhdrc
,一些脚本就没贴上了,感兴趣的可以评论留言或者 GitHub 上翻翻看其他人的配置:
#SKHD STUFF
# if you're having troubles finding key codes for a key just type skhd --observe in a terminal and type a key. Pretty cool! Or just check the wiki.
## HYPER == SHIFT + CMD + ALT + OPTION
### ============================================================================ ###
### My Settings ###
### ============================================================================ ###
## Close active application (快速关闭窗口)
ctrl + alt - backspace : $(yabai -m window $(yabai -m query --windows --window | jq -re ".id") --close)
## Equalize size of windows (平铺当前界面所有窗口)
ctrl + alt - 0 : yabai -m space --balance
## focus window (切换窗口焦点)
ctrl + alt - k : sh ~/.config/dotfiles/yabai/script/focus_window.sh up
ctrl + alt - j : sh ~/.config/dotfiles/yabai/script/focus_window.sh down
ctrl + alt - h : sh ~/.config/dotfiles/yabai/script/focus_window.sh left
ctrl + alt - l : sh ~/.config/dotfiles/yabai/script/focus_window.sh right
## swap window & move window in floating mode (移动窗口)
shift + alt - k : yabai -m window --swap north
shift + alt - j : yabai -m window --swap south
shift + alt - h : yabai -m window --swap west
shift + alt - l : yabai -m window --swap east
## Rotate windows clockwise and anticlockwise (旋转窗口)
ctrl + alt - e : yabai -m space --rotate 90
ctrl + alt - r : yabai -m space --rotate 270
## float / Unfloat window (切换窗口浮动)
ctrl + alt - space : yabai -m window --toggle float ; yabai -m window --grid 12:12:1:1:9:9
## full screen / un-full screen(切换窗口全屏) 0x24 表示回车
ctrl + alt - 0x24 : yabai -m window --toggle zoom-fullscreen
## window resize
ctrl + shift + alt - k : yabai -m window --resize top:0:-20 || yabai -m window --resize bottom:0:-20
ctrl + shift + alt - j : yabai -m window --resize top:0:20 || yabai -m window --resize bottom:0:20
ctrl + shift + alt - h : yabai -m window --resize left:-20:0 || yabai -m window --resize right:-20:0
ctrl + shift + alt - l : yabai -m window --resize right:20:0 || yabai -m window --resize left:20:0
## send window to next monitor and follow focus (将窗口发送到另一个显示器)
ctrl + alt - left : sh ~/.config/dotfiles/yabai/script/move_window_to_left.sh display
ctrl + alt - right : sh ~/.config/dotfiles/yabai/script/move_window_to_right.sh display
## create desktop, move window and follow focus - uses jq for parsing json (brew install jq)
shift + alt - n : yabai -m space --create && \
index="$(yabai -m query --spaces --display | jq 'map(select(."native-fullscreen" == 0))[-1].index')" && \
yabai -m space --focus "${index}"