yabai icon indicating copy to clipboard operation
yabai copied to clipboard

Add FARTHEST_DIR_SEL for windows

Open kiryph opened this issue 2 years ago • 3 comments

This PR is useful to enable circulation (aka cyclic or periodic boundaries) requested in https://github.com/koekeishiya/yabai/issues/1165.

Following excerpt of an skhd file illustrates how to define mappings to use the added FARTHEST_DIR_SEL

# Left ⇧ ^ h
shift + ctrl - h : yabai -m window --focus west \
|| yabai -m window --focus farthest_east

# Down ⇧ ^ j
shift + ctrl - j : yabai -m window --focus south \
|| yabai -m window --focus farthest_north

# Up ⇧ ^ k
shift + ctrl - k : yabai -m window --focus north \
|| yabai -m window --focus farthest_south

# Right ⇧ ^ l
shift + ctrl - l : yabai -m window --focus east \
|| yabai -m window --focus farthest_west

Similar mappings can be defined for --swap, --stack and --warp.

kiryph avatar Feb 23 '22 10:02 kiryph

Simpler Solutions with jq min_by/max_by(.frame.x)

This is simpler compared to the PR since it ignores the y-coordinate. In complex window layouts, the behaviour of the PR can be viewed as more desirable since two windows with the same x-coordinate are distinguished by the y-coordinate and the one with the closer y-coordinate is returned.

Windows

  1. Focus Most Right Window across Displays
yabai -m window --focus $(yabai -m query --windows | jq '[.[] | select(."is-visible")] | max_by(.frame.x) | .id')
  1. Focus Most Left Window across Displays
yabai -m window --focus $(yabai -m query --windows | jq '[.[] | select(."is-visible")] | min_by(.frame.x) | .id')
  1. Focus Most Left Window on Right Display
yabai -m window --focus $(yabai -m query --windows --display east | jq '[.[] | select(."is-visible")] | min_by(.frame.x) | .id')
  1. Focus Most Right Window on Left Display
yabai -m window --focus $(yabai -m query --windows --display west | jq '[.[] | select(."is-visible")] | max_by(.frame.x) | .id')

Displays

This approach can also be used to determine for displays the farthest east/west display

  1. Focus Most Right Display
yabai -m display --focus $(yabai -m query --displays | jq 'max_by(.frame.x) | .index')
  1. Focus Most Left Display
yabai -m display --focus $(yabai -m query --displays | jq 'min_by(.frame.x) | .index')

kiryph avatar Jul 21 '22 15:07 kiryph

Solution with jq min_by/max_by and minimize perpendicular coordinate

  1. Focus Top Window on Current Space
CUR=$(yabai -m query --windows --window | jq -rc) &&\
MIN_Y=$(yabai -m query --windows --space | jq -e '[.[] | select(."is-visible")] | min_by(.frame.y) | .frame.y') &&\
FARTHEST_NORTH=$(yabai -m query --windows --space | jq -e --argjson min_y $MIN_Y --argjson cur $CUR \
'[.[] | select(."is-visible" and .frame.y == $min_y and .frame.y < $cur.frame.y)] | min_by((.frame.x - $cur.frame.x)|fabs) | .id') &&\
yabai -m window --focus $FARTHEST_NORTH;
  1. Focus Bottom Window on Current Space
CUR=$(yabai -m query --windows --window | jq -rc) &&\
MAX_Y=$(yabai -m query --windows --space | jq -e '[.[] | select(."is-visible")] | max_by(.frame.y) | .frame.y') &&\
FARTHEST_SOUTH=$(yabai -m query --windows --space | jq -e --argjson max_y $MAX_Y --argjson cur $CUR \
'[.[] | select(."is-visible" and .frame.y == $max_y and .frame.y > $cur.frame.y)] | min_by((.frame.x-$cur.frame.x)|fabs) | .id') &&\
yabai -m window --focus $FARTHEST_SOUTH;
  1. Focus Most Left Window on Current Space
CUR=$(yabai -m query --windows --window | jq -rc) &&\
MIN_X=$(yabai -m query --windows --space | jq -e '[.[] | select(."is-visible")] | min_by(.frame.x) | .frame.x') &&\
FARTHEST_WEST=$(yabai -m query --windows --space | jq -e --argjson min_x $MIN_X --argjson cur $CUR \
'[.[] | select(."is-visible" and .frame.x == $min_x and .frame.x < $cur.frame.x)] | min_by((.frame.y-$cur.frame.y)|fabs) | .id') &&\
yabai -m window --focus $FARTHEST_WEST;
  1. Focus Most Right Window on Current Space
CUR=$(yabai -m query --windows --window | jq -rc) &&\
MAX_X=$(yabai -m query --windows --space | jq -e '[.[] | select(."is-visible")] | max_by(.frame.x) | .frame.x') &&\
FARTHEST_EAST=$(yabai -m query --windows --space | jq -e --argjson max_x $MAX_X --argjson cur $CUR \
'[.[] | select(."is-visible" and .frame.x == $max_x and .frame.x > $cur.frame.x)] | min_by((.frame.y-$cur.frame.y)|fabs) | .id') &&\
yabai -m window --focus $FARTHEST_EAST;

However, a builtin solution can be faster. These shell scripts consist of

  • 3x yabai queries
  • 3x invocations of jq and
  • the final user action

kiryph avatar Jul 25 '22 09:07 kiryph

Yes, with this it would be so much easier

Bellavene avatar Sep 11 '23 19:09 Bellavene