Ariver
2026-05-18 ca0d8f786a86122e742914b58a4a0eacded64b61
VoiceSnapGo/internal/hotkey/hotkey_darwin.go
@@ -7,16 +7,22 @@
#cgo LDFLAGS: -framework Cocoa -framework ApplicationServices
#import <Cocoa/Cocoa.h>
#include <ApplicationServices/ApplicationServices.h>
#include <pthread.h>
static volatile int g_keysDown[128];
static volatile double g_lastDownAt[128];
static volatile int g_monitorStarted = 0;
static volatile int g_monitorLaunching = 0;
static CFMachPortRef g_eventTap = NULL;
static CFRunLoopSourceRef g_eventTapSource = NULL;
static volatile unsigned long long g_monitorStartAttempts = 0;
static volatile unsigned long long g_eventTapCreateFailures = 0;
static volatile unsigned long long g_eventTapDisabledCount = 0;
static volatile unsigned long long g_altEventSeq[2];
static volatile int g_altEventDown[2];
static volatile int g_altEventType[2];
static volatile unsigned long long g_altEventFlags[2];
static volatile double g_altEventAt[2];
static id g_activityToken = nil;
static double nowSeconds(void) {
   return CFAbsoluteTimeGetCurrent();
@@ -70,19 +76,13 @@
   if (mask == 0) return;
   BOOL physicalDown = CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, (CGKeyCode)keyCode);
   if (physicalDown) {
      handleKeyEvent(keyCode, YES);
      recordAltEvent(keyCode, 3, flags);
      return;
   }
   BOOL groupDown = (flags & mask) ? YES : NO;
   handleKeyEvent(keyCode, groupDown ? YES : NO);
   handleKeyEvent(keyCode, physicalDown ? YES : NO);
   recordAltEvent(keyCode, 3, flags);
}
static CGEventRef keyboardEventTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
   if (type == kCGEventTapDisabledByTimeout || type == kCGEventTapDisabledByUserInput) {
      g_eventTapDisabledCount++;
      if (g_eventTap != NULL) CGEventTapEnable(g_eventTap, true);
      return event;
   }
@@ -102,7 +102,11 @@
}
static void startEventTapMonitor(void) {
   if (g_monitorStarted) return;
   if (g_monitorStarted) {
      g_monitorLaunching = 0;
      return;
   }
   g_monitorStartAttempts++;
   CGEventMask eventMask = CGEventMaskBit(kCGEventKeyDown) |
      CGEventMaskBit(kCGEventKeyUp) |
@@ -114,19 +118,27 @@
      eventMask,
      keyboardEventTapCallback,
      NULL);
   if (g_eventTap == NULL) return;
   if (g_eventTap == NULL) {
      g_eventTapCreateFailures++;
      g_monitorLaunching = 0;
      return;
   }
   g_eventTapSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, g_eventTap, 0);
   if (g_eventTapSource == NULL) {
      g_eventTapCreateFailures++;
      CFRelease(g_eventTap);
      g_eventTap = NULL;
      g_monitorLaunching = 0;
      return;
   }
   CFRunLoopAddSource(CFRunLoopGetCurrent(), g_eventTapSource, kCFRunLoopCommonModes);
   CGEventTapEnable(g_eventTap, true);
   g_monitorStarted = 1;
   g_monitorLaunching = 0;
   CFRunLoopRun();
   g_monitorStarted = 0;
}
static int ensureAccessibility(void) {
@@ -134,10 +146,33 @@
   return AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)opts) ? 1 : 0;
}
static void startKeyMonitor(void) {
   dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
static void beginHotkeyActivity(void) {
   if (g_activityToken != nil) return;
   g_activityToken = [[NSProcessInfo processInfo]
      beginActivityWithOptions:NSActivityUserInitiatedAllowingIdleSystemSleep
      reason:@"VoiceSnap global hotkey listener"];
}
static void* eventTapThreadMain(void* arg) {
   (void)arg;
   @autoreleasepool {
      startEventTapMonitor();
   });
   }
   g_monitorLaunching = 0;
   return NULL;
}
static void startKeyMonitor(void) {
   if (g_monitorStarted || g_monitorLaunching) return;
   g_monitorLaunching = 1;
   pthread_t thread;
   int err = pthread_create(&thread, NULL, eventTapThreadMain, NULL);
   if (err != 0) {
      g_monitorLaunching = 0;
      g_eventTapCreateFailures++;
      return;
   }
   pthread_detach(thread);
}
// isModifierDown polls the current system modifier flags via CGEventSource.
@@ -149,7 +184,9 @@
static int isSideModifierDown(int keyCode) {
   if (keyCode >= 0 && keyCode < 128) {
      if (g_keysDown[keyCode]) return 1;
      if (CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, (CGKeyCode)keyCode)) return 1;
      if (g_keysDown[keyCode] && g_lastDownAt[keyCode] > 0 && nowSeconds() - g_lastDownAt[keyCode] < 0.25) return 1;
      if (g_keysDown[keyCode]) g_keysDown[keyCode] = 0;
      if (g_lastDownAt[keyCode] > 0 && nowSeconds() - g_lastDownAt[keyCode] < 0.12) return 1;
   }
   return 0;
