feat: 启动时自动检测权限并跳转系统设置
This commit is contained in:
parent
1aee169c68
commit
0c1482c983
@ -16,10 +16,65 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
func applicationDidFinishLaunching(_ notification: Notification) {
|
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||||
NSApp.setActivationPolicy(.accessory)
|
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()
|
let started = keyMonitor.start()
|
||||||
if !started {
|
if !started {
|
||||||
showPermissionAlert()
|
print("[App] Failed to start key monitor")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
keyMonitor.onFnDown = { [weak self] in
|
keyMonitor.onFnDown = { [weak self] in
|
||||||
@ -29,8 +84,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
keyMonitor.onFnUp = { [weak self] in
|
keyMonitor.onFnUp = { [weak self] in
|
||||||
self?.stopRecording()
|
self?.stopRecording()
|
||||||
}
|
}
|
||||||
|
|
||||||
print("[App] Ready")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Recording
|
// MARK: - Recording
|
||||||
@ -134,26 +187,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
finalTranscription = ""
|
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) {
|
func applicationWillTerminate(_ notification: Notification) {
|
||||||
keyMonitor.stop()
|
keyMonitor.stop()
|
||||||
audioMonitor.stop()
|
audioMonitor.stop()
|
||||||
|
|||||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user