diff --git a/Sources/App/AppDelegate.swift b/Sources/App/AppDelegate.swift index bdd84c0..4721890 100644 --- a/Sources/App/AppDelegate.swift +++ b/Sources/App/AppDelegate.swift @@ -16,10 +16,65 @@ final class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ notification: Notification) { NSApp.setActivationPolicy(.accessory) - // 启动按键监听 + // 检查辅助功能权限 + if !CGPreflightListenEventAccess() { + requestAccessibilityPermission() + } else { + startKeyMonitor() + } + + print("[App] Ready") + } + + // MARK: - Permissions + + private func requestAccessibilityPermission() { + // 自动打开系统设置 + NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility")!) + + // 显示提示 + let alert = NSAlert() + alert.messageText = "需要辅助功能权限" + alert.informativeText = """ + Voice Input 需要「辅助功能」权限才能监听 Fn 键。 + + 系统设置已自动打开,请: + 1. 点击左下角的锁并输入密码 + 2. 在列表中找到并勾选「VoiceInput」 + 3. 返回本应用 + + 点击「继续」后,应用将每 2 秒检查一次权限状态。 + """ + alert.alertStyle = .informational + alert.addButton(withTitle: "继续") + alert.addButton(withTitle: "退出") + + if alert.runModal() == .alertFirstButtonReturn { + // 轮询检查权限 + Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { [weak self] timer in + if CGPreflightListenEventAccess() { + timer.invalidate() + DispatchQueue.main.async { + self?.startKeyMonitor() + // 显示成功提示 + let successAlert = NSAlert() + successAlert.messageText = "权限已授权" + successAlert.informativeText = "辅助功能权限已开启,Voice Input 正在运行。" + successAlert.alertStyle = .informational + successAlert.runModal() + } + } + } + } else { + NSApp.terminate(nil) + } + } + + private func startKeyMonitor() { let started = keyMonitor.start() if !started { - showPermissionAlert() + print("[App] Failed to start key monitor") + return } keyMonitor.onFnDown = { [weak self] in @@ -29,8 +84,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate { keyMonitor.onFnUp = { [weak self] in self?.stopRecording() } - - print("[App] Ready") } // MARK: - Recording @@ -134,26 +187,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate { finalTranscription = "" } - // MARK: - Permissions - - private func showPermissionAlert() { - let alert = NSAlert() - alert.messageText = "Accessibility Permission Required" - alert.informativeText = """ - Voice Input needs Accessibility permission to detect the Fn key globally. - - Please go to System Settings > Privacy & Security > Accessibility - and enable Voice Input. - """ - alert.alertStyle = .warning - alert.addButton(withTitle: "Open System Settings") - alert.addButton(withTitle: "Later") - - if alert.runModal() == .alertFirstButtonReturn { - NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility")!) - } - } - func applicationWillTerminate(_ notification: Notification) { keyMonitor.stop() audioMonitor.stop() diff --git a/VoiceInput-20260424.dmg b/VoiceInput-20260424.dmg index 00cdf31..c03bfda 100644 Binary files a/VoiceInput-20260424.dmg and b/VoiceInput-20260424.dmg differ