diff --git a/apps/macos/Sources/OpenClaw/DevicePairingApprovalPrompter.swift b/apps/macos/Sources/OpenClaw/DevicePairingApprovalPrompter.swift index 195ab66daf..f85e8d1a5d 100644 --- a/apps/macos/Sources/OpenClaw/DevicePairingApprovalPrompter.swift +++ b/apps/macos/Sources/OpenClaw/DevicePairingApprovalPrompter.swift @@ -22,16 +22,6 @@ final class DevicePairingApprovalPrompter { private var alertHostWindow: NSWindow? private var resolvedByRequestId: Set = [] - private final class AlertHostWindow: NSWindow { - override var canBecomeKey: Bool { - true - } - - override var canBecomeMain: Bool { - true - } - } - private struct PairingList: Codable { let pending: [PendingRequest] let paired: [PairedDevice]? @@ -238,35 +228,11 @@ final class DevicePairingApprovalPrompter { } private func endActiveAlert() { - guard let alert = self.activeAlert else { return } - if let parent = alert.window.sheetParent { - parent.endSheet(alert.window, returnCode: .abort) - } - self.activeAlert = nil - self.activeRequestId = nil + PairingAlertSupport.endActiveAlert(activeAlert: &self.activeAlert, activeRequestId: &self.activeRequestId) } private func requireAlertHostWindow() -> NSWindow { - if let alertHostWindow { - return alertHostWindow - } - - let window = AlertHostWindow( - contentRect: NSRect(x: 0, y: 0, width: 520, height: 1), - styleMask: [.borderless], - backing: .buffered, - defer: false) - window.title = "" - window.isReleasedWhenClosed = false - window.level = .floating - window.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary] - window.isOpaque = false - window.hasShadow = false - window.backgroundColor = .clear - window.ignoresMouseEvents = true - - self.alertHostWindow = window - return window + PairingAlertSupport.requireAlertHostWindow(alertHostWindow: &self.alertHostWindow) } private func handle(push: GatewayPush) { diff --git a/apps/macos/Sources/OpenClaw/NodePairingApprovalPrompter.swift b/apps/macos/Sources/OpenClaw/NodePairingApprovalPrompter.swift index 964b340e6b..ee994b38f6 100644 --- a/apps/macos/Sources/OpenClaw/NodePairingApprovalPrompter.swift +++ b/apps/macos/Sources/OpenClaw/NodePairingApprovalPrompter.swift @@ -38,16 +38,6 @@ final class NodePairingApprovalPrompter { private var remoteResolutionsByRequestId: [String: PairingResolution] = [:] private var autoApproveAttempts: Set = [] - private final class AlertHostWindow: NSWindow { - override var canBecomeKey: Bool { - true - } - - override var canBecomeMain: Bool { - true - } - } - private struct PairingList: Codable { let pending: [PendingRequest] let paired: [PairedNode]? @@ -242,35 +232,11 @@ final class NodePairingApprovalPrompter { } private func endActiveAlert() { - guard let alert = self.activeAlert else { return } - if let parent = alert.window.sheetParent { - parent.endSheet(alert.window, returnCode: .abort) - } - self.activeAlert = nil - self.activeRequestId = nil + PairingAlertSupport.endActiveAlert(activeAlert: &self.activeAlert, activeRequestId: &self.activeRequestId) } private func requireAlertHostWindow() -> NSWindow { - if let alertHostWindow { - return alertHostWindow - } - - let window = AlertHostWindow( - contentRect: NSRect(x: 0, y: 0, width: 520, height: 1), - styleMask: [.borderless], - backing: .buffered, - defer: false) - window.title = "" - window.isReleasedWhenClosed = false - window.level = .floating - window.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary] - window.isOpaque = false - window.hasShadow = false - window.backgroundColor = .clear - window.ignoresMouseEvents = true - - self.alertHostWindow = window - return window + PairingAlertSupport.requireAlertHostWindow(alertHostWindow: &self.alertHostWindow) } private func handle(push: GatewayPush) { diff --git a/apps/macos/Sources/OpenClaw/PairingAlertSupport.swift b/apps/macos/Sources/OpenClaw/PairingAlertSupport.swift new file mode 100644 index 0000000000..e8e4428bf3 --- /dev/null +++ b/apps/macos/Sources/OpenClaw/PairingAlertSupport.swift @@ -0,0 +1,46 @@ +import AppKit + +final class PairingAlertHostWindow: NSWindow { + override var canBecomeKey: Bool { + true + } + + override var canBecomeMain: Bool { + true + } +} + +@MainActor +enum PairingAlertSupport { + static func endActiveAlert(activeAlert: inout NSAlert?, activeRequestId: inout String?) { + guard let alert = activeAlert else { return } + if let parent = alert.window.sheetParent { + parent.endSheet(alert.window, returnCode: .abort) + } + activeAlert = nil + activeRequestId = nil + } + + static func requireAlertHostWindow(alertHostWindow: inout NSWindow?) -> NSWindow { + if let alertHostWindow { + return alertHostWindow + } + + let window = PairingAlertHostWindow( + contentRect: NSRect(x: 0, y: 0, width: 520, height: 1), + styleMask: [.borderless], + backing: .buffered, + defer: false) + window.title = "" + window.isReleasedWhenClosed = false + window.level = .floating + window.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary] + window.isOpaque = false + window.hasShadow = false + window.backgroundColor = .clear + window.ignoresMouseEvents = true + + alertHostWindow = window + return window + } +}