diff --git a/WakaTime/Helpers/PropertiesManager.swift b/WakaTime/Helpers/PropertiesManager.swift index 4c44f63..c21feb6 100644 --- a/WakaTime/Helpers/PropertiesManager.swift +++ b/WakaTime/Helpers/PropertiesManager.swift @@ -14,6 +14,7 @@ class PropertiesManager { enum Keys: String { case shouldLaunchOnLogin = "launch_on_login" case shouldLogToFile = "log_to_file" + case shouldRequestA11y = "request_a11y" case shouldAutomaticallyDownloadUpdates = "should_automatically_download_updates" case hasLaunchedBefore = "has_launched_before" case domainPreference = "domain_preference" @@ -72,6 +73,21 @@ class PropertiesManager { } } + static var shouldRequestA11yPermission: Bool { + get { + guard UserDefaults.standard.string(forKey: Keys.shouldRequestA11y.rawValue) != nil else { + UserDefaults.standard.set(true, forKey: Keys.shouldRequestA11y.rawValue) + return true + } + + return UserDefaults.standard.bool(forKey: Keys.shouldRequestA11y.rawValue) + } + set { + UserDefaults.standard.set(newValue, forKey: Keys.shouldRequestA11y.rawValue) + UserDefaults.standard.synchronize() + } + } + static var hasLaunchedBefore: Bool { get { guard UserDefaults.standard.string(forKey: Keys.hasLaunchedBefore.rawValue) != nil else { diff --git a/WakaTime/Views/SettingsView.swift b/WakaTime/Views/SettingsView.swift index b7e3407..776db85 100644 --- a/WakaTime/Views/SettingsView.swift +++ b/WakaTime/Views/SettingsView.swift @@ -44,8 +44,18 @@ class SettingsView: NSView, NSTextFieldDelegate, NSTextViewDelegate { return checkbox }() + lazy var requestA11yCheckbox: NSButton = { + let checkbox = NSButton( + checkboxWithTitle: "Enable stats from Xcode by requesting accessibility permission", + target: self, + action: #selector(enableA11yCheckboxClicked) + ) + checkbox.state = PropertiesManager.shouldRequestA11yPermission ? .on : .off + return checkbox + }() + lazy var checkboxesStackView: NSStackView = { - let stack = NSStackView(views: [launchAtLoginCheckbox, enableLoggingCheckbox]) + let stack = NSStackView(views: [launchAtLoginCheckbox, requestA11yCheckbox, enableLoggingCheckbox]) stack.alignment = .leading stack.orientation = .vertical stack.spacing = 10 @@ -233,6 +243,15 @@ class SettingsView: NSView, NSTextFieldDelegate, NSTextViewDelegate { } } + @objc func enableA11yCheckboxClicked() { + PropertiesManager.shouldRequestA11yPermission = requestA11yCheckbox.state == .on + if requestA11yCheckbox.state == .on { + PropertiesManager.shouldRequestA11yPermission = true + } else { + PropertiesManager.shouldRequestA11yPermission = false + } + } + @objc func domainPreferenceDidChange(_ sender: NSSegmentedControl) { PropertiesManager.domainPreference = sender.selectedSegment == 0 ? .domain : .url updateDomainPreference(animate: true) diff --git a/WakaTime/WakaTime.swift b/WakaTime/WakaTime.swift index 1dc0c78..7282644 100644 --- a/WakaTime/WakaTime.swift +++ b/WakaTime/WakaTime.swift @@ -24,7 +24,7 @@ class WakaTime: HeartbeatEventHandler { Dependencies.installDependencies() if SettingsManager.shouldRegisterAsLoginItem() { SettingsManager.registerAsLoginItem() } - if !Accessibility.requestA11yPermission() { + if PropertiesManager.shouldRequestA11yPermission && !Accessibility.requestA11yPermission() { delegate.a11yStatusChanged(false) } diff --git a/WakaTime/Watchers/Watcher.swift b/WakaTime/Watchers/Watcher.swift index c271221..206d1ab 100644 --- a/WakaTime/Watchers/Watcher.swift +++ b/WakaTime/Watchers/Watcher.swift @@ -148,6 +148,10 @@ class Watcher: NSObject { } catch { Logging.default.log("Failed to setup AXObserver: \(error.localizedDescription)") + guard PropertiesManager.shouldRequestA11yPermission else { + return + } + // TODO: App could be still launching, retry setting AXObserver in 20 seconds for this app if lastCheckedA11y.timeIntervalSinceNow > 60 {