YABAI(1)

πŸ“¦ version 7.1.25, in nixpkgs unstable

🌸 YABAI(1) β€” the Yabai Manual, bestie 🌸

okay so welcome to the yabai(1) manual, but make it make sense. it's giving β€œUnix docs but your smartest friend is explaining it in the group chat.” no cap.

πŸ’– NAME πŸ’–

yabai β€” window manager. that's the whole name, periodt.

✨ SYNOPSIS ✨

yabai
[--load-sa|--uninstall-sa|--install-service|--uninstall-service|--start-service|--restart-service|--stop-service|--message,-m
msg|--config,-c config_file|--verbose,-V|--version,-v|--help,-h]

πŸ¦‹ DESCRIPTION πŸ¦‹

okay so yabai is a tiling window manager for macOS based on binary space partitioning. literally iconic, fr fr.

πŸ’… OPTIONS πŸ’…

  • --load-sa β€” Load the scripting-addition into Dock.app. Installs and updates the scripting-addition when necessary. Path is /Library/ScriptingAdditions/yabai.osax. ⚠️ System Integrity Protection must be partially disabled.
  • --uninstall-sa β€” Uninstall the scripting-addition. Must be run as root. Path is /Library/ScriptingAdditions/yabai.osax. ⚠️ System Integrity Protection must be partially disabled.
  • --install-service β€” Writes a launchd service file to disk. Path is ~/Library/LaunchAgents/com.asmvik.yabai.plist.
  • --uninstall-service β€” Removes a launchd service file from disk. Path is ~/Library/LaunchAgents/com.asmvik.yabai.plist.
  • --start-service β€” Enables, loads, and starts the launchd service. Will install service file if it does not exist.
  • --restart-service β€” Attempts to restart the service instance.
  • --stop-service β€” Stops a running instance of the service and unloads it.
  • --message, -m <msg> β€” Send message to a running instance of yabai β€” that's your <msg>, bestie.
  • --config, -c <config_file> β€” Use the specified configuration file. Executes using /usr/bin/env sh -c <config_file> if the exec-bit is set. Interpreted using /usr/bin/env sh <config_file> if the exec-bit is unset.
  • --verbose, -V β€” Output debug information to stdout.
  • --version, -v β€” Print version to stdout and exit.
  • --help, -h β€” Print options to stdout and exit.

🌈 DEFINITIONS 🌈

here's the little dictionary so the rest of this page doesn't feel like a cryptex. keep these exact, iykyk.

REGEX       := POSIX extended regular expression syntax
               <https://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002dextended-regular-expression-syntax.html>

LABEL       := arbitrary string/text used as an identifier

LAYER       := below | normal | above | auto

BOOL_SEL    := on | off

FLOAT_SEL   := 0 < <value> <= 1.0

RULE_SEL    := <index> | LABEL

SIGNAL_SEL  := <index> | LABEL

DIR_SEL     := north | east | south | west

STACK_SEL   := stack.prev | stack.next | stack.first | stack.last | stack.recent | stack.<index (1-based)>

WINDOW_SEL  := prev | next | first | last | recent | mouse | largest | smallest | sibling | first_nephew | second_nephew | uncle | first_cousin | second_cousin | STACK_SEL | DIR_SEL | <window id>

DISPLAY_SEL := prev | next | first | last | recent | mouse | DIR_SEL | <arrangement index (1-based)> | LABEL

SPACE_SEL   := prev | next | first | last | recent | mouse | <mission-control index (1-based)> | LABEL

EASING      := ease_in_sine  | ease_out_sine  | ease_in_out_sine  |
               ease_in_quad  | ease_out_quad  | ease_in_out_quad  |
               ease_in_cubic | ease_out_cubic | ease_in_out_cubic |
               ease_in_quart | ease_out_quart | ease_in_out_quart |
               ease_in_quint | ease_out_quint | ease_in_out_quint |
               ease_in_expo  | ease_out_expo  | ease_in_out_expo  |
               ease_in_circ  | ease_out_circ  | ease_in_out_circ

🌟 DOMAINS 🌟

the domains are the big categories, bestie. we're going in order, no skipping, okay?

πŸŽ€ Config πŸŽ€

General Syntax

yabai -m config <global setting>

Get or set the value of <global setting>.

yabai -m config [--space <SPACE_SEL>] <space setting>

