zonza/build_app.sh
Ralph Mayola 2b0d81796b fix: icône de barre de menu absente sur macOS Tahoe
setActivationPolicy_(Accessory) appelé avant rumps.run() empêche la
création du NSStatusItem sur Tahoe (vérifié par test A/B). Retiré :
LSUIElement dans l'Info.plist suffit pour masquer l'icône Dock.
Le lanceur redirige aussi stdout/stderr vers ~/Library/Logs/Zonza.log.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 00:14:15 +02:00

72 lines
3.2 KiB
Bash
Executable File

#!/bin/bash
# Construit Zonza.app — un LANCEUR léger (pas un bundle autonome).
#
# Pourquoi un lanceur plutôt que PyInstaller/py2app : empaqueter MLX + multiprocessing +
# hotkey globale sans compte développeur Apple se bat en permanence contre macOS (bombe à
# fork, permissions TCC réinitialisées à chaque rebuild, shaders Metal non bundlés). Le
# lanceur exécute le code via le venv du dépôt, où TOUT fonctionne de façon stable.
#
# RÈGLE DE PROPRETÉ : ce script est l'UNIQUE chemin de build. Il construit DIRECTEMENT
# dans /Applications — jamais dans /tmp ni dans le dépôt. C'est ce qui garantit qu'une
# seule entrée existe dans LaunchServices (l'historique de builds éparpillés est ce qui
# avait créé des icônes en double avec l'ancienne app Dictée).
#
# Limite : non distribuable seul (l'utilisateur doit cloner le dépôt + créer le venv).
#
# Usage : ./build_app.sh → installe directement /Applications/Zonza.app
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
APP="/Applications/Zonza.app"
CONTENTS="$APP/Contents"
PYBIN="$HERE/.venv/bin/python3"
[ -x "$PYBIN" ] || { echo "Erreur : venv introuvable ($PYBIN). Lance : python3 -m venv .venv && .venv/bin/pip install -r requirements.txt"; exit 1; }
# icône (générée si absente)
[ -f "$HERE/assets/icon.icns" ] || { "$PYBIN" "$HERE/assets/make_icon.py" && "$HERE/assets/make_icns.sh"; }
echo "→ construction du lanceur $APP"
rm -rf "$APP"
mkdir -p "$CONTENTS/MacOS" "$CONTENTS/Resources"
# exécutable : un script qui lance l'app via le python du venv (PWD = dépôt)
cat > "$CONTENTS/MacOS/zonza" <<LAUNCHER
#!/bin/bash
cd "$HERE"
exec "$PYBIN" "$HERE/app.py" >> "\$HOME/Library/Logs/Zonza.log" 2>&1
LAUNCHER
chmod +x "$CONTENTS/MacOS/zonza"
# icône
cp "$HERE/assets/icon.icns" "$CONTENTS/Resources/icon.icns"
# Info.plist : app de barre de menu (pas d'icône Dock) + permission micro + icône
cat > "$CONTENTS/Info.plist" <<'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key><string>Zonza</string>
<key>CFBundleDisplayName</key><string>Zonza</string>
<key>CFBundleIdentifier</key><string>cloud.mrtechlab.zonza</string>
<key>CFBundleVersion</key><string>1.0</string>
<key>CFBundleShortVersionString</key><string>1.0</string>
<key>CFBundlePackageType</key><string>APPL</string>
<key>CFBundleExecutable</key><string>zonza</string>
<key>CFBundleIconFile</key><string>icon</string>
<key>LSUIElement</key><true/>
<key>NSMicrophoneUsageDescription</key>
<string>Zonza a besoin du micro pour transcrire votre voix localement.</string>
</dict>
</plist>
PLIST
# enregistrement propre dans LaunchServices (remplace toute entrée précédente du même chemin)
LSREGISTER=/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister
"$LSREGISTER" -f "$APP" 2>/dev/null || true
touch "$APP"
echo "$APP installé."
echo " Lance Zonza depuis Spotlight, accorde Surveillance de l'entrée + Accessibilité une"
echo " fois (à 'python3' ou 'Zonza' selon ce que macOS propose), c'est définitif."