fix(computer-use): settle macOS permission checks

This commit is contained in:
Jinwoo-H
2026-08-07 05:41:07 -04:00
parent 419151dddd
commit 5947912569
6 changed files with 366 additions and 32 deletions
@@ -0,0 +1,73 @@
import Foundation
public enum PermissionTrustSettling {
public struct Outcome: Equatable {
public let settled: Bool
public let attempts: Int
public let waitedMs: Int
public init(settled: Bool, attempts: Int, waitedMs: Int) {
self.settled = settled
self.attempts = attempts
self.waitedMs = waitedMs
}
}
public static let defaultTimeoutMs = 1_500
public static let defaultIntervalMs = 100
public static func settle(
timeoutMs: Int = defaultTimeoutMs,
intervalMs: Int = defaultIntervalMs,
sleepMs: (Int) -> Void = { interval in
Thread.sleep(forTimeInterval: TimeInterval(interval) / 1_000)
},
probe: () -> Bool
) -> Outcome {
precondition(timeoutMs >= 0, "timeoutMs must not be negative")
precondition(intervalMs > 0, "intervalMs must be positive")
var attempts = 0
var waitedMs = 0
while true {
attempts += 1
if probe() {
return Outcome(settled: true, attempts: attempts, waitedMs: waitedMs)
}
if waitedMs >= timeoutMs {
return Outcome(settled: false, attempts: attempts, waitedMs: waitedMs)
}
let interval = min(intervalMs, timeoutMs - waitedMs)
sleepMs(interval)
waitedMs += interval
}
}
public static func settleWithFallback(
initialTimeoutMs: Int = defaultTimeoutMs,
finalTimeoutMs: Int,
intervalMs: Int = defaultIntervalMs,
sleepMs: (Int) -> Void = { interval in
Thread.sleep(forTimeInterval: TimeInterval(interval) / 1_000)
},
probe: () -> Bool,
fallbackProbe: () -> Bool
) -> Bool {
if settle(
timeoutMs: initialTimeoutMs,
intervalMs: intervalMs,
sleepMs: sleepMs,
probe: probe
).settled {
return true
}
if fallbackProbe() {
return true
}
return settle(
timeoutMs: finalTimeoutMs,
intervalMs: intervalMs,
sleepMs: sleepMs,
probe: probe
).settled
}
}
@@ -0,0 +1,22 @@
public struct ScreenCaptureProbeWindow: Equatable {
public let layer: Int
public let ownerPid: Int32
public let windowId: UInt32
public init(layer: Int, ownerPid: Int32, windowId: UInt32) {
self.layer = layer
self.ownerPid = ownerPid
self.windowId = windowId
}
}
public enum ScreenCaptureProbeWindowSelection {
public static func firstCrossProcessNormalWindow(
ownPid: Int32,
windows: [ScreenCaptureProbeWindow]
) -> UInt32? {
windows.first { window in
window.layer == 0 && window.ownerPid != ownPid
}?.windowId
}
}