Is it possible to disable tiling for a display? I'd like windows to behave similar to vanilla macOS (except for the bar space).
I'm running on a MBP 13'' and tiling doesn't go too well with that size. I do, however, use tiling extensively when using external displays.
Thanks.
_Note: I wrote a lot more than I intended to at first, but maybe people can learn about some advanced features of yabai from this._
Let's walk you through how you can already do this with yabai's existing API.
What tools do we need, and where is their documentation located at?
|Tool|Documentation|
|-:|:-|
|yabai| https://github.com/koekeishiya/yabai/blob/master/doc/yabai.asciidoc|
|jq|https://stedolan.github.io/jq/manual/|
Having read the documentation, what are the obvious limitations we are trying to work around?
With that in mind, let's solve each of these individually.
1. a) How do we identify the target display?
We can either use the display with the smallest size, the first one by index (mostly reliable), or the main display (that's the one whose (frame.x, frame.y) == (0, 0)).
I'll choose to use the display with the index 1 for this solution, as it's the easiest to read.
1. b) How do we set the layout for a given space?
The yabai documentation holds the answer to this:
yabai -m space [<selector>] --layout <bsp|float>
1. c) How do we set the layout for all spaces on one display?
First of all, we want to do this in our yabairc so the code always executes right after yabai starts.
We can get a list of all spaces from a given display using yabai -m query --displays --display <selector>. A valid selector here would be the index 1, or the named selector first.
We can then use jq to print all mission-control indices associated with the display, and use xargs to make yabai execute a command for every single one of them.
yabai -m query --displays --display 1 |
jq '.spaces[]' |
xargs -I{} yabai -m space {} --layout float
Running this, you may notice lots of cannot set layout for a macOS fullscreen space! error messages. Let's fix these by excluding fullscreen spaces from our query. You may notice that display queries do not carry this information, so we need to switch a space query instead.
yabai -m query --spaces --display 1 |
jq '.[] | select(."native-fullscreen" == 0).index' |
xargs -I{} yabai -m space {} --layout float
Works like a charm!
2. How do we handle new spaces?
yabai cannot currently notify you when new spaces are created, as this is unsupported by the signal API. What you can do, however, is register for the space_changed signal, which triggers whenever the space focus changes.
The space_changed signal carries two points of data: $YABAI_SPACE_ID (id of the newly focused space) and $YABAI_RECENT_SPACE_ID (id of the previously focused space).
We can then figure out if $YABAI_SPACE_ID is a non-fullscreen space on the target display, and if it is, change its layout to float.
yabai -m signal --add event=space_changed action="$action"
Now, what does this $action need to look like?
read -r -d '' action <<- 'EOF'
yabai -m query --spaces --display 1 |
jq ".[] | select(.id == $YABAI_SPACE_ID and .\"native-fullscreen\" == 0).index" |
xargs -I{} yabai -m space {} --layout float
EOF
This can still be improved by also switching the space back to bsp if it's on another display, but I won't show that here.
3. What if a space gets moved between displays?
Think about it: While a space is being moved between displays, it cannot be focused. If you can live without immediately changing the layout of moved spaces, the signal from 2. might be good enough already.
yabais signal API is limited to events that macOS emits, which is why there are no space_moved, space_created, or space_destroyed events.
Such events would need to be artificially created by yabai, but could in turn improve the signal API. These are not a thing yet.
Most helpful comment
_Note: I wrote a lot more than I intended to at first, but maybe people can learn about some advanced features of yabai from this._
Let's walk you through how you can already do this with yabai's existing API.
Problem Space
What tools do we need, and where is their documentation located at?
|Tool|Documentation|
|-:|:-|
|yabai| https://github.com/koekeishiya/yabai/blob/master/doc/yabai.asciidoc|
|jq|https://stedolan.github.io/jq/manual/|
Having read the documentation, what are the obvious limitations we are trying to work around?
With that in mind, let's solve each of these individually.
Solution Space
1. a) How do we identify the target display?
We can either use the display with the smallest size, the first one by index (mostly reliable), or the main display (that's the one whose
(frame.x, frame.y) == (0, 0)).I'll choose to use the display with the index 1 for this solution, as it's the easiest to read.
1. b) How do we set the layout for a given space?
The yabai documentation holds the answer to this:
1. c) How do we set the layout for all spaces on one display?
First of all, we want to do this in our yabairc so the code always executes right after yabai starts.
We can get a list of all spaces from a given display using
yabai -m query --displays --display <selector>. A valid selector here would be the index1, or the named selectorfirst.We can then use
jqto print all mission-control indices associated with the display, and usexargsto make yabai execute a command for every single one of them.Running this, you may notice lots of
cannot set layout for a macOS fullscreen space!error messages. Let's fix these by excluding fullscreen spaces from our query. You may notice that display queries do not carry this information, so we need to switch a space query instead.Works like a charm!
2. How do we handle new spaces?
yabai cannot currently notify you when new spaces are created, as this is unsupported by the signal API. What you can do, however, is register for the
space_changedsignal, which triggers whenever the space focus changes.The
space_changedsignal carries two points of data:$YABAI_SPACE_ID(id of the newly focused space) and$YABAI_RECENT_SPACE_ID(id of the previously focused space).We can then figure out if
$YABAI_SPACE_IDis a non-fullscreen space on the target display, and if it is, change its layout to float.Now, what does this
$actionneed to look like?This can still be improved by also switching the space back to bsp if it's on another display, but I won't show that here.
3. What if a space gets moved between displays?
Think about it: While a space is being moved between displays, it cannot be focused. If you can live without immediately changing the layout of moved spaces, the signal from 2. might be good enough already.
Future Improvement Ideas
yabais signal API is limited to events that macOS emits, which is why there are no
space_moved,space_created, orspace_destroyedevents.Such events would need to be artificially created by yabai, but could in turn improve the signal API. These are not a thing yet.