Yabai: Add optional label=... arguments for deleting/overwriting rules and signals

Created on 17 Jun 2019  路  6Comments  路  Source: koekeishiya/yabai

Feature suggestion

Rules and signals should have an optional label=... argument. Adding a rule (--add) with the same label as an existing rule should overwrite it, and there should also be a way to delete rules and signals using --delete label=....

Example use cases

I'm refactoring my auto update script so it just needs to be sourced鈥攁nd I'd like to register it to the system_woke signal. This does not work currently because it recursively registers itself, leading to doubled up rules on every trigger.

# inside auto update script
yabai -m signal --add event=system_woke \
        action="source ${BASH_SOURCE:-$0}"

Another use case is utilising the display_* signals to change rules, especially space assignments for windows.

Further reasoning

Unlike chunkwm, yabai has no plugin system.

After experimenting with rules and signals a lot I came to the conclusion that they can be much more flexible than plugins ever were, with just a few things missing like labels and (maybe sometime in the future?) arguments passed to the shell script. The ease of use with shell scripts is just great, especially with the queries returning JSON formatted output.

Most helpful comment

Rules can now also be labelled. Closing this.

All 6 comments

Seems reasonable. Might have to specify the event-type when removing a signal, to reduce search space. Will try without at first, but time complexity might become too high if tons of signals are utilized.

As for passing arguments to shell scripts. I'm not quite sure how much information is necessary and which signals should transmit information, but I have previously noted down the following:

     *  application_launched:   pid
     *  application_terminated: pid
     *  application_front_switched: pid
     *  application_activated: pid
     *  application_deactivated: pid
     *  application_visible: pid
     *  application_hidden: pid
     *  window_created: wid
     *  window_destroyed: wid
     *  window_focused: wid
     *  window_moved: wid
     *  window_resized: wid
     *  window_minimized: wid
     *  window_deminimized: wid
     *  window_title_changed: wid
     *  space_changed: mission-control index
     *  display_changed: arrangement-index

I don't think the other signals could carry a lot of useful information.

Regarding events and carrying information: Here's what I think.

Further additions for scripting could then be query support for pid/wid/sid/did. I think space/display id is better than mission control/arrangement index here because it survives moving stuff around. Querying could then get you the mission control / arrangement index.


Click to expand table

event|$1|$2
-|-|-
application_launched|process id
application_terminated|process id
application_front_switched|process id|last process id
application_activated|process id
application_deactivated|process id
application_visible|process id
application_hidden|process id
window_created|process id|window id
window_destroyed|process id|window id
window_focused|process id|window id
window_moved|process id|window id
window_resized|process id|window id
window_minimized|process id|window id
window_deminimized|process id|window id
window_title_changed|process id|window id
space_changed|space id|last space id
display_added|display id
display_removed|display id
display_moved|display id
display_resized|display id
display_changed|display id
mouse_down|button id|coordinates
mouse_up|button id|coordinates
mouse_dragged|button id|coordinates
mouse_moved|button id|coordinates
mission_control_enter
mission_control_check_for_exit
mission_control_exit
dock_did_restart|sa load status
menu_opened
menu_bar_hidden_changed
system_woke
bar_refresh
daemon_message|message

Signals now transmit data. I used most of your suggestion, with a couple of changes. Some events that you listed simply don't transmit data either due to implementation reasons or because I found it unnecessary.

event|$1|$2
-|-|-
application_launched|process id
application_terminated|process id
application_front_switched|process id|last process id
application_activated|process id
application_deactivated|process id
application_visible|process id
application_hidden|process id
window_created|process id|window id
window_destroyed|process id|window id
window_focused|process id|window id
window_moved|process id|window id
window_resized|process id|window id
window_minimized|process id|window id
window_deminimized|process id|window id
window_title_changed|process id|window id
space_changed|space id|last space id
display_added|display id
display_removed|display id
display_moved|display id
display_resized|display id
display_changed|display id|last display id
mouse_down|button id|coordinates
mouse_up|button id|coordinates
mouse_dragged|button id|coordinates
mouse_moved|button id|coordinates
mission_control_enter
mission_control_check_for_exit
mission_control_exit
dock_did_restart
menu_opened
menu_bar_hidden_changed
system_woke
bar_refresh
daemon_message

I found it unnecessary to send the sa load status because we automatically reload the sa when the Dock is restarted anyway. As long as the scripting-addition is not uninstalled it will always stay loaded while yabai is running.

The daemon_message signal will not pass along the message contents because of how the message system has been implemented.

Signals can now be labelled. A labelled signal will be overwritten by another signal with the same label, regardless of its event-type.

Labelled signals can be removed on demand.

# get notified when the mouse moves
yabai -m signal --add label=test event=mouse_moved action=..

# overwrite previous signal to get notified about mouse clicks instead
yabai -m signal --add label=test event=mouse_down action=..

# no longer necessary to get  notified of mouse_down events
yabai -m signal --remove test

That's amazing, thank you!

Are you planning to implement this for rules as well? I'm imagining something like this:

```sh

separate file that's sourced from .yabairc

reload this file when a display is added

yabai -m signal --add label=display_added event=display_added \
action="source ${BASH_SOURCE:-$0}"

reload this file when a display is removed

yabai -m signal --add label=display_removed event=display_removed \
action="source ${BASH_SOURCE:-$0}"

case $(yabai -m query --displays | jq '. | length') in
1)
# show mail on space 5
yabai -m rule --add label=mail app="^Mail$" space=5
;;
2)
# show mail as native-fullscreen on display 2
yabai -m rule --add label=mail app="^Mail$" display=2 native-fullscreen=on
;;
esac

Rules can now also be labelled. Closing this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

eramdam picture eramdam  路  3Comments

brentd picture brentd  路  4Comments

koekeishiya picture koekeishiya  路  4Comments

koekeishiya picture koekeishiya  路  4Comments

Hum4n01d picture Hum4n01d  路  4Comments