Get or set the value of <space setting>.

Global Settings

  • debug_output [<BOOL_SEL>] β€” Enable output of debug information to stdout.
  • external_bar [<main|all|off>:<top_padding>:<bottom_padding>] β€” Specify top and bottom padding for a potential custom bar that you may be running. main: Apply the given padding only to spaces located on the main display. all: Apply the given padding to all spaces regardless of their display. off: Do not apply any special padding.
  • menubar_opacity [<FLOAT_SEL>] β€” Changes the transparency of the macOS menubar. If the value is 0.0, the menubar will no longer respond to mouse-events, effectively hiding the menubar permanently. The menubar will automatically become fully opaque upon entering a native-fullscreen space, and adjusted down afterwards.
  • mouse_follows_focus [<BOOL_SEL>] β€” When focusing a window, put the mouse at its center.
  • focus_follows_mouse [autofocus|autoraise|off] β€” Automatically focus the window under the mouse.
  • display_arrangement_order [default|vertical|horizontal] β€” Specify how displays are ordered (determined by center point). default: Native macOS ordering. vertical: Order by y-coordinate (followed by x-coordinate when equal). horizontal: Order by x-coordinate (followed by y-coordinate when equal).
  • window_origin_display [default|focused|cursor] β€” Specify which display a newly created window should be managed in. default: The display in which the window is created (standard macOS behaviour). focused: The display that has focus when the window is created. cursor: The display that currently holds the mouse cursor.
  • window_placement [first_child|second_child] β€” Specify whether managed windows should become the first or second leaf-node.
  • window_insertion_point [focused|first|last] β€” Specify where new managed windows will be inserted.
  • window_zoom_persist [<BOOL_SEL>] β€” Windows will keep their zoom-state through layout changes.
  • skip_window_focus_animation [<BOOL_SEL>] β€” Bypass macOS space animation when an application or window on an inactive space is focused. You should only enable this if you do NOT use the scripting addition. The scripting addition implements the same functionality in a more robust way.
  • window_shadow [<BOOL_SEL>|float] β€” Draw shadow for windows. ⚠️ System Integrity Protection must be partially disabled.
  • window_opacity [<BOOL_SEL>] β€” Enable opacity for windows. ⚠️ System Integrity Protection must be partially disabled.
  • window_opacity_duration [<FLOAT_SEL>] β€” Duration of transition between active / normal opacity. ⚠️ System Integrity Protection must be partially disabled.
  • active_window_opacity [<FLOAT_SEL>] β€” Opacity of the focused window. ⚠️ System Integrity Protection must be partially disabled.
  • normal_window_opacity [<FLOAT_SEL>] β€” Opacity of an unfocused window. ⚠️ System Integrity Protection must be partially disabled.
  • window_animation_duration [<FLOAT_SEL>] β€” Duration of window frame animation. If 0.0, the change in dimension is not animated. Requires Screen Recording permissions. ⚠️ System Integrity Protection must be partially disabled.
  • window_animation_easing [<EASING>] β€” Easing function to use for window animations. See https://easings.net for details.
  • insert_feedback_color [0xAARRGGBB] β€” Color of the window --insert message and mouse_drag selection. The purpose is to provide a visual preview of the new window frame.
  • split_ratio [<FLOAT_SEL>] β€” Specify the size distribution when a window is split.
  • mouse_modifier [cmd|alt|shift|ctrl|fn] β€” Keyboard modifier used for moving and resizing windows.
  • mouse_action1 [move|resize] β€” Action performed when pressing mouse_modifier + button1.
  • mouse_action2 [move|resize] β€” Action performed when pressing mouse_modifier + button2.
  • mouse_drop_action [swap|stack] β€” Action performed when a bsp-managed window is dropped in the center of some other bsp-managed window.

Space Settings

  • layout [bsp|stack|float] β€” Set the layout of the selected space.
  • split_type [vertical|horizontal|auto] β€” Specify how a window should be split. vertical: The window is split along the y-axis. horizontal: The window is split along the x-axis. auto: The axis is determined based on width/height ratio.
  • top_padding [<integer number>] β€” Padding added at the upper side of the selected space.
  • bottom_padding [<integer number>] β€” Padding added at the lower side of the selected space.
  • left_padding [<integer number>] β€” Padding added at the left side of the selected space.
  • right_padding [<integer number>] β€” Padding added at the right side of the selected space.
  • window_gap [<integer number>] β€” Size of the gap that separates windows for the selected space.
  • auto_balance [<BOOL_SEL>|x-axis|y-axis] β€” Balance the window tree upon change, so that all windows occupy an equally sized area.

