Cykl życia nakładki głosowej (macOS)
Odbiorcy: współtwórcy aplikacji na macOS. Cel: utrzymać przewidywalne zachowanie nakładki głosowej, gdy nakładają się słowo wybudzające i push‑to‑talk.Aktualna intencja
- Jeśli nakładka jest już widoczna z powodu słowa wybudzającego, a użytkownik naciśnie skrót klawiszowy, sesja hotkey przejmuje istniejący tekst zamiast go resetować. Nakładka pozostaje widoczna, dopóki skrót jest przytrzymany. Po zwolnieniu: wyślij, jeśli istnieje przycięty tekst; w przeciwnym razie zamknij.
- Samo słowo wybudzające nadal wysyła automatycznie po ciszy; push‑to‑talk wysyła natychmiast po zwolnieniu.
Zaimplementowane (9 grudnia 2025)
- Sesje nakładki przenoszą teraz token na każde przechwycenie (słowo wybudzające lub push‑to‑talk). Aktualizacje częściowe/końcowe/wysyłania/zamykania/poziomu są odrzucane, gdy token się nie zgadza, co zapobiega przestarzałym wywołaniom zwrotnym.
- Push‑to‑talk przejmuje dowolny widoczny tekst nakładki jako prefiks (tak aby naciśnięcie skrótu, gdy nakładka wybudzenia jest aktywna, zachowało tekst i dodało nową mowę). Czeka do 1,5 s na końcową transkrypcję, po czym w razie potrzeby wraca do bieżącego tekstu.
- Logowanie dźwięków sygnalnych/nakładki jest emitowane w
infow kategoriachvoicewake.overlay,voicewake.pttorazvoicewake.chime(start sesji, częściowe, końcowe, wysłanie, zamknięcie, powód dźwięku).
Następne kroki
- VoiceSessionCoordinator (actor)
- W danym momencie posiada dokładnie jeden
VoiceSession. - API (oparte na tokenach):
beginWakeCapture,beginPushToTalk,updatePartial,endCapture,cancel,applyCooldown. - Odrzuca wywołania zwrotne niosące przestarzałe tokeny (zapobiega ponownemu otwieraniu nakładki przez stare rozpoznawacze).
- W danym momencie posiada dokładnie jeden
- VoiceSession (model)
- Pola:
token,source(wakeWord|pushToTalk), tekst zatwierdzony/ulotny, flagi dźwięków, timery (auto‑wysyłanie, bezczynność),overlayMode(display|editing|sending), termin zakończenia cooldown.
- Pola:
- Powiązanie nakładki
VoiceSessionPublisher(ObservableObject) odzwierciedla aktywną sesję w SwiftUI.VoiceWakeOverlayViewrenderuje wyłącznie poprzez publisher; nigdy nie modyfikuje bezpośrednio globalnych singletonów.- Akcje użytkownika w nakładce (
sendNow,dismiss,edit) wywołują koordynatora z tokenem sesji.
- Ujednolicona ścieżka wysyłania
- Przy
endCapture: jeśli przycięty tekst jest pusty → zamknij; w przeciwnym razieperformSend(session:)(odtwarza dźwięk wysyłania jeden raz, przekazuje dalej, zamyka). - Push‑to‑talk: bez opóźnienia; słowo wybudzające: opcjonalne opóźnienie dla auto‑wysyłania.
- Zastosuj krótki cooldown dla środowiska wake po zakończeniu push‑to‑talk, aby słowo wybudzające nie uruchamiało się natychmiast ponownie.
- Przy
- Logowanie
- Koordynator emituje logi
.infow podsystemiebot.molt, kategorievoicewake.overlayorazvoicewake.chime. - Kluczowe zdarzenia:
session_started,adopted_by_push_to_talk,partial,finalized,send,dismiss,cancel,cooldown.
- Koordynator emituje logi
Lista kontrolna debugowania
-
Strumieniuj logi podczas odtwarzania „przyklejonej” nakładki:
- Zweryfikuj, że istnieje tylko jeden aktywny token sesji; przestarzałe wywołania zwrotne powinny być odrzucane przez koordynatora.
-
Upewnij się, że zwolnienie push‑to‑talk zawsze wywołuje
endCapturez aktywnym tokenem; jeśli tekst jest pusty, oczekujdismissbez dźwięku i bez wysyłania.
Kroki migracji (sugerowane)
- Dodaj
VoiceSessionCoordinator,VoiceSessionorazVoiceSessionPublisher. - Zrefaktoryzuj
VoiceWakeRuntime, aby tworzyć/aktualizować/kończyć sesje zamiast bezpośrednio dotykaćVoiceWakeOverlayController. - Zrefaktoryzuj
VoicePushToTalk, aby przejmować istniejące sesje i wywoływaćendCaptureprzy zwolnieniu; zastosuj cooldown środowiska. - Podłącz
VoiceWakeOverlayControllerdo publishera; usuń bezpośrednie wywołania z runtime/PTT. - Dodaj testy integracyjne dla przejmowania sesji, cooldown oraz zamykania przy pustym tekście.