Cycle through pair of spaces for two screens with one keyboard shortcut
I have two displays and created for each display with Mission Control several desktops (also known as Spaces):
Display 1: Desktops 1-5
Display 2: Desktops 6-10
I have following related settings adjusted
- Disabled: Automatically rearrange Spaces based on most recent use
- Enabled: Displays have separate Spaces
I want to treat the desktops of each display as 5 pairs:
- Desktops 1,6
- Desktops 2,7
- Desktops 3,8
- Desktops 4,9
- Desktops 5,10
I have already changed the keyboard shortcuts as following (from here):
This works fine after I have deleted ~/Library/Preferences/com.apple.symbolichotkeys.plist
.
How can I cycle through the pairs of desktops with one keyboard shortcut, e.g. ctrl-left/right
?
I am actually testing Amethyst and want to use mod1+n/p
(mod1=ctrl+shift
). I am hoping that I could use AppleScript to increase/decrease the desktop number 'modulo 5'. I am on macOS 10.14.5.
Yabai: tiling window manager with support for spaces
https://github.com/koekeishiya/yabai/wiki#comparison-with-other-window-managers
Requirements of Yabai
- "System Integrity Protection (SIP)" must be disabled
- "Displays have separate spaces" must be enabled
Note
- Yabai allows you to switch to a different space without animation (great)
Disable the Mission Control Mappings and use this ~/.skhdrc
file with mappings as the OP wants (uses jq
, e.g. install with $ brew install jq
)
ctrl - left : index=`yabai -m query --spaces --space | jq '.index'` &&\
if (($index != 1 && $index != 6 )) then\
new=$((index-1)); \
other=$(((new+4)%10+1));\
yabai -m space --focus "${other}"; yabai -m space --focus "${new}";\
fi
ctrl - right : index=`yabai -m query --spaces --space | jq '.index'` &&\
if (($index != 5 && $index != 10 )) then\
new=$((index+1)); \
other=$(((index+4)%10+1));\
yabai -m space --focus "${other}"; yabai -m space --focus "${new}";\
fi
# ctrl+1-5:
ctrl - 1 : index=`yabai -m query --displays --display | jq '.index'` &&\
if (($index == 1)) then\
yabai -m space --focus 6; yabai -m space --focus 1;\
else \
yabai -m space --focus 1; yabai -m space --focus 6;\
fi
ctrl - 2 : index=`yabai -m query --displays --display | jq '.index'` &&\
if (($index == 1)) then\
yabai -m space --focus 7; yabai -m space --focus 2;\
else \
yabai -m space --focus 2; yabai -m space --focus 7;\
fi
ctrl - 3 : index=`yabai -m query --displays --display | jq '.index'` &&\
if (($index == 1)) then\
yabai -m space --focus 8; yabai -m space --focus 3;\
else \
yabai -m space --focus 3; yabai -m space --focus 8;\
fi
ctrl - 4 : index=`yabai -m query --displays --display | jq '.index'` &&\
if (($index == 1)) then\
yabai -m space --focus 9; yabai -m space --focus 4;\
else \
yabai -m space --focus 4; yabai -m space --focus 9;\
fi
ctrl - 5 : index=`yabai -m query --displays --display | jq '.index'` &&\
if (($index == 1)) then\
yabai -m space --focus 10; yabai -m space --focus 5;\
else \
yabai -m space --focus 5; yabai -m space --focus 10;\
fi
Addition: Yabai signal space_changed
When you click in the dock on a non-visible application, only the display changes which has the space with the desired application. You can use Yabai signal space_changed
to react to any space change to change the space of the other display as well:
# file ~/.config/yabai/yabairc
yabai -m signal --add event=space_changed action="~/.config/yabai/maintain_paired_spaces.sh"
#!/usr/bin/env sh
# file: ~/.config/yabai/maintain_paired_spaces.sh
# Keep two displays with spaces [1-5] and [6-12] in sync
#
# yabai signal 'space_changed'
# Passes two arguments $YABAI_SPACE_ID and $YABAI_RECENT_SPACE_ID
# Note $YABAI_SPACE_ID is not the same as the mission control index.
# Translate YABAI_SPACE_ID to mission control index as following
new=$(yabai -m query --spaces | jq ".[] | select(.id == $YABAI_SPACE_ID) | .index")
# modulo arithmetic
other=$(((new+4)%10+1))
# Check if already visible
visible=$(yabai -m query --spaces | jq ".[] | select(.visible == 1 and .index == $other)")
if [ -z "$visible" ]; then
yabai -m space --focus "${other}"
display=$(yabai -m query --spaces --space $other | jq ".display")
fi
Note there is a small time delay.
Disable tiling
If you are not interested in a tiling window manager but want to use these mappings, you can choose the layout mode 'float' in ~/.config/yabai/yabairc
:
yabai -m config layout float