├── LICENSE.txt ├── yabairc ├── README.md ├── yabai3 └── skhdrc /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2023 Sebastian Stammler 4 | 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the “Software”), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /yabairc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # the scripting-addition must be loaded manually if 4 | # you are running yabai on macOS Big Sur. Uncomment 5 | # the following line to have the injection performed 6 | # when the config is executed during startup. 7 | # 8 | # for this to work you must configure sudo such that 9 | # it will be able to run the command without password 10 | # 11 | # see this wiki page for information: 12 | # - https://github.com/koekeishiya/yabai/wiki/Installing-yabai-(latest-release) 13 | # 14 | # sudo yabai --load-sa 15 | # yabai -m signal --add event=dock_did_restart action="sudo yabai --load-sa" 16 | 17 | #!/usr/bin/env sh 18 | 19 | # bar settings 20 | yabai -m config top_padding 0 21 | 22 | # global settings 23 | yabai -m config mouse_follows_focus off 24 | yabai -m config focus_follows_mouse autofocus 25 | 26 | yabai -m config window_placement second_child 27 | yabai -m config window_topmost on 28 | 29 | yabai -m config window_opacity off 30 | yabai -m config window_opacity_duration 0.0 31 | yabai -m config window_shadow on 32 | 33 | yabai -m config active_window_opacity 1.0 34 | yabai -m config normal_window_opacity 0.90 35 | yabai -m config split_ratio 0.50 36 | yabai -m config auto_balance off 37 | 38 | # Mouse support 39 | yabai -m config mouse_modifier alt 40 | yabai -m config mouse_action1 move 41 | yabai -m config mouse_action2 resize 42 | 43 | # general space settings 44 | yabai -m config layout bsp 45 | yabai -m config top_padding 3 46 | yabai -m config bottom_padding 3 47 | yabai -m config left_padding 3 48 | yabai -m config right_padding 3 49 | yabai -m config window_gap 5 50 | 51 | # Unmanaged windows 52 | yabai -m rule --add app='^System Information$' manage=off 53 | yabai -m rule --add app='^System Settings$' manage=off 54 | yabai -m rule --add title='Preferences$' manage=off 55 | yabai -m rule --add title='Settings$' manage=off 56 | yabai -m rule --add title='Calculator$' manage=off 57 | yabai -m rule --add app='Raycast' manage=off 58 | 59 | echo "yabai configuration loaded." 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # yabai3 2 | 3 | **yabai3** is an [i3](https://github.com/i3/i3) sanity wrapper around [yabai](https://github.com/koekeishiya/yabai). 4 | It's a simple `zsh` script. 5 | 6 | ## Features 7 | 8 | **yabai3** provides a few commands that imitate the way i3 behaves under the same action, but uses `yabai` to accomplish the intended effects. 9 | In the following list of available commands, `` refers to any yabai direction `(north|west|east|south)`. 10 | 11 | * `yabai3 focus ` -- move focus to window or screen in the given direction. It also cycles through stacks. 12 | * `yabai3 move ` -- move focused window in the given direction. 13 | It enters and leaves stacks, and also moves to adjacent displays. 14 | * `yabai3 layout-toggle` -- toggle between `stack` and `bsp` display layout. 15 | * `yabai3 resize (shrink|grow) (width|height) ` -- shrink/grow the width/height of the focused window by `` pixels. 16 | * `yabai3 stack-(enter|leave) ` -- enter/leave a stack in the given direction with the focused window. 17 | These are also used internally in the `move` command, and can be used themselves for more specific stack management. 18 | 19 | Most other i3 actions can be imitated close enough with existing `yabai` commands, so they aren't part of `yabai3` (yet). 20 | The example `skhd` configuration below also uses plain `yabai` in these cases. 21 | Note that **yabai3** is still young and work in progress, so more commands might be added in the future. 22 | 23 | ## Usage 24 | 25 | Create hotkey bindings just as you would for `yabai` itself, e.g. using [skhd](https://github.com/koekeishiya/skhd). 26 | 27 | Opinionated and ready to use configuration examples for **yabai** and **skhd** that work with **yabai3** can be found in files [`yabairc`](./yabairc) and [`skhdrc`](./skhdrc). 28 | They assume that the [`yabai3`](./yabai3) script is accessible somewhere on your `$PATH`. 29 | You can replace `yabai3` invocations with an absolute path to the script if it's not. 30 | 31 | They also assume that the alias 32 | ```sh 33 | alias alacritty-new='alacritty msg create-window; open -a Alacritty' 34 | 35 | ``` 36 | is available to spawn a new [alacritty](https://github.com/alacritty/alacritty) window. 37 | This alias ensures that a single alacritty app instances is reused for new windows and that any new window gets focused after creation. 38 | Change it to your terminal of choice if you don't use alacritty. 39 | -------------------------------------------------------------------------------- /yabai3: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | typeset -A stack_dir=( 4 | "south" "stack.next" 5 | "north" "stack.prev" 6 | ) 7 | 8 | typeset -A stack_wrap=( 9 | "south" "stack.first" 10 | "north" "stack.last" 11 | ) 12 | 13 | typeset -A opposite=( 14 | "east" "west" 15 | "west" "east" 16 | "north" "south" 17 | "south" "north" 18 | ) 19 | 20 | alias yqww='yabai -m query --windows --window' 21 | alias ytf2='yabai -m window --toggle float && yabai -m window --toggle float' 22 | 23 | err() { 24 | echo "yabai3: $1"; exit 1 25 | } 26 | 27 | sidx() { 28 | echo $(yqww $@ | jq '."stack-index"') 29 | } 30 | 31 | focus() { 32 | local dir=$1 33 | 34 | case $dir in 35 | west|east) 36 | yabai -m window --focus $dir || \ 37 | yabai -m display --focus $dir 38 | ;; 39 | north|south) 40 | yabai -m window --focus $stack_dir[$dir] || \ 41 | yabai -m window --focus $dir || \ 42 | yabai -m window --focus $stack_wrap[$dir] 43 | ;; 44 | *) 45 | err "focus: unknown direction ${dir}" 46 | esac 47 | } 48 | 49 | layout-toggle() { 50 | yabai -m space --layout $(yabai -m query --spaces --space | jq -r 'if .type == "bsp" then "stack" else "bsp" end') 51 | } 52 | 53 | stack-leave() { 54 | yabai -m window --insert $1 && ytf2 55 | } 56 | 57 | stack-enter() { 58 | yabai -m window $1 --stack $opposite[$1] 59 | } 60 | 61 | move() { 62 | local dir=$1 63 | 64 | if [[ $(sidx) -gt 0 ]]; then 65 | # if in stack, north/south directions should move within until hitting border 66 | if [[ $dir == (#s)(south|north) ]]; then 67 | yabai -m window --swap $stack_dir[$dir] && return 68 | fi 69 | # otherwise, leave 70 | stack-leave $dir 71 | elif [[ $(sidx $dir) -gt 0 ]]; then 72 | # if there's a stack, enter 73 | stack-enter $dir 74 | else 75 | # otherwise, swap or move to next display 76 | yabai -m window --swap $dir || \ 77 | (yabai -m window --display $dir && yabai -m display --focus $dir) 78 | fi 79 | } 80 | 81 | resize() { 82 | (( $3 )) || err "resize: scale factor not a number: $3" 83 | 84 | case $1 in 85 | shrink) local s=-1 ;; 86 | grow) local s=1 ;; 87 | *) err "resize: unknown scale: $1" ;; 88 | esac 89 | 90 | local r=$(( $s * $3 )) 91 | 92 | case $2 in 93 | width) 94 | yabai -m window --resize right:$r:0 || \ 95 | yabai -m window --resize left:$((-($r))):0 96 | ;; 97 | height) 98 | yabai -m window --resize bottom:0:$r || \ 99 | yabai -m window --resize top:0:$((-($r))) 100 | ;; 101 | *) 102 | err "resize: unknown orientation: $2" 103 | ;; 104 | esac 105 | } 106 | 107 | # main 108 | case $1 in 109 | focus) 110 | focus $2 111 | ;; 112 | move) 113 | move $2 114 | ;; 115 | stack-leave) 116 | stack-leave $2 117 | ;; 118 | stack-enter) 119 | stack-enter $2 120 | ;; 121 | layout-toggle) 122 | layout-toggle 123 | ;; 124 | resize) 125 | resize $2 $3 $4 126 | ;; 127 | *) 128 | err "unknown command: $1" 129 | ;; 130 | esac 131 | -------------------------------------------------------------------------------- /skhdrc: -------------------------------------------------------------------------------- 1 | # restart yabai 2 | alt + shift - r : yabai --restart-service 3 | 4 | # close focused window 5 | alt - w : yabai -m window --close 6 | 7 | # balance windows - 0x18 = equal 8 | alt - 0x18 : yabai -m space --balance 9 | 10 | # toggle window fullscreen 11 | alt - f : yabai -m window --toggle zoom-fullscreen 12 | 13 | # toggle window native fullscreen 14 | alt + shift - f : yabai -m window --toggle native-fullscreen 15 | 16 | # toggle v/h split 17 | alt - e : yabai -m window --toggle split 18 | 19 | # floating windows - 0x2B = period 20 | alt + shift - 0x2F : yabai -m window --toggle float 21 | 22 | # change focused window 23 | alt - h : yabai3 focus west 24 | alt - j : yabai3 focus south 25 | alt - k : yabai3 focus north 26 | alt - l : yabai3 focus east 27 | 28 | # change focused workspace 29 | alt - 1 : yabai -m space --focus 1 30 | alt - 2 : yabai -m space --focus 2 31 | alt - 3 : yabai -m space --focus 3 32 | alt - 4 : yabai -m space --focus 4 33 | alt - 5 : yabai -m space --focus 5 34 | alt - 6 : yabai -m space --focus 6 35 | alt - 7 : yabai -m space --focus 7 36 | alt - 8 : yabai -m space --focus 8 37 | alt - 9 : yabai -m space --focus 9 38 | alt - 0 : yabai -m space --focus 10 39 | 40 | # move focused windows 41 | alt + shift - h : yabai3 move west 42 | alt + shift - j : yabai3 move south 43 | alt + shift - k : yabai3 move north 44 | alt + shift - l : yabai3 move east 45 | 46 | # move focused window to workspace 47 | alt + shift - 1 : yabai -m window --space 1 48 | alt + shift - 2 : yabai -m window --space 2 49 | alt + shift - 3 : yabai -m window --space 3 50 | alt + shift - 4 : yabai -m window --space 4 51 | alt + shift - 5 : yabai -m window --space 5 52 | alt + shift - 6 : yabai -m window --space 6 53 | alt + shift - 7 : yabai -m window --space 7 54 | alt + shift - 8 : yabai -m window --space 8 55 | alt + shift - 9 : yabai -m window --space 9 56 | alt + shift - 0 : yabai -m window --space 10 57 | 58 | # new window insertions 59 | alt - b : yabai -m window --insert south 60 | alt - v : yabai -m window --insert east 61 | 62 | # new terminals 63 | alt - return : alacritty-new 64 | alt + shift - b : yabai -m window --insert south && alacritty-new 65 | alt + shift - v : yabai -m window --insert east && alacritty-new 66 | 67 | # stack window movement mode 68 | :: stack 69 | alt - s ; stack 70 | stack < escape ; default 71 | stack < s : yabai -m window --insert stack; skhd -k escape 72 | stack < return : yabai -m window --insert stack \ 73 | && alacritty-new; skhd -k escape 74 | stack < h : yabai3 stack-enter west; skhd -k escape 75 | stack < j : yabai3 stack-enter south; skhd -k escape 76 | stack < k : yabai3 stack-enter north; skhd -k escape 77 | stack < l : yabai3 stack-enter east; skhd -k escape 78 | stack < shift - h : yabai3 stack-leave west 79 | stack < shift - j : yabai3 stack-leave south 80 | stack < shift - k : yabai3 stack-leave north 81 | stack < shift - l : yabai3 stack-leave east 82 | 83 | # resize window mode 84 | :: resize 85 | alt - r ; resize 86 | resize < escape ; default 87 | resize < return ; default 88 | resize < h : yabai3 resize shrink width 96 89 | resize < j : yabai3 resize grow height 64 90 | resize < k : yabai3 resize shrink height 64 91 | resize < l : yabai3 resize grow width 96 92 | --------------------------------------------------------------------------------