66 lines
2.2 KiB
Swift
66 lines
2.2 KiB
Swift
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)
|
|
}
|
|
}
|