@@ -157,10 +194,27 @@
static int isKeyDown(int keyCode) {
   if (keyCode >= 0 && keyCode < 128) {
      if (g_keysDown[keyCode]) return 1;
      if (CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, (CGKeyCode)keyCode)) return 1;
      if (g_keysDown[keyCode] && g_lastDownAt[keyCode] > 0 && nowSeconds() - g_lastDownAt[keyCode] < 0.25) return 1;
      if (g_keysDown[keyCode]) g_keysDown[keyCode] = 0;
      if (g_lastDownAt[keyCode] > 0 && nowSeconds() - g_lastDownAt[keyCode] < 0.12) return 1;
   }
   return 0;
}
static int isPhysicalKeyDown(int keyCode) {
   if (keyCode < 0 || keyCode >= 128) return 0;
   return CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, (CGKeyCode)keyCode) ? 1 : 0;
}
static int isTrackedKeyDown(int keyCode) {
   if (keyCode < 0 || keyCode >= 128) return 0;
   return g_keysDown[keyCode] ? 1 : 0;
}
static int isRecentKeyDown(int keyCode) {
   if (keyCode < 0 || keyCode >= 128 || g_lastDownAt[keyCode] <= 0) return 0;
   return nowSeconds() - g_lastDownAt[keyCode] < 0.12 ? 1 : 0;
}
static double lastKeyDownAge(int keyCode) {
@@ -170,6 +224,22 @@
static int isMonitorStarted(void) {
   return g_monitorStarted;
}
static int isMonitorLaunching(void) {
   return g_monitorLaunching;
}
static unsigned long long monitorStartAttempts(void) {
   return g_monitorStartAttempts;
}
static unsigned long long eventTapCreateFailures(void) {
   return g_eventTapCreateFailures;
}
static unsigned long long eventTapDisabledCount(void) {
   return g_eventTapDisabledCount;
}
static unsigned long long altEventSeq(int index) {
@@ -245,11 +315,13 @@
}
type darwinListener struct {
   lastAltSeq   map[int]uint64
   lastAltState map[int]bool
   lastAltSeq       map[int]uint64
   lastAltState     map[int]bool
   lastMonitorRetry time.Time
}
func newPlatformListener() Listener {
   C.beginHotkeyActivity()
   trusted := C.ensureAccessibility()
   if trusted == 0 {
      logger.Info("Accessibility permission not granted for current app identity — hotkey won't work until VoiceSnap is removed and re-added in System Settings > Privacy & Security > Accessibility")
@@ -257,19 +329,34 @@
      logger.Info("Accessibility permission granted")
   }
   C.startKeyMonitor()
   time.Sleep(150 * time.Millisecond)
   deadline := time.Now().Add(time.Second)
   for C.isMonitorStarted() == 0 && C.isMonitorLaunching() != 0 && time.Now().Before(deadline) {
      time.Sleep(50 * time.Millisecond)
   }
   if C.isMonitorStarted() == 0 {
      logger.Error("Keyboard event tap failed to start; check Accessibility permission")
      logger.Error(
         "Keyboard event tap not running yet; attempts=%d failures=%d launching=%t. Physical hotkey polling fallback is enabled.",
         uint64(C.monitorStartAttempts()),
         uint64(C.eventTapCreateFailures()),
         C.isMonitorLaunching() != 0,
      )
   } else {
      logger.Info("Keyboard event tap started")
      logger.Info(
         "Keyboard event tap started; attempts=%d failures=%d disabled=%d",
         uint64(C.monitorStartAttempts()),
         uint64(C.eventTapCreateFailures()),
         uint64(C.eventTapDisabledCount()),
      )
   }
   return &darwinListener{
      lastAltSeq:   map[int]uint64{},
      lastAltState: map[int]bool{},
      lastAltSeq:       map[int]uint64{},
      lastAltState:     map[int]bool{},
      lastMonitorRetry: time.Now(),
   }
}
func (l *darwinListener) IsKeyDown(vk int) bool {
   l.retryMonitorIfNeeded()
   if keyCode, ok := vkToPhysicalModifier[vk]; ok {
      down := C.isSideModifierDown(C.int(keyCode)) != 0
      l.logAltDiagnostics(vk, keyCode, down)
@@ -291,17 +378,38 @@
   return C.isKeyDown(C.int(macKey)) != 0
}
func (l *darwinListener) retryMonitorIfNeeded() {
   if C.isMonitorStarted() != 0 || C.isMonitorLaunching() != 0 {
      return
   }
   if time.Since(l.lastMonitorRetry) < 10*time.Second {
      return
   }
   l.lastMonitorRetry = time.Now()
   logger.Info(
      "Keyboard event tap retry requested; attempts=%d failures=%d disabled=%d",
      uint64(C.monitorStartAttempts()),
      uint64(C.eventTapCreateFailures()),
      uint64(C.eventTapDisabledCount()),
   )
   C.startKeyMonitor()
}
func (l *darwinListener) logAltDiagnostics(vk, keyCode int, down bool) {
   index := altDiagnosticIndex(keyCode)
   if index < 0 {
      return
   }
   physicalDown := C.isPhysicalKeyDown(C.int(keyCode)) != 0
   trackedDown := C.isTrackedKeyDown(C.int(keyCode)) != 0
   recentDown := C.isRecentKeyDown(C.int(keyCode)) != 0
   seq := uint64(C.altEventSeq(C.int(index)))
   if seq != l.lastAltSeq[vk] {
      l.lastAltSeq[vk] = seq
      logger.Info(
         "Hotkey event tap: key=%s vk=0x%X keyCode=%d seq=%d event=%s eventDown=%t pollDown=%t flags=0x%X age=%.3fs tapStarted=%t",
         "Hotkey event tap: key=%s vk=0x%X keyCode=%d seq=%d event=%s eventDown=%t pollDown=%t physicalDown=%t trackedDown=%t recentDown=%t flags=0x%X age=%.3fs tapStarted=%t",
         GetKeyName(vk),
         vk,
         keyCode,
@@ -309,6 +417,9 @@
         altEventTypeName(int(C.altEventType(C.int(index)))),
         C.altEventDown(C.int(index)) != 0,
         down,
         physicalDown,
         trackedDown,
         recentDown,
         uint64(C.altEventFlags(C.int(index))),
         float64(C.altEventAge(C.int(index))),
         C.isMonitorStarted() != 0,
@@ -317,7 +428,33 @@
   if previous, ok := l.lastAltState[vk]; !ok || previous != down {
      l.lastAltState[vk] = down
      logger.Info("Hotkey poll: key=%s vk=0x%X keyCode=%d down=%t tapStarted=%t", GetKeyName(vk), vk, keyCode, down, C.isMonitorStarted() != 0)
      logger.Info(
         "Hotkey poll: key=%s vk=0x%X keyCode=%d down=%t source=%s physicalDown=%t trackedDown=%t recentDown=%t tapStarted=%t",
         GetKeyName(vk),
         vk,
         keyCode,
         down,
         hotkeySource(down, physicalDown, trackedDown, recentDown),
         physicalDown,
         trackedDown,
         recentDown,
         C.isMonitorStarted() != 0,
      )
   }
}
func hotkeySource(down, physicalDown, trackedDown, recentDown bool) string {
   switch {
   case !down:
      return "none"
   case physicalDown:
      return "physical"
   case trackedDown:
      return "eventTap"
   case recentDown:
      return "recent"
   default:
      return "unknown"
   }
}