Add accessibility request button

This commit is contained in:
Hariharan Mudaliar 2025-12-01 22:30:40 +05:30
commit 05ce48968d
3 changed files with 194 additions and 4 deletions

View file

@ -0,0 +1,76 @@
import Foundation
import Combine
import AppKit
#if canImport(ApplicationServices)
import ApplicationServices
#endif
/// Tracks accessibility permission status and exposes helpers to request access.
@MainActor
final class AccessibilityPermissionStore: ObservableObject {
static let shared = AccessibilityPermissionStore()
@Published private(set) var isAuthorized: Bool = AccessibilityPermissionStore.isAccessibilityAuthorized()
private var pollingTask: Task<Void, Never>?
private init() {}
deinit {
pollingTask?.cancel()
}
func refreshStatus() {
updateAuthorizationStatus(to: Self.isAccessibilityAuthorized())
}
func requestAuthorizationPrompt() {
#if canImport(ApplicationServices)
let promptKey = kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String
let options: CFDictionary = [promptKey: true] as CFDictionary
_ = AXIsProcessTrustedWithOptions(options)
#endif
beginPollingForStatusChanges()
}
func openSystemSettings() {
#if os(macOS)
if let url = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility") {
NSWorkspace.shared.open(url)
}
#endif
}
private func beginPollingForStatusChanges() {
pollingTask?.cancel()
pollingTask = Task { [weak self] in
for _ in 0..<30 {
try? await Task.sleep(nanoseconds: 500_000_000)
let status = Self.isAccessibilityAuthorized()
await MainActor.run {
guard let self else { return }
self.updateAuthorizationStatus(to: status)
}
if status {
break
}
}
}
}
private func updateAuthorizationStatus(to newValue: Bool) {
guard newValue != isAuthorized else { return }
isAuthorized = newValue
if !newValue {
beginPollingForStatusChanges()
}
}
private static func isAccessibilityAuthorized() -> Bool {
#if canImport(ApplicationServices)
return AXIsProcessTrusted()
#else
return true
#endif
}
}