πŸ¦‹ Display πŸ¦‹

General Syntax

yabai -m display [<DISPLAY_SEL>] <COMMAND>

COMMAND

  • --focus <DISPLAY_SEL> β€” Focus the given display.
  • --space <SPACE_SEL> β€” The given space will become visible on the selected display, without changing focus. The given space must belong to the selected display. ⚠️ System Integrity Protection must be partially disabled.
  • --label [<LABEL>] β€” Label the selected display, allowing that label to be used as an alias in commands that take a DISPLAY_SEL parameter. If the command is called without an argument it will try to remove a previously assigned label.

🐚 Space 🐚

General Syntax

yabai -m space [<SPACE_SEL>] <COMMAND>

COMMAND

  • --focus <SPACE_SEL> β€” Focus the given space.
  • --switch <SPACE_SEL> β€” The selected space will always be the currently focused space. The given space substitutes the selected space, gaining focus. If the selected space and the given space belong to different displays, this behaves like --swap. If the selected space and the given space belong to the same display, this behaves like --focus. ⚠️ System Integrity Protection must be partially disabled.
  • --create [<DISPLAY_SEL>] β€” Create a new space on the given display. If none specified, use the display of the active space instead. ⚠️ System Integrity Protection must be partially disabled.
  • --destroy [<SPACE_SEL>] β€” Remove the given space. If none specified, use the selected space instead. ⚠️ System Integrity Protection must be partially disabled.
  • --move <SPACE_SEL> β€” Move position of the selected space to the position of the given space. The selected space and given space must both belong to the same display. ⚠️ System Integrity Protection must be partially disabled.
  • --swap <SPACE_SEL> β€” swap the selected space with the space you point at πŸ”„. If the two spaces live on different displays, literally all the windows get swapped over. If they're on the same display, then it's the actual spaces themselves that swap. Requires System Integrity Protection to be partially disabled πŸ’…
  • --display <DISPLAY_SEL> β€” yeet the selected space over to the given display πŸ–₯️✨. System Integrity Protection must be partially disabled.
  • --equalize [x-axis|y-axis] β€” resets the split ratios on the selected space back to the default value, along whichever axis you name πŸ“. Leave the axis off and it does both. Balance restored, no cap.
  • --balance [x-axis|y-axis] β€” nudges the split ratios on the selected space so every window along that axis takes up the same area βš–οΈ. No axis given? Both, obviously.
  • --mirror x-axis|y-axis β€” flips the whole tree of the selected space along the given axis πŸͺž. It's giving reflection.
  • --rotate 90|180|270 β€” rotates the tree of the selected space πŸ”„. Valid values are literally 90, 180 and 270 β€” nothing else, bestie.
  • --padding abs|rel:<top>:<bottom>:<left>:<right> β€” the padding added at the sides of the selected space 🧸. Four numbers, in that exact order.
  • --gap abs|rel:<gap> β€” the size of the gap separating windows on the selected space πŸ•³οΈβœ¨.
  • --toggle padding|gap|mission-control|show-desktop β€” flips a space setting on or off for the selected space πŸ”€.
  • --layout bsp|stack|float β€” sets the layout of the selected space 🧩.
  • --label [<LABEL>] β€” labels the selected space, so you can use that label as an alias in any command that takes a SPACE_SEL parameter πŸ·οΈπŸ’–. Call it with no argument and it'll try to remove a previously assigned label. Bye label πŸ‘‹

πŸͺŸ WINDOW

General Syntax

yabai -m window [<WINDOW_SEL>] <COMMAND>

