From 50dce2df557c6b461882f3e7c43d088ea948c884 Mon Sep 17 00:00:00 2001 From: Quentin Eude Date: Sun, 11 Oct 2026 23:13:44 +0200 Subject: [PATCH] fix(macos): suppress Swift compiler warnings - Replace force casts with unsafeDowncast for type safety - Fix AXUIElement sendability violations in async restoration - Improve C string conversion safety with explicit bounds check --- Sources/DefiMacOS/AXFocusOperations.swift | 2 +- Sources/DefiMacOS/AXFrameCoordinator.swift | 11 +++++++---- .../MacOSPlatform+WindowSnapshotDiscovery.swift | 2 +- Sources/DefiMacOS/WindowSnapshotRefreshPolicy.swift | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Sources/DefiMacOS/AXFocusOperations.swift b/Sources/DefiMacOS/AXFocusOperations.swift index 7fe8f1a0..9d96005e 100644 --- a/Sources/DefiMacOS/AXFocusOperations.swift +++ b/Sources/DefiMacOS/AXFocusOperations.swift @@ -44,6 +44,6 @@ struct AXFocusOperations: @unchecked Sendable { element, kAXFocusedAttribute as CFString, &rawValue ) == .success, let rawValue, CFGetTypeID(rawValue) == CFBooleanGetTypeID() else { return nil } - return CFBooleanGetValue(rawValue as! CFBoolean) + return CFBooleanGetValue(unsafeDowncast(rawValue, to: CFBoolean.self)) } } diff --git a/Sources/DefiMacOS/AXFrameCoordinator.swift b/Sources/DefiMacOS/AXFrameCoordinator.swift index 79bdb01a..6a2bbc9e 100644 --- a/Sources/DefiMacOS/AXFrameCoordinator.swift +++ b/Sources/DefiMacOS/AXFrameCoordinator.swift @@ -687,6 +687,7 @@ final class AXFrameCoordinator: @unchecked Sendable { lock.unlock() for (processID, restore) in retiredEnhancedUIRestores { guard let reservation = restoreReservations[processID] else { continue } + let token = restore.token reservation.queue.async { [self, reservation] in defer { reservation.release() @@ -696,17 +697,19 @@ final class AXFrameCoordinator: @unchecked Sendable { let superseded = deferredEnhancedUIRestores[processID] != nil lock.unlock() guard !superseded else { return } - let restored = AXMessagingTimeoutAccess.shared.withTimeout(0.016, elements: [restore.application]) { - accessibilityWriter.setEnhancedUserInterface(true, application: restore.application) + // AXUIElement isn't Sendable; an application element is fully identified by its pid. + let application = AXUIElementCreateApplication(processID) + let restored = AXMessagingTimeoutAccess.shared.withTimeout(0.016, elements: [application]) { + accessibilityWriter.setEnhancedUserInterface(true, application: application) } lock.lock() deferredEnhancedUIRestores[processID]?.disabled = false if !restored { // Keep a failed retirement recoverable by rediscovery or shutdown. if deferredEnhancedUIRestores[processID] == nil { - deferredEnhancedUIRestores[processID] = (restore.token, restore.application, false) + deferredEnhancedUIRestores[processID] = (token, application, false) } - appendTraceLocked("enhanced-ui-restore-failed pid=\(processID) token=\(restore.token) retired=1") + appendTraceLocked("enhanced-ui-restore-failed pid=\(processID) token=\(token) retired=1") } lock.unlock() } diff --git a/Sources/DefiMacOS/MacOSPlatform+WindowSnapshotDiscovery.swift b/Sources/DefiMacOS/MacOSPlatform+WindowSnapshotDiscovery.swift index dd372819..450f1dd1 100644 --- a/Sources/DefiMacOS/MacOSPlatform+WindowSnapshotDiscovery.swift +++ b/Sources/DefiMacOS/MacOSPlatform+WindowSnapshotDiscovery.swift @@ -358,7 +358,7 @@ extension SnapshotEngine { let retryNow = discoveryNow if unmatchedWindowElementsByProcess[processID]?.isEmpty == false { if unmatchedWindowRetryIsPending(attempts: unmatchedWindowRetryAttemptsByProcess[processID] ?? 0), - processWindowRetryDeadlines[processID].map { $0 <= retryNow + 0.000001 } == true + processWindowRetryDeadlines[processID].map({ $0 <= retryNow + 0.000001 }) == true { consumeUnmatchedWindowRetries(processIDs: [processID]) } else if forceWindowListRefresh && !unmatchedWindowRetryIsPending( diff --git a/Sources/DefiMacOS/WindowSnapshotRefreshPolicy.swift b/Sources/DefiMacOS/WindowSnapshotRefreshPolicy.swift index 95608c89..2543479b 100644 --- a/Sources/DefiMacOS/WindowSnapshotRefreshPolicy.swift +++ b/Sources/DefiMacOS/WindowSnapshotRefreshPolicy.swift @@ -295,7 +295,7 @@ func appBundleIdentifier(executablePath: String) -> String? { func appBundleIdentifier(processID: pid_t) -> String? { var path = [CChar](repeating: 0, count: Int(MAXPATHLEN) * 4) guard proc_pidpath(processID, &path, UInt32(path.count)) > 0 else { return nil } - return appBundleIdentifier(executablePath: String(cString: path)) + return appBundleIdentifier(executablePath: String(decoding: path.prefix { $0 != 0 }.map { UInt8(bitPattern: $0) }, as: UTF8.self)) } func resolvedFrontmostProcessID(