Took your mac to the next level with yabai and skhd !

Introduction

In this article I will comeback on a recent experience I had with my macos. I was thinking if I could get any faster with the switch between spaces (desktop), and can it be configurable easily with hotkey ?

Introduce to you yabai ! A window management utility for macos, and with the combinaison with skhd to be able to configure hotkey, your experience will be way faster.

The result

0:00
/0:14

The goal here is to never use the mouse to switch from different spaces. We will now see how to install and configure yabai.

Installation yabai

First you will need to install yabai via:

brew install koekeishiya/formulae/yabai

Then start the service:

yabai --start-service

This will prompt the user to allow yabai accessibility permissions. Check the box next to yabai to allow accessibility permissions.

Then use again:

yabai --start-service

yabai need root level to perform operation on the Dock.app you will need to add some config in the file /etc/sudoers :

sudo vim /etc/sudoers

Add this at the end of the file:

sudo visudo -f /private/etc/sudoers.d/yabai

# input the line below into the file you are editing.
#  replace <yabai> with the path to the yabai binary (output of: which yabai).
#  replace <user> with your username (output of: whoami). 
#  replace <hash> with the sha256 hash of the yabai binary (output of: shasum -a 256 $(which yabai)).
#   this hash must be updated manually after upgrading yabai.

<user> ALL=(root) NOPASSWD: sha256:<hash> <yabai> --load-sa

/etc/sudoers

Don't forget to replace <user>, <hash> and <yabai> via all the command above.

For more details about the yabai installation take a look of the wiki page.

Subscribe to Etienne Théodore

Don’t miss out on the latest articles. Only one email by week about Flutter/Dart (no-spam)
your@email.com
Subscribe

The configuration of yabai

We will now create the configuration of yabai, all the config is in this file ~/.config/yabai/yabairc.

Create this file and put this into:

# for this to work you must configure sudo such that
# it will be able to run the command without password

yabai -m signal --add event=dock_did_restart action="sudo yabai --load-sa"
sudo yabai --load-sa

# default layout (can be bsp, stack or float)
yabai -m config layout bsp

# new window spawns to the right if vertical split, or bottom if horizontal split
yabai -m config window_placement second_child

# padding set to 12px
# yabai -m config top_padding 12
# yabai -m config bottom_padding 12
# yabai -m config left_padding 12
# yabai -m config right_padding 12
# yabai -m config window_gap 12

# -- mouse settings --

# center mouse on window with focus
yabai -m config mouse_follows_focus on

# modifier for clicking and dragging with mouse
yabai -m config mouse_modifier alt
# set modifier + left-click drag to move window
yabai -m config mouse_action1 move
# set modifier + right-click drag to resize window
yabai -m config mouse_action2 resize

# when window is dropped in center of another window, swap them (on edges it will split it)
yabai -m mouse_drop_action swap


# disable specific apps
yabai -m rule --add app="^System Settings$" manage=off
yabai -m rule --add app="^Calculator$" manage=off
yabai -m rule --add app="^Karabiner-Elements$" manage=off
yabai -m rule --add app="^QuickTime Player$" manage=off

~/.config/yabai/yabairc

Like we can see I comment some line like adding padding between window etc... feel free to uncomment and custom your experience.

Now we have seen the installation and configuration of yabai, let's use skhd to configure all hot key to perform some operation on yabai.

Installation of skdh

  brew install koekeishiya/formulae/skhd
  skhd --start-service

You be prompt to accept some privacy setting then re-start skhd.

skhd need to be configurate to work properly. If you want more detail about it take a look of the github of skhd

The configuration of skhd

Like yabai you will need to create a file named:

$HOME/.config/skhd/skhdrc

Then put this into:

# -- Changing Window Focus --

# change window focus within space
alt - j : yabai -m window --focus south
alt - k : yabai -m window --focus north
alt - h : yabai -m window --focus west
alt - l : yabai -m window --focus east

#change focus between external displays (left and right)
alt - s: yabai -m display --focus west
alt - g: yabai -m display --focus east

# -- Modifying the Layout --

# rotate layout clockwise
shift + alt - r : yabai -m space --rotate 270

# flip along y-axis
shift + alt - y : yabai -m space --mirror y-axis

# flip along x-axis
shift + alt - x : yabai -m space --mirror x-axis

# toggle window float
shift + alt - t : yabai -m window --toggle float --grid 4:4:1:1:2:2


# -- Modifying Window Size --

# maximize a window
shift + alt - m : yabai -m window --toggle zoom-fullscreen

