perf: prevent random freezes of the ui (#563)
timers were on the main thread, creating indeterministic freezes
This commit is contained in:
1 parent
7b304903ee
commit
e208da91da
4 files changed
+25
-15
No files matched your search
@@ -8,6 +8,7 @@ class BackgroundWork {
|
||||
static var crashReportsQueue: DispatchQueue!
|
||||
static var accessibilityEventsThread: BackgroundThreadWithRunLoop!
|
||||
static var mouseEventsThread: BackgroundThreadWithRunLoop!
|
||||
static var systemPermissionsThread: BackgroundThreadWithRunLoop!
|
||||
|
||||
// we cap concurrent tasks to .processorCount to avoid thread explosion on the .global queue
|
||||
static let globalSemaphore = DispatchSemaphore(value: ProcessInfo.processInfo.processorCount)
|
||||
@@ -21,6 +22,10 @@ class BackgroundWork {
|
||||
accessibilityEventsThread = BackgroundThreadWithRunLoop("accessibilityEventsThread", .userInteractive)
|
||||
mouseEventsThread = BackgroundThreadWithRunLoop("mouseEventsThread", .userInteractive)
|
||||
}
|
||||
|
||||
static func startSystemPermissionThread() {
|
||||
systemPermissionsThread = BackgroundThreadWithRunLoop("systemPermissionsThread", .utility)
|
||||
}
|
||||
}
|
||||
|
||||
extension DispatchQueue {
|
||||
|
||||
@@ -42,12 +42,13 @@ class SystemPermissions {
|
||||
}
|
||||
|
||||
static func observePermissionsPostStartup() {
|
||||
timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true, block: { _ in
|
||||
timer = Timer(timeInterval: 5, repeats: true, block: { _ in
|
||||
if !(accessibilityIsGranted() && screenRecordingIsGranted()) {
|
||||
App.app.restart()
|
||||
}
|
||||
})
|
||||
timer.tolerance = 4.9
|
||||
CFRunLoopAddTimer(BackgroundWork.systemPermissionsThread.runLoop, timer, .defaultMode)
|
||||
}
|
||||
|
||||
static func observePermissionsPreStartup(_ startupBlock: @escaping () -> Void) {
|
||||
@@ -55,23 +56,26 @@ class SystemPermissions {
|
||||
// this call triggers the permission prompt, however it's the only way to force the app to be listed with a checkbox
|
||||
SLSRequestScreenCaptureAccess()
|
||||
}
|
||||
timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { _ in
|
||||
timer = Timer(timeInterval: 0.1, repeats: true) { _ in
|
||||
let accessibility = accessibilityIsGranted()
|
||||
let screenRecording = screenRecordingIsGranted()
|
||||
if accessibility && screenRecording {
|
||||
permissionsWindow.close()
|
||||
timer.invalidate()
|
||||
startupBlock()
|
||||
} else {
|
||||
if accessibility != permissionsWindow.accessibilityView.isPermissionGranted {
|
||||
permissionsWindow.accessibilityView.updatePermissionStatus(accessibility)
|
||||
}
|
||||
if #available(OSX 10.15, *), screenRecording != permissionsWindow.screenRecordingView.isPermissionGranted {
|
||||
permissionsWindow.screenRecordingView.updatePermissionStatus(screenRecording)
|
||||
DispatchQueue.main.async {
|
||||
if accessibility && screenRecording {
|
||||
permissionsWindow.close()
|
||||
timer.invalidate()
|
||||
startupBlock()
|
||||
} else {
|
||||
if accessibility != permissionsWindow.accessibilityView.isPermissionGranted {
|
||||
permissionsWindow.accessibilityView.updatePermissionStatus(accessibility)
|
||||
}
|
||||
if #available(OSX 10.15, *), screenRecording != permissionsWindow.screenRecordingView.isPermissionGranted {
|
||||
permissionsWindow.screenRecordingView.updatePermissionStatus(screenRecording)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
timer.tolerance = 0.09
|
||||
CFRunLoopAddTimer(BackgroundWork.systemPermissionsThread.runLoop, timer, .defaultMode)
|
||||
}
|
||||
|
||||
static func ensurePermissionsAreGranted(_ continueAppStartup: @escaping () -> Void) {
|
||||
|
||||
@@ -41,6 +41,7 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
PFMoveToApplicationsFolderIfNecessary()
|
||||
#endif
|
||||
AXUIElement.setGlobalTimeout()
|
||||
BackgroundWork.startSystemPermissionThread()
|
||||
SystemPermissions.ensurePermissionsAreGranted { [weak self] in
|
||||
guard let self = self else { return }
|
||||
BackgroundWork.start()
|
||||
|
||||
@@ -4,8 +4,8 @@ class PermissionsWindow: NSWindow, NSWindowDelegate {
|
||||
var accessibilityView: PermissionView!
|
||||
var screenRecordingView: PermissionView!
|
||||
|
||||
override init(contentRect: NSRect, styleMask style: StyleMask, backing backingStoreType: BackingStoreType, defer flag: Bool) {
|
||||
super.init(contentRect: .zero, styleMask: style, backing: backingStoreType, defer: flag)
|
||||
convenience init() {
|
||||
self.init(contentRect: .zero, styleMask: [.titled, .miniaturizable, .closable], backing: .buffered, defer: false)
|
||||
delegate = self
|
||||
setupWindow()
|
||||
setupView()
|
||||
|
||||
Reference in new issue
Block a user