I want to use Swift (Xcode 13.2.1) to send a Cmd-C and Cmd-V to copy selected text in macOS 11.6 (Big Sur) as described in several StackOverflow posts (e.g. How to obtain the selected text from the frontmost application in macOS?).
I was carefully following the existing recommendations to set the right options for the macOS Security & Privacy framework:
- Disabled App Sandbox:
<key>com.apple.security.app-sandbox</key> <false/>
- Added "Hardened Runtime" and enabled "Apple Events"
- Added to
Info.plist
:<key>NSAppleEventsUsageDescription</key> <string>NSApplication</string>
- Disabled and enabled the apps checkbox in "Security & Privacy" -> "Accessibility" after every build.
But, no luck. The interesting thing is, when I'm using the same code in a "Command Line Tool" project (no GUI) everything works fine.
Here is my code:
let pasteboard = NSPasteboard.general
pasteboard.clearContents()
let source = CGEventSource(stateID: CGEventSourceStateID.hidSystemState)
let cmdKey: UInt16 = 0x38
let cKey: UInt16 = 0x08
let cmdDown = CGEvent(keyboardEventSource: source, virtualKey: cmdKey, keyDown: true)
let cmdUp = CGEvent(keyboardEventSource: source, virtualKey: cmdKey, keyDown: false)
let keyCDown = CGEvent(keyboardEventSource: source, virtualKey: cKey, keyDown: true)
let keyCUp = CGEvent(keyboardEventSource: source, virtualKey: cKey, keyDown: false)
let loc = CGEventTapLocation.cghidEventTap
cmdDown?.flags = CGEventFlags.maskCommand
cmdUp?.flags = CGEventFlags.maskCommand
keyCDown?.flags = CGEventFlags.maskCommand
keyCUp?.flags = CGEventFlags.maskCommand
cmdDown?.post(tap: loc)
keyCDown?.post(tap: loc)
cmdUp?.post(tap: loc)
keyCUp?.post(tap: loc)
sleep(1)
print("clipboard:")
let content = pasteboard.string(forType: .string) ?? "" // Default to empty string
print(content)
Any ideas or suggestions or ideas?
Best,
floek