From 5fbe9789faf05ce99bbff6ec4cd0b905519acbd0 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Fri, 03 Jul 2026 05:18:07 +0800
Subject: [PATCH] Freeze R221 2.2.2 source baseline

---
 C1.source/privatevoice.src/internal/hotkey/hotkey_darwin.go |   41 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/C1.source/privatevoice.src/internal/hotkey/hotkey_darwin.go b/C1.source/privatevoice.src/internal/hotkey/hotkey_darwin.go
index b9582fe..8143070 100755
--- a/C1.source/privatevoice.src/internal/hotkey/hotkey_darwin.go
+++ b/C1.source/privatevoice.src/internal/hotkey/hotkey_darwin.go
@@ -12,8 +12,10 @@
 static volatile double g_lastDownAt[128];
 static volatile int g_monitorStarted = 0;
 static volatile int g_monitorLaunching = 0;
+static volatile int g_monitorStopping = 0;
 static CFMachPortRef g_eventTap = NULL;
 static CFRunLoopSourceRef g_eventTapSource = NULL;
+static CFRunLoopRef g_eventTapRunLoop = 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;
@@ -138,8 +140,26 @@
 	CGEventTapEnable(g_eventTap, true);
 	g_monitorStarted = 1;
 	g_monitorLaunching = 0;
+	g_eventTapRunLoop = CFRunLoopGetCurrent();
+	if (g_eventTapRunLoop != NULL) CFRetain(g_eventTapRunLoop);
 	CFRunLoopRun();
+
+	if (g_eventTap != NULL) CGEventTapEnable(g_eventTap, false);
+	if (g_eventTapSource != NULL) {
+		CFRunLoopRemoveSource(CFRunLoopGetCurrent(), g_eventTapSource, kCFRunLoopCommonModes);
+		CFRelease(g_eventTapSource);
+		g_eventTapSource = NULL;
+	}
+	if (g_eventTap != NULL) {
+		CFRelease(g_eventTap);
+		g_eventTap = NULL;
+	}
+	if (g_eventTapRunLoop != NULL) {
+		CFRelease(g_eventTapRunLoop);
+		g_eventTapRunLoop = NULL;
+	}
 	g_monitorStarted = 0;
+	g_monitorStopping = 0;
 }
 
 static int ensureAccessibility(void) {
@@ -154,6 +174,12 @@
 		reason:@"PrivateVoice Dictation global hotkey listener"];
 }
 
+static void endHotkeyActivity(void) {
+	if (g_activityToken == nil) return;
+	[[NSProcessInfo processInfo] endActivity:g_activityToken];
+	g_activityToken = nil;
+}
+
 static void* eventTapThreadMain(void* arg) {
 	(void)arg;
 	@autoreleasepool {
@@ -164,7 +190,7 @@
 }
 
 static void startKeyMonitor(void) {
-	if (g_monitorStarted || g_monitorLaunching) return;
+	if (g_monitorStarted || g_monitorLaunching || g_monitorStopping) return;
 	g_monitorLaunching = 1;
 	pthread_t thread;
 	int err = pthread_create(&thread, NULL, eventTapThreadMain, NULL);
@@ -174,6 +200,15 @@
 		return;
 	}
 	pthread_detach(thread);
+}
+
+static void stopKeyMonitor(void) {
+	g_monitorStopping = 1;
+	if (g_eventTap != NULL) CGEventTapEnable(g_eventTap, false);
+	if (g_eventTapRunLoop != NULL) {
+		CFRunLoopStop(g_eventTapRunLoop);
+	}
+	endHotkeyActivity();
 }
 
 // isModifierDown polls the current system modifier flags via CGEventSource.
@@ -522,6 +557,10 @@
 	return false
 }
 
+func (l *darwinListener) Close() {
+	C.stopKeyMonitor()
+}
+
 func (l *darwinListener) wasPressedSince(vk int, since time.Time) bool {
 	if since.IsZero() {
 		return l.IsKeyDown(vk)

--
Gitblit v1.9.3