Un lanceur Qt pour Windows, et un assemblage partage
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,7 +25,6 @@ if "--diagnostic" in sys.argv:
|
||||
print(mettre_en_forme(diagnostiquer()))
|
||||
sys.exit(0)
|
||||
|
||||
import os
|
||||
import threading
|
||||
|
||||
from objc import super
|
||||
@@ -41,11 +40,8 @@ from Foundation import NSObject, NSTimer
|
||||
from PyObjCTools import AppHelper
|
||||
from pynput import keyboard
|
||||
|
||||
from controller import ZonzaController
|
||||
from core import CONFIG, modele_retenu, validate_config
|
||||
from interface import classe_overlay_pour
|
||||
from moteur import choisir_transcripteur, detecter_moteur
|
||||
from systeme import choisir_systeme
|
||||
from assemblage import acquerir_verrou, construire
|
||||
from core import CONFIG
|
||||
|
||||
_STATE_TITLES = {
|
||||
"idle": "🎙️",
|
||||
@@ -55,19 +51,21 @@ _STATE_TITLES = {
|
||||
|
||||
|
||||
class ZonzaApp(NSObject):
|
||||
"""Délégué applicatif : status item + menu + hotkey + contrôleur."""
|
||||
"""Délégué applicatif : status item + menu + hotkey.
|
||||
|
||||
def initWithTranscripteur_systeme_(self, transcripteur, systeme):
|
||||
Le contrôleur (donc le transcripteur, l'overlay et le système) vient déjà
|
||||
assemblé d'`assemblage.construire()` — voir `main()`. Ce délégué ne fait
|
||||
plus QUE ce qui est propre à Cocoa : le NSStatusItem, le menu, et le
|
||||
marshalage `AppHelper.callAfter` vers le thread principal.
|
||||
"""
|
||||
|
||||
def initWithController_(self, controller):
|
||||
self = super().init()
|
||||
if self is None:
|
||||
return None
|
||||
self._item = None
|
||||
self._sounds_item = None
|
||||
self.pulse = classe_overlay_pour().alloc().init()
|
||||
self.controller = ZonzaController(
|
||||
CONFIG, self.pulse, transcripteur, systeme, on_state=self._set_state,
|
||||
run_on_main=AppHelper.callAfter,
|
||||
)
|
||||
self.controller = controller
|
||||
self._listener = None
|
||||
return self
|
||||
|
||||
@@ -144,23 +142,18 @@ class ZonzaApp(NSObject):
|
||||
|
||||
def main():
|
||||
# une seule instance a la fois : sinon deux modeles en RAM et la meme
|
||||
# hotkey captee deux fois (cf systeme.acquerir_verrou_instance).
|
||||
# hotkey captee deux fois (cf systeme.acquerir_verrou_instance). La prise
|
||||
# du verrou reste ICI (pas dans assemblage.construire) : c'est au lanceur
|
||||
# de décider quoi faire d'un refus, avant même de construire quoi que ce
|
||||
# soit d'autre.
|
||||
from systeme import choisir_systeme
|
||||
systeme = choisir_systeme()
|
||||
lock = systeme.acquerir_verrou_instance(
|
||||
os.path.join(systeme.dossier_donnees(), "instance.lock")
|
||||
)
|
||||
lock = acquerir_verrou(systeme)
|
||||
if lock is None:
|
||||
print("[garde] une autre instance de Zonza tourne deja — arret.")
|
||||
return
|
||||
main._lock = lock # garder le verrou vivant tant que le process vit
|
||||
validate_config(CONFIG)
|
||||
moteur = detecter_moteur()
|
||||
transcripteur = choisir_transcripteur(
|
||||
nom=moteur,
|
||||
modele=modele_retenu(moteur, CONFIG["model"]),
|
||||
langue=CONFIG["language"],
|
||||
amorce=CONFIG["initial_prompt"],
|
||||
)
|
||||
|
||||
# si l'Accessibilité n'est pas accordée, macOS affiche sa popup officielle
|
||||
# (« Zonza souhaite contrôler cet ordinateur ») et ajoute l'app à la liste —
|
||||
# bien plus fiable qu'un ajout manuel via « + » dans les Réglages.
|
||||
@@ -170,8 +163,19 @@ def main():
|
||||
)
|
||||
trusted = AXIsProcessTrustedWithOptions({kAXTrustedCheckOptionPrompt: True})
|
||||
print(f"[diag] accessibilité accordée : {bool(trusted)}")
|
||||
|
||||
app = NSApplication.sharedApplication()
|
||||
delegate = ZonzaApp.alloc().initWithTranscripteur_systeme_(transcripteur, systeme)
|
||||
# Dépendance circulaire : `on_state` doit marshaler vers `delegate._apply_title`,
|
||||
# mais `delegate` a besoin du contrôleur déjà construit pour naître. Cassée
|
||||
# avec une case remplie APRÈS coup, comme dans lanceur_qt.py — la fermeture
|
||||
# ne lit `case["delegate"]` qu'au moment de l'appel, jamais à la construction.
|
||||
case = {}
|
||||
assemblage = construire(
|
||||
run_on_main=AppHelper.callAfter,
|
||||
on_state=lambda s: case["delegate"]._set_state(s),
|
||||
)
|
||||
delegate = ZonzaApp.alloc().initWithController_(assemblage["controller"])
|
||||
case["delegate"] = delegate
|
||||
delegate.setup()
|
||||
# référence gardée pour toute la vie du processus (sinon GC → icône disparaît)
|
||||
main._delegate = delegate
|
||||
|
||||
Reference in New Issue
Block a user