الانتقال إلى المحتوى الرئيسي

Voice Wake وPush-to-Talk

الأوضاع

  • وضع كلمة التنبيه (الافتراضي): ينتظر مُعرِّف Speech العامل دائمًا رموز التشغيل (swabbleTriggerWords). وعند المطابقة يبدأ الالتقاط، ويعرض النافذة المتراكبة مع النص الجزئي، ويرسل تلقائيًا بعد الصمت.
  • Push-to-talk (الضغط المطول على Right Option): اضغط مطولًا على مفتاح Right Option لبدء الالتقاط فورًا — من دون حاجة إلى كلمة تشغيل. تظهر النافذة المتراكبة أثناء الضغط؛ ويؤدي الإفلات إلى الإنهاء والتمرير بعد تأخير قصير حتى تتمكن من تعديل النص.

سلوك وقت التشغيل (كلمة التنبيه)

  • يعيش مُعرِّف Speech في VoiceWakeRuntime.
  • لا يتم التشغيل إلا عند وجود توقف ذي معنى بين كلمة التنبيه والكلمة التالية (~فجوة 0.55 ثانية). ويمكن أن تبدأ النافذة المتراكبة/النغمة عند هذا التوقف حتى قبل بدء الأمر.
  • نوافذ الصمت: 2.0 ثانية عندما يكون الكلام مستمرًا، و5.0 ثوانٍ إذا لم يُسمع سوى trigger فقط.
  • الإيقاف الصارم: 120 ثانية لمنع الجلسات الخارجة عن السيطرة.
  • إزالة الارتداد بين الجلسات: 350ms.
  • تُدار النافذة المتراكبة عبر VoiceWakeOverlayController مع تلوين committed/volatile.
  • بعد الإرسال، يُعاد تشغيل المُعرِّف بشكل نظيف للاستماع إلى trigger التالية.

ثوابت دورة الحياة

  • إذا كانت Voice Wake مفعلة وكانت الأذونات ممنوحة، فيجب أن يكون مُعرِّف كلمة التنبيه في وضع الاستماع (إلا أثناء التقاط push-to-talk صريح).
  • يجب ألا تمنع رؤية النافذة المتراكبة (بما في ذلك الإغلاق اليدوي عبر زر X) استئناف المُعرِّف للاستماع أبدًا.

وضع فشل النافذة المتراكبة العالقة (سابقًا)

في السابق، إذا علقت النافذة المتراكبة مرئية وأغلقتها يدويًا، فقد تبدو Voice Wake “ميتة” لأن محاولة إعادة التشغيل في وقت التشغيل قد تُحجب بسبب ظهور النافذة المتراكبة ولم تكن تُجدول أي إعادة تشغيل لاحقة. التقوية:
  • لم تعد إعادة تشغيل وقت تشغيل التنبيه محجوبة بسبب ظهور النافذة المتراكبة.
  • يؤدي اكتمال إغلاق النافذة المتراكبة إلى تشغيل VoiceWakeRuntime.refresh(...) عبر VoiceSessionCoordinator، لذا فإن الإغلاق اليدوي بزر X يعيد الاستماع دائمًا.

تفاصيل Push-to-Talk

  • يستخدم اكتشاف المفتاح الساخن مراقب .flagsChanged عامًا لمفتاح Right Option (keyCode 61 + .option). نحن نراقب الأحداث فقط (من دون اعتراضها).
  • يعيش مسار الالتقاط في VoicePushToTalk: يبدأ Speech فورًا، ويبث الأجزاء الجزئية إلى النافذة المتراكبة، ويستدعي VoiceWakeForwarder عند الإفلات.
  • عند بدء push-to-talk، نوقف وقت تشغيل كلمة التنبيه مؤقتًا لتجنب تنافس audio taps؛ ويُعاد تشغيله تلقائيًا بعد الإفلات.
  • الأذونات: يتطلب Microphone + Speech؛ كما أن رؤية الأحداث تحتاج إلى موافقة Accessibility/Input Monitoring.
  • لوحات المفاتيح الخارجية: قد لا يكشف بعضها عن Right Option كما هو متوقع — لذا وفّر اختصارًا بديلًا إذا أبلغ المستخدمون عن حالات تفويت.

الإعدادات المواجهة للمستخدم

  • مفتاح Voice Wake: يفعّل وقت تشغيل كلمة التنبيه.
  • Hold Cmd+Fn to talk: يفعّل مراقب push-to-talk. ويكون معطلًا على macOS < 26.
  • محددات اللغة والميكروفون، ومقياس المستوى المباشر، وجدول كلمات التشغيل، وأداة الاختبار (محلية فقط؛ ولا تقوم بالتمرير).
  • يحتفظ محدد الميكروفون بآخر اختيار إذا انقطع جهاز ما، ويعرض تلميحًا بانقطاعه، ويرجع مؤقتًا إلى إعداد النظام الافتراضي حتى يعود.
  • الأصوات: نغمات عند اكتشاف trigger وعند الإرسال؛ ويكون الافتراضي هو صوت نظام macOS “Glass”. ويمكنك اختيار أي ملف يمكن لـ NSSound تحميله (مثل MP3/WAV/AIFF) لكل حدث أو اختيار No Sound.

سلوك التمرير

  • عند تمكين Voice Wake، يتم تمرير النصوص المفرغة إلى gateway/agent النشط (الوضع المحلي أو البعيد نفسه المستخدم في بقية تطبيق mac).
  • تُسلَّم الردود إلى آخر مزود رئيسي تم استخدامه (WhatsApp/Telegram/Discord/WebChat). وإذا فشل التسليم، فسيُسجل الخطأ وتظل عملية التشغيل مرئية عبر WebChat/سجلات الجلسة.

حمولة التمرير

  • تقوم VoiceWakeForwarder.prefixedTranscript(_:) بإضافة تلميح الجهاز قبل الإرسال. وهي مشتركة بين مساري كلمة التنبيه وpush-to-talk.

تحقق سريع

  • فعّل push-to-talk، واضغط مطولًا على Cmd+Fn، وتحدث، ثم أفلت: يجب أن تعرض النافذة المتراكبة الأجزاء الجزئية ثم ترسل.
  • أثناء الضغط المطول، يجب أن تظل أذنا شريط القوائم مكبرتين (باستخدام triggerVoiceEars(ttl:nil)); ثم تعودان إلى طبيعتهما بعد الإفلات.