# balance out tree of windows (resize to occupy same area)
shift + alt - e : yabai -m space --balance

# -- Moving Windows Around --

# swap windows
shift + alt - j : yabai -m window --swap south
shift + alt - k : yabai -m window --swap north
shift + alt - h : yabai -m window --swap west
shift + alt - l : yabai -m window --swap east

# move window and split
ctrl + alt - j : yabai -m window --warp south
ctrl + alt - k : yabai -m window --warp north
ctrl + alt - h : yabai -m window --warp west
ctrl + alt - l : yabai -m window --warp east

# move window to display left and right
shift + alt - s : yabai -m window --display west; yabai -m display --focus west;
shift + alt - g : yabai -m window --display east; yabai -m display --focus east;


# move window to prev and next space
shift + alt - p : yabai -m window --space prev;
shift + alt - n : yabai -m window --space next;

# move window to space #
shift + alt - 1 : yabai -m window --space 1;
shift + alt - 2 : yabai -m window --space 2;
shift + alt - 3 : yabai -m window --space 3;
shift + alt - 4 : yabai -m window --space 4;
shift + alt - 5 : yabai -m window --space 5;
shift + alt - 6 : yabai -m window --space 6;
shift + alt - 7 : yabai -m window --space 7;

# -- Starting/Stopping/Restarting Yabai --

# stop/start/restart yabai
ctrl + alt - q : brew services stop yabai
ctrl + alt - s : brew services start yabai
ctrl + alt - r : brew services restart yabai

# -- Switch between spaces even if full screen
ctrl - 1 : index=1; eval "$(yabai -m query --spaces | jq --argjson index "${index}" -r '(.[] | select(.index == $index).windows[0]) as $wid | if $wid then "yabai -m window --focus \"" + ($wid | tostring) + "\"" else "skhd --key \"ctrl - " + (map(select(."is-native-fullscreen" == false)) | index(map(select(.index == $index))) + 1 % 10 | tostring) + "\"" end')"
ctrl - 2 : index=2; eval "$(yabai -m query --spaces | jq --argjson index "${index}" -r '(.[] | select(.index == $index).windows[0]) as $wid | if $wid then "yabai -m window --focus \"" + ($wid | tostring) + "\"" else "skhd --key \"ctrl - " + (map(select(."is-native-fullscreen" == false)) | index(map(select(.index == $index))) + 1 % 10 | tostring) + "\"" end')"
ctrl - 3 : index=3; eval "$(yabai -m query --spaces | jq --argjson index "${index}" -r '(.[] | select(.index == $index).windows[0]) as $wid | if $wid then "yabai -m window --focus \"" + ($wid | tostring) + "\"" else "skhd --key \"ctrl - " + (map(select(."is-native-fullscreen" == false)) | index(map(select(.index == $index))) + 1 % 10 | tostring) + "\"" end')"
ctrl - 4 : index=4; eval "$(yabai -m query --spaces | jq --argjson index "${index}" -r '(.[] | select(.index == $index).windows[0]) as $wid | if $wid then "yabai -m window --focus \"" + ($wid | tostring) + "\"" else "skhd --key \"ctrl - " + (map(select(."is-native-fullscreen" == false)) | index(map(select(.index == $index))) + 1 % 10 | tostring) + "\"" end')"
ctrl - 5 : index=5; eval "$(yabai -m query --spaces | jq --argjson index "${index}" -r '(.[] | select(.index == $index).windows[0]) as $wid | if $wid then "yabai -m window --focus \"" + ($wid | tostring) + "\"" else "skhd --key \"ctrl - " + (map(select(."is-native-fullscreen" == false)) | index(map(select(.index == $index))) + 1 % 10 | tostring) + "\"" end')"
c

$HOME/.config/skhd/skhdrc

Like you can see in the file, you can custom your own hotkey. For example something I like to use is shift + alt - m to maximize the current windows. Take your time to see what you can do and feel free to change any hotkey.

For switching between space I use ctrl - 1 to go to the first space etc... That allow me to change between my different workspace really fast.

Conclusion

You will never use your trackpad or any mouse or alt+tab anymore to find your apps. Organise your space one time then switch fast between them. With the combinaison of neovim you will never quit your keyboard ! Thanks for reading this article, feel free to follow me on X for more tips/article during my dev journey.

Subscribe to Etienne Théodore

Don’t miss out on the latest articles. Only one email by week about Flutter/Dart (no-spam)
your@email.com
Subscribe

Subscribe to Etienne Théodore

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe