import AppKit import ApplicationServices public struct SystemPasteboard: PasteboardProviding { public init() {} public func readItems() -> [PasteboardItem] { (NSPasteboard.general.pasteboardItems ?? []).map { item in var dict: PasteboardItem = [:] for type in item.types { if let data = item.data(forType: type) { dict[type.rawValue] = data } } return dict } } public func writeString(_ text: String) { let pasteboard = NSPasteboard.general pasteboard.clearContents() pasteboard.setString(text, forType: .string) } public func writeItems(_ items: [PasteboardItem]) { let pasteboard = NSPasteboard.general pasteboard.clearContents() let restored = items.map { dict -> NSPasteboardItem in let item = NSPasteboardItem() for (type, data) in dict { item.setData(data, forType: NSPasteboard.PasteboardType(type)) } return item } if !restored.isEmpty { pasteboard.writeObjects(restored) } } } public struct CGEventPaster: KeystrokePosting { public enum PasteError: Error, LocalizedError { case accessibilityDenied case eventCreationFailed public var errorDescription: String? { switch self { case .accessibilityDenied: "Geen Accessibility-rechten: tekst staat op het klembord, plak zelf met ⌘V." case .eventCreationFailed: "Kon het plak-event niet aanmaken: tekst staat op het klembord." } } } public init() {} public func postPaste() throws { guard AXIsProcessTrusted() else { throw PasteError.accessibilityDenied } let source = CGEventSource(stateID: .combinedSessionState) let vKey: CGKeyCode = 0x09 guard let down = CGEvent(keyboardEventSource: source, virtualKey: vKey, keyDown: true), let up = CGEvent(keyboardEventSource: source, virtualKey: vKey, keyDown: false) else { throw PasteError.eventCreationFailed } down.flags = .maskCommand up.flags = .maskCommand down.post(tap: .cgAnnotatedSessionEventTap) up.post(tap: .cgAnnotatedSessionEventTap) } }