COMMAND

  • --focus [<WINDOW_SEL>] β€” focuses the given window πŸ‘€. Nothing specified? Then it focuses the selected window instead.
  • --close [<WINDOW_SEL>] β€” closes the given window ❌. No argument means close the selected window instead. Heads up: this only works on windows that provide a close button in its titlebar β€” no button, no closing, sorry babe.
  • --minimize [<WINDOW_SEL>] β€” minimizes the given window πŸ“₯. No argument β†’ minimizes the selected one. Again: only works on windows that provide a minimize button in its titlebar.
  • --deminimize <WINDOW_SEL> β€” restores the given window if it's minimized 🌀️. Important detail: the window will only get focus if the owning application has focus. Also note you can just --focus a minimized window to restore it as the focused window β€” same result, different route, iykyk.
  • --display <DISPLAY_SEL> β€” sends the selected window to the given display πŸ–₯οΈπŸ’¨.
  • --space <SPACE_SEL> β€” sends the selected window to the given space πŸš€.
  • --swap <WINDOW_SEL> β€” swaps the position of the selected window and the given window πŸ”„.
  • --warp <WINDOW_SEL> β€” re-inserts the selected window, splitting the given window πŸŒ€. Very main character of it.
  • --stack <WINDOW_SEL> β€” stacks the given window on top of the selected window πŸ₯ž. Fair warning: any kind of warp operation performed on a stacked window will unstack it.
  • --insert <DIR_SEL>|stack β€” sets the splitting mode of the selected window βž•. Plot twist: if the current splitting mode already matches the selected mode, the action gets undone.
  • --grid <rows>:<cols>:<start-x>:<start-y>:<width>:<height> β€” sets the frame of the selected window based on a self-defined grid πŸ“βœ¨. Six numbers, colon-separated, exactly like that.
  • --move abs|rel:<dx>:<dy> β€” if the type is rel, the selected window gets moved by dx pixels horizontally and dy pixels vertically ➑️. If the type is abs, then dx and dy become the brand new position.
  • --resize top|left|bottom|right|top_left|top_right|bottom_right|bottom_left|abs:<dx>:<dy> β€” resizes the selected window by moving the given handle dx pixels horizontally and dy pixels vertically πŸ“. If the handle is abs, the new size will be dx width and dy height β€” and ngl, that one cannot be used on managed windows 🚫.
  • --ratio rel|abs:<dr> β€” if the type is rel, the split ratio of the selected window changes by dr; otherwise dr becomes the new split ratio βš–οΈ. A positive/negative delta will increase/decrease the size of the left-child β€” that's the rule, remember it.
  • --toggle float|sticky|pip|shadow|split|zoom-parent|zoom-fullscreen|windowed-fullscreen|native-fullscreen|expose|<LABEL> β€” toggles the given property of the selected window πŸ”€. The following properties require System Integrity Protection to be partially disabled: sticky, pip, shadow, and LABEL (the scratchpad identifier). πŸ’…
  • --sub-layer <LAYER> β€” sets the stacking sub-layer of the selected window πŸ—‚οΈ. Once you do this, the window is no longer eligible for automatic change in sub-layer when managed/unmanaged β€” it's on its own now. Pass the value auto to reset back to normal and make it become automatically managed again. System Integrity Protection must be partially disabled.
  • --opacity <FLOAT_SEL> β€” sets the opacity of the selected window πŸ«₯✨. After this it's no longer eligible for automatic change in opacity upon focus change. Pass 0.0 to reset back to full opacity and make it become automatically managed again. System Integrity Protection must be partially disabled.
  • --raise [<WINDOW_SEL>] β€” orders the selected window above the given window, or to the front within its layer ⬆️. System Integrity Protection must be partially disabled.
  • --lower [<WINDOW_SEL>] β€” orders the selected window below the given window, or to the back within its layer ⬇️. System Integrity Protection must be partially disabled.
  • --scratchpad [<LABEL>|recover] β€” a unique identifier used to identify a window scratchpad πŸ—’οΈ. An identifier may only be assigned to a single window at any given time. A scratchpad window will automatically be treated as a (manage=off) floating window. If the scratchpad is already taken by another window, this assignment will fail. If the scratchpad is re-assigned, the previous identifier will become available again. Leave off the value and the window will seize to be a scratchpad window. The special value recover can be used to forcefully bring all scratchpad windows to the front β€” super useful if windows become inaccessible due to a restart or crash 😭. System Integrity Protection must be partially disabled.

πŸ” QUERY

General Syntax

yabai -m query <COMMAND> [<PROPERTIES>] [<ARGUMENT>]

COMMAND

  • --displays β€” retrieve information about displays πŸ–₯️.
  • --spaces β€” retrieve information about spaces 🌌.
  • --windows β€” retrieve information about windows πŸͺŸ.

