Sainte moly, c'était vraiment un parcours difficile pour obtenir en apparence un résultat aussi simple.
TLDR
Exigences :
yabai
- pour obtenir des informations sur les espaces
skhd
ou autre chose pour connecter des raccourcis clavier avec des scripts shell
jq
- pour analyser la sortie json dans le shell
- (facultatif)
SpaceLauncher
- si vous l'utilisez déjà et que vous souhaitez que le raccourci soit par exemple Space+D ("D" comme Bureau)
Si vous n'utilisez pas yabai
, installer tout ce qui précède peut être trop. Cette solution n'est peut-être acceptable que si vous utilisez déjà yabai
ou prévoyez de l'utiliser.
Bonne nouvelle - ma solution ne nécessite pas de désactiver SIP (Protection de l'intégrité du système).
1. D'accord, c'est parti. Créez les fichiers ci-dessous dans un dossier (je les ai mis dans ~/.local/scripts/
).
get_empty_space.sh
#!/bin/bash
my_array=($(yabai -m query --spaces --display | jq '.[].windows | any'))
any_space_empty=false
for ((i = 0; i < ${#my_array[@]}; i++)); do
if ! ${my_array[i]}; then
echo $((i + 1))
any_space_empty=true
break
fi
done
if ! $any_space_empty; then
echo false
fi
create_space.sh
open -a 'Mission Control'
sleep 0.1
osascript -e 'tell application "System Events" to click (every button whose value of attribute "AXDescription" is "add desktop") of group 2 of group 1 of group 1 of process "Dock"'
sleep 0.1
osascript -e 'tell application "System Events" to key code 53'
switch_space.sh
#!/bin/bash
declare -a desktophash
desktophash[1]=18
desktophash[2]=19
desktophash[3]=20
desktophash[4]=21
desktophash[5]=23
desktophash[6]=22
desktophash[7]=26
desktophash[8]=28
desktophash[9]=25
desktophash[10]=29
desktopkey=${desktophash[$1]}
osascript -e "tell application \"System Events\" to key code $desktopkey using option down"
go_to_desktop.sh
#!/bin/bash
empty_space=$(/Users/yourname/.local/scripts/get_empty_space.sh)
if [ "$empty_space" == "false" ]; then
/Users/yourname/.local/scripts/create_space.sh
sleep 0.15
fi
empty_space=$(/Users/yourname/.local/scripts/get_empty_space.sh)
/Users/yourname/.local/scripts/switch_space.sh $empty_space
2. Ensuite, attribuez les autorisations d'exécution aux fichiers ci-dessus.
chmod +x ~/.local/scripts/get_empty_space.sh
chmod +x ~/.local/scripts/create_space.sh
chmod +x ~/.local/scripts/switch_space.sh
chmod +x ~/.local/scripts/go_to_desktop.sh
3. Attribuez des raccourcis système macOS pour les espaces.
- Créez des espaces/bureaux de sorte qu'au moins 10 existent avant de passer à l'étape suivante.
- Allez dans Préférences Système > Clavier > Raccourcis > Contrôle de Mission.
- Attribuez des raccourcis pour les 10 entrées Basculer vers le Bureau N.
- Les raccourcis qui ne nécessitent pas de modifier mon code ci-dessus sont Opt+N, donc Opt+1 va vers l'espace 1, et ainsi de suite. Vous pouvez choisir des raccourcis différents, mais alors vous devrez modifier
switch_space.sh
en conséquence, probablement juste la dernière ligne de celui-ci.
4. Attribuez un raccourci dans skhd
pour exécuter le script go_to_desktop.sh
.
Dans le fichier .skhdrc
, ajoutez une ligne comme ceci :
f4 : /Users/yourname/.local/scripts/go_to_desktop.sh
4a. (étape facultative) Dans SpaceLauncher liez Space+D pour appuyer sur F4.
- Touche : D
- Action : Simuler une frappe de touche
- Touche : F4
5. Appuyez sur le raccourci - vous devrez peut-être ajouter des autorisations à skhd
avant qu'il ne commence à fonctionner.
Explication et débogage
1. Si vous avez une langue OS différente de l'anglais américain, vous devrez peut-être modifier le script create_space.sh
.
Basé sur le fil de discussion de StackOverflow d'où je tire mon script, le script ci-dessous a de bonnes chances de fonctionner, mais n'est pas testé :
open -b 'com.apple.exposelauncher'
sleep 0.5
osascript -e 'tell application id "com.apple.systemevents" tell (every application process whose bundle identifier = "com.apple.dock") to click (button 1 of group 2 of group 1 of group 1)'
sleep 0.5
osascript -e 'key code 53 -- touche Échap'
L'AppleScript du fil de discussion :
do shell script "open -b 'com.apple.exposelauncher'"
delay 0.5
tell application id "com.apple.systemevents"
tell (every application process ¬
whose bundle identifier = "com.apple.dock") to ¬
click (button 1 of group 2 of group 1 of group 1)
delay 0.5
key code 53 -- touche Échap
end tell
2. Vous devrez peut-être augmenter les délais dans create_space.sh
et go_to_desktop.sh
pour qu'ils fonctionnent correctement sur votre Mac.
Par essais et erreurs et en partant de 0,5 seconde, j'ai abouti aux délais dans mes scripts. J'utilise un MacBook Pro M1.
3. Une brève explication des scripts.
Vous pouvez tester tous les scripts séparément pour voir s'ils fonctionnent et ce qu'ils font.
create_space.sh
- assez explicite. L'espace créé sera à la fin.
switch_space.sh
- imite le clic sur Opt+N sur le clavier. Il est utilisé comme ./switch_space.sh 5
pour aller à l'espace n° 5.
get_empty_space.sh
- affiche le nombre entier d'un espace vide. S'il n'y a pas d'espace vide, il affiche false
. La sortie de celui-ci sera une entrée à switch_space.sh
.
go_to_desktop.sh
- le code, je pense, est assez lisible pour s'expliquer lui-même.
La magie se produit principalement dans la première ligne de get_empty_space.sh
. La fonction yabai -m query --spaces --display
renvoie quelque chose comme :
[{
"index":1,
"windows":[1350901],
...
},
...
]
La clé windows de chaque espace peut nous dire s'il y a des fenêtres là-bas ou non. Nous le passons à jq
avec cette ligne yabai -m query --spaces --display | jq '.[].windows'
et obtenons simplement les listes de fenêtres.
[
1350901
]
[
1357661
]
...
Améliorez-le encore avec | any
et cette ligne yabai -m query --spaces --display | jq '.[].windows | any'
nous donne une liste de booléens, où true
signifie qu'il y a des fenêtres dans l'espace donné.
true
true
...
Le reste est assez standard en bash
.
Pensées finales
N'est-ce pas trop pour une tâche aussi "simple" ? Peut-être. Il aurait probablement pu être réalisé avec juste un script bash au lieu de 4, mais :
- a) J'ai passé beaucoup de temps à apprendre le
bash
pour le faire fonctionner et c'était plus facile pour moi de cette façon
- b) ces scripts ne font qu'une petite tâche chacun et je m'attends à leur trouver une utilisation dans d'autres automatisations également