koekeishiya / yabai

A tiling window manager for macOS based on binary space partitioning
MIT License
24.01k stars 652 forks source link

Swap the current node and the biggest node #186

Closed kiryph closed 5 years ago

kiryph commented 5 years ago

bspwm offers to swap the current node and the biggest node and has an example shortcut for this in the example config file:

# swap the current node and the biggest node
super + g
    bspc node -s biggest

I would find this useful as well since I tend to treat one area as my main working area (similar to what under Amethyst is called main pane or under Xmonad master area).

dominiklohmann commented 5 years ago

This has been possible since the addition of #105, which added the window selectors smallest and largest.

# syntax: yabai -m window [<sel>] --swap largest
# e.g. to swap the focused window with the largest window:
yabai -m window --swap largest
kiryph commented 5 years ago

Thanks again. I did not see it in the documentation:

Apparently, one can find it under https://github.com/koekeishiya/yabai/blob/master/doc/yabai.asciidoc#5-definitions

kiryph commented 5 years ago

@dominiklohmann I was wondering, if this fails (i.e. focus is on the largest node/window), is it possible to toggle with the last window?

dominiklohmann commented 5 years ago

It returns a non-zero exit code, so you can use a || b or if ! a; then b; fi

yabai -m window --swap largest || yabai -m window --swap last

Additionally, if you want the first output to not appear in your error log file for skhd when it fails, you can redirect it's error message to /dev/null.

yabai -m window --swap largest 2> /dev/null || yabai -m window --swap last

However... this really makes no sense to do at all here. If focusing the largest tiled window fails, focusing the last tiled window will also fail, as both will refer to the same window when only a single tiled window is on the space.

kiryph commented 5 years ago

I was not clear enough: I meant the last window swapped with.

Maybe a way could be to store on the first invocation of alt-b the window id of the largest node. On a new invocation, while the largest window is focused, this id (if exists) could be used to swap with.

Is there a possibility to store a value persistently between invocations of mappings in an skhdrc config?

dominiklohmann commented 5 years ago

The closest built-in thing is the recent selector for the most recently focused window.

Is there a possibility to store a value persistently between invocations of mappings in an skhdrc config?

Store the value in a file in ${TMPDIR}, e.g.

# I have not tested this, but I think this should work
(yabai -m window --swap largest && yabai -m query --windows --window | jq -r '.id' > "${TMPDIR}/yabai_last_window_swapped_wid") || yabai -m window --swap "$(cat "${TMPDIR}/yabai_last_window_swapped_wid")"
kiryph commented 5 years ago

Yes, this helps me.

However, the exit code of yabai -m window --swap largest; echo $? is always zero, even when no swapping occurs (e.g. terminal window is the largest window where I execute this command).

Is this intentional?

dominiklohmann commented 5 years ago

Well it's not like the swap failed, it's just a no-op. Not sure if this can be considered a bug for swap/warp. I created a new issue to discuss this behaviour (#187).

kiryph commented 5 years ago

Instead of relying on the exit code, another possibility is to check if the window id of largest window is unchanged:

alt - m : \
    largest_id=$(yabai -m query --windows --window largest | jq -r '.id');\
    current_id=$(yabai -m query --windows --window | jq -r '.id');\
    if [ "$largest_id" != "$current_id" ]; then;\
      echo "$largest_id" >! "${TMPDIR}/yabai_last_window_swapped_wid";\
      yabai -m window --swap largest;\
    elif test -f "${TMPDIR}/yabai_last_window_swapped_wid"; then;\
      yabai -m window --swap $(cat "${TMPDIR}/yabai_last_window_swapped_wid");\
    fi;

I use zsh which complains by > if file already exists, hence >! is used. I do not know if this is compatible with posix or at least bash.

dominiklohmann commented 5 years ago

You can setopt CLOBBER in zsh to use the POSIX sh compatible behaviour. You probably have it unset somewhere, I think it‘a a default option.

kiryph commented 5 years ago

It has turned out that the 'directory' module of zimfw which I use does this:

https://github.com/zimfw/zimfw/blob/5b90c96cd136eb13010d9e71e36da4f59caed7e3/modules/directory/README.md