ARGUMENT

  • --display [<DISPLAY_SEL>] β€” constrain matches to the selected display πŸ–₯️.
  • --space [<SPACE_SEL>] β€” constrain matches to the selected space 🌌.
  • --window [<WINDOW_SEL>] β€” constrain matches to the selected window πŸͺŸ.

PROPERTIES

A comma-separated string containing the names of fields to include in the output 🎯. Every field name you hand over must be present in the dataformat of the corresponding entity β€” no making stuff up, bestie.

DATAFORMAT

πŸ’» DISPLAY

{
    "id": number,
    "uuid": string,
    "index": number,
    "label": string,
    "frame": object {
        "x": number,
        "y": number,
        "w": number,
        "h": number
    },
    "spaces": array of number,
    "has-focus": bool
}

🌌 SPACE

{
    "id": number,
    "uuid": string,
    "index": number,
    "label": string,
    "type": string,
    "display": number,
    "windows": array of number,
    "first-window": number,
    "last-window": number,
    "has-focus": bool,
    "is-visible": bool,
    "is-native-fullscreen": bool
}

πŸͺŸ WINDOW

{
    "id": number,
    "pid": number,
    "app": string,
    "title": string,
    "scratchpad": string,
    "frame": object {
        "x": number,
        "y": number,
        "w": number,
        "h": number,
    },
    "role": string,
    "subrole": string,
    "root-window": bool,
    "display": number,
    "space": number,
    "level": number,
    "sub-level": number,
    "layer": string,
    "sub-layer": string,
    "opacity": number,
    "split-type": string,
    "split-child": string,
    "stack-index": number,
    "can-move": bool,
    "can-resize": bool,
    "has-focus": bool,
    "has-shadow": bool,
    "has-parent-zoom": bool,
    "has-fullscreen-zoom": bool,
    "has-ax-reference": bool,
    "is-native-fullscreen": bool,
    "is-visible": bool,
    "is-minimized": bool,
    "is-hidden": bool,
    "is-floating": bool,
    "is-sticky": bool,
    "is-grabbed": bool
}
🚨 okay this next bit is important, don't skip it

Some window properties are only accessible when yabai has a valid AX-reference for that window πŸ™ˆ. This AX-reference can only be retrieved when the space that the window is visible on is active.

If windows are already opened on inactive spaces when yabai is launched, yabai will attempt to detect these using a workaround, and for most applications and windows this will work βœ…. Some windows are not detected using this method, and for those windows yabai will retrieve a limited amount of information, until the space that window belongs to becomes active β€” and here's the kicker β€” yabai window commands will NOT WORK for these windows πŸ’€.

You can spot these windows by looking at the has-ax-reference property πŸ‘€. Once the space the window belongs to becomes active, yabai will automatically create an AX-reference. From that point forwards the queries will contain complete information, and the window can be used with yabai window commands ✨.

The properties that contain incorrect information for windows with has-ax-reference: false are as follows:

{
    "role": string,
    "subrole": string,
    "can-move": bool,
    "can-resize": bool
}

πŸ“œ RULE

All rules that match the given filter will be applied in the order they were registered πŸ—ƒοΈ. If multiple rules specify a value for the same property, the latter rule will end up overriding that value. And if the display and space properties are both set, the space property takes precedence πŸ‘‘.

The following properties require System Integrity Protection to be partially disabled: sticky, sub-layer, opacity, scratchpad. πŸ’…

General Syntax

yabai -m rule <COMMAND>

πŸŽ€ RULES πŸŽ€

COMMAND

  • --add [--one-shot] [<ARGUMENT>] β€” makes a brand new rule, bestie. Rules only apply to windows that spawn after the rule has been added, so timing matters, okay? If --one-shot is present, the rule fires once and then automatically removes itself β€” one and done, no notes πŸ’….
  • --apply [<RULE_SEL> | <ARGUMENT>] β€” pushes a rule onto the windows that already exist right now. No argument given? Then all existing rules apply. Give it an index or a label and that specific rule applies. You can also just hand it arguments directly, same way you would in --add. Heads up: any existing --one-shot rules that haven't fired yet get straight up ignored by this command, lowkey rude but that's the rule πŸ™ˆ.
  • --remove <RULE_SEL> β€” yeets an existing rule, picked by its index or its label.
  • --list β€” prints out the whole roster of registered rules. ✨

ARGUMENT

  • label=<LABEL> β€” the label you use to identify the rule, one unique name per rule.
  • app[!]=<REGEX> β€” the name of the application. If ! is there, it inverts the match.
  • title[!]=<REGEX> β€” the title of the window. ! present means invert the match.
  • role[!]=<REGEX> β€” the accessibility role of the window (https://developer.apple.com/documentation/applicationservices/carbon_accessibility/roles?language=objc). ! present inverts the match.
  • subrole[!]=<REGEX> β€” the accessibility subrole of the window (https://developer.apple.com/documentation/applicationservices/carbon_accessibility/subroles?language=objc). Yeah, ! means invert the match.
  • display=[^]<DISPLAY_SEL> β€” sends the window to a display. If ^ is present, it follows focus instead.
  • space=[^]<SPACE_SEL> β€” sends the window to a space. ^ present = follow focus.
  • manage=<BOOL_SEL> β€” should this window be managed (tiled) or not (floating)? Most windows get managed automatically, so honestly you'd mostly reach for this to make something float.
  • sticky=<BOOL_SEL> β€” the window shows up on every single space. Requires System Integrity Protection to be partially disabled.
  • mouse_follows_focus=<BOOL_SEL> β€” when the window gets focused, park the mouse in its center. This overrides the global mouse_follows_focus setting.
  • sub-layer=<LAYER> β€” the window gets ordered inside this stacking sub-layer. Once you do this, the window is no longer eligible for automatic sub-layer changes when it's managed or unmanaged. Set it to auto to reset back to normal and let it become automatically managed again. Requires System Integrity Protection partially disabled.
  • opacity=<FLOAT_SEL> β€” sets the window's opacity. After this, the window is no longer eligible for automatic opacity changes on focus change. Set it to 0.0 to reset back to full opacity and make it automatically managed again. Requires System Integrity Protection partially disabled.
  • native-fullscreen=<BOOL_SEL> β€” the window should go into native macOS fullscreen mode.
  • grid=<rows>:<cols>:<start-x>:<start-y>:<width>:<height> β€” sets the window frame from a grid you define yourself. Iconic, honestly.
  • scratchpad=<LABEL> β€” a unique identifier for a window scratchpad. One identifier can only belong to one window at a time. A scratchpad window is automatically treated as a (manage=off) floating window. If this rule matches multiple windows, only the first one that matched gets the scratchpad identifier. Requires System Integrity Protection partially disabled.

DATAFORMAT

{
    "index": number,
    "label": string,
    "app": string,
    "title": string,
    "role": string,
    "subrole": string,
    "display": number,
    "space": number,
    "follow_space": bool,
    "opacity": number,
    "manage": bool (optional),
    "sticky": bool (optional),
    "mouse_follows_focus": bool (optional),
    "sub-layer": string,
    "native-fullscreen": bool (optional),
    "grid": string,
    "scratchpad": string,
    "one-shot": bool,
    "flags": string
}

πŸ“‘ SIGNALS πŸ“‘

A signal is just a lil way for you to react to an event that's already been processed. The arguments get passed to you through environment variables, so you can slurp them up in your script. 🫢

General Syntax

yabai -m signal <COMMAND>

COMMAND

  • --add event=<EVENT> action=<ACTION> [label=<LABEL>] [app[!]=<REGEX>] [title[!]=<REGEX>] [active=yes|no] β€” adds a signal (optionally labelled, bestie) that runs an action after an event of the given type gets processed. Some signals let you scope them by application name and/or window title, plus its active/focused state.
  • --remove <SIGNAL_SEL> β€” removes an existing signal, picked by index or label.
  • --list β€” outputs the list of registered signals. πŸ’–

EVENT

  • application_launched β€” fires when a new application launches. Eligible for app filter. Passes one argument: $YABAI_PROCESS_ID.
  • application_terminated β€” fires when an application gets terminated. Eligible for app and active filter. Passes one argument: $YABAI_PROCESS_ID.
  • application_front_switched β€” fires when the front-most application changes. Passes two arguments: $YABAI_PROCESS_ID, $YABAI_RECENT_PROCESS_ID.
  • application_activated β€” fires when an application is activated. Eligible for app filter. Passes one argument: $YABAI_PROCESS_ID.
  • application_deactivated β€” fires when an application is deactivated. Eligible for app filter. Passes one argument: $YABAI_PROCESS_ID.
  • application_visible β€” fires when an application becomes unhidden. Eligible for app filter. Passes one argument: $YABAI_PROCESS_ID.
  • application_hidden β€” fires when an application gets hidden. Eligible for app and active filter. Passes one argument: $YABAI_PROCESS_ID.
  • window_created β€” fires when a window is created. This also covers windows that get implicitly created at application launch. Eligible for app and title filter. Passes one argument: $YABAI_WINDOW_ID.
  • window_destroyed β€” fires when a window is destroyed. Also applies to windows implicitly destroyed at application exit. Eligible for app and active filter. Passes one argument: $YABAI_WINDOW_ID.
  • window_focused β€” fires when a window becomes the key-window. Eligible for app and title filter. Passes one argument: $YABAI_WINDOW_ID.
  • window_moved β€” fires when a window changes position. Eligible for app, title and active filter. Passes one argument: $YABAI_WINDOW_ID.
  • window_resized β€” fires when a window changes dimensions. Eligible for app, title and active filter. Passes one argument: $YABAI_WINDOW_ID.
  • window_minimized β€” fires when a window has been minimized. Eligible for app, title and active filter. Passes one argument: $YABAI_WINDOW_ID.
  • window_deminimized β€” fires when a window has been deminimized. Eligible for app and title filter. Passes one argument: $YABAI_WINDOW_ID.
  • window_title_changed β€” fires when a window changes its title. Eligible for app, title and active filter. Passes one argument: $YABAI_WINDOW_ID.
  • space_created β€” fires when a space is created. Passes two arguments: $YABAI_SPACE_ID, $YABAI_SPACE_INDEX.
  • space_destroyed β€” fires when a space is destroyed. Passes one argument: $YABAI_SPACE_ID.
  • space_changed β€” fires when the active space changes. Passes four arguments: $YABAI_SPACE_ID, $YABAI_SPACE_INDEX, $YABAI_RECENT_SPACE_ID, $YABAI_RECENT_SPACE_INDEX.
  • display_added β€” fires when a new display is added. Passes two arguments: $YABAI_DISPLAY_ID, $YABAI_DISPLAY_INDEX.
  • display_removed β€” fires when a display is removed. Passes one argument: $YABAI_DISPLAY_ID.
  • display_moved β€” fires when something changes about the display arrangement. Passes two arguments: $YABAI_DISPLAY_ID, $YABAI_DISPLAY_INDEX.
  • display_resized β€” fires when a display changes resolution. Passes two arguments: $YABAI_DISPLAY_ID, $YABAI_DISPLAY_INDEX.
  • display_changed β€” fires when the active display changes. Passes four arguments: $YABAI_DISPLAY_ID, $YABAI_DISPLAY_INDEX, $YABAI_RECENT_DISPLAY_ID, $YABAI_RECENT_DISPLAY_INDEX.
  • mission_control_enter β€” fires when mission-control activates. Passes one argument: $YABAI_MISSION_CONTROL_MODE.
  • mission_control_exit β€” fires when mission-control deactivates. Passes one argument: $YABAI_MISSION_CONTROL_MODE.
  • dock_did_change_pref β€” fires when the macOS Dock preferences change.
  • dock_did_restart β€” fires when Dock.app restarts.
  • menu_bar_hidden_changed β€” fires when the macOS menubar autohide setting changes.
  • system_woke β€” fires when macOS wakes from sleep. β˜€οΈ

ACTION

Any arbitrary command you want, executed through /usr/bin/env sh -c. Go off, bestie.


DATAFORMAT

{
    "index": number,
    "label": string,
    "app": string,
    "title": string,
    "active": bool (optional),
    "event": string,
    "action": string
}

πŸ’€ EXIT CODES πŸ’€

If yabai can't handle a message, it returns a non-zero exit code. That's the whole vibe check β€” anything nonzero means something went sideways.


πŸ‘‘ AUTHOR πŸ‘‘

Γ…smund Vikane <aasvi93 at gmail.com>


And that's the whole page, bestie β€” you made it to the end, genuinely so proud of you 🌸 This little masterpiece is Yabai, dated 2026-05-08, and it goes by YABAI(1) in the man-page streets. Now go tile some windows. Periodt. πŸ’œ

πŸ“¦ where this page comes from