|
|
@ -10,6 +10,7 @@ public final class AppDelegate: NSObject, NSApplicationDelegate { |
|
|
private var isBusyFinalizing = false |
|
|
private var isBusyFinalizing = false |
|
|
private var currentAudioLevel: Float = 0.0 |
|
|
private var currentAudioLevel: Float = 0.0 |
|
|
private var latestPartialText: String? = nil |
|
|
private var latestPartialText: String? = nil |
|
|
|
|
|
private var permissionPollTimer: Timer? |
|
|
|
|
|
|
|
|
// Remote Android Phone Local Receiver (Port 8999) |
|
|
// Remote Android Phone Local Receiver (Port 8999) |
|
|
private var remoteListener: NWListener? |
|
|
private var remoteListener: NWListener? |
|
|
@ -135,6 +136,34 @@ public final class AppDelegate: NSObject, NSApplicationDelegate { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private func checkInitialPermissions() { |
|
|
private func checkInitialPermissions() { |
|
|
|
|
|
// 1. Force macOS to trigger the system Accessibility prompt dialog! |
|
|
|
|
|
let axOptions = [kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String: true] as CFDictionary |
|
|
|
|
|
let axTrusted = AXIsProcessTrustedWithOptions(axOptions) |
|
|
|
|
|
print("AppDelegate: 🔒 Accessibility Permission Status (trusted: \(axTrusted))") |
|
|
|
|
|
|
|
|
|
|
|
if !axTrusted { |
|
|
|
|
|
print("AppDelegate: ⚠️ Accessibility not yet granted! Prompting user and monitoring...") |
|
|
|
|
|
// Open Accessibility pane directly |
|
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { |
|
|
|
|
|
if let url = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility") { |
|
|
|
|
|
NSWorkspace.shared.open(url) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Poll every 1.5 seconds until user toggles the switch |
|
|
|
|
|
permissionPollTimer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: true) { [weak self] timer in |
|
|
|
|
|
let nowTrusted = AXIsProcessTrusted() |
|
|
|
|
|
if nowTrusted { |
|
|
|
|
|
print("AppDelegate: 🟢 Accessibility Permission GRANTED by user!") |
|
|
|
|
|
timer.invalidate() |
|
|
|
|
|
self?.permissionPollTimer = nil |
|
|
|
|
|
HotkeyManager.shared.registerHotkeys() |
|
|
|
|
|
HUDOverlayController.shared.show(state: .success(text: "دسترسی Accessibility تایید شد ✅")) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 2. Microphone permission |
|
|
audioRecorder.requestMicrophonePermission { granted in |
|
|
audioRecorder.requestMicrophonePermission { granted in |
|
|
if !granted { |
|
|
if !granted { |
|
|
print("Warning: Microphone permission not granted.") |
|
|
print("Warning: Microphone permission not granted.") |
|
|
|