How to paste text from one app to another using Cocoa?
Asked Answered
C

3

9

I have read about NSPasteBoard in the Apple documentation, and how it allows for applications to write into the PasteBoard and allow other applications to read that text and use it.

Could someone tell me how to paste text from am application (that sits in the status bar) into a NSTextField that is inside a different application.

What I am trying to do is something similar what Snippet and SnippetsApp do.

If I am completely stupid and missed the obvious in Apple Docs, could you please point me to the right path :)

Thanks!

Creel answered 21/4, 2010 at 6:25 Comment(0)
T
9

Could someone tell me how to paste text from am application (that sits in the status bar) into a NSTextField that is inside a different application.

Pasting is what happens in the receiving application. Writing to a pasteboard is copying.

Furthermore, you can't assume that the user will want to paste into an NSTextField. It may be an NSTextView, or a textarea in a WebView, or a Carbon EditText or MLTE control, or some other text editor such as a Qt or wxWidgets text editor. They may even be using an app with a list view that lets them paste text directly into it.

So, there's no programmatic way to directly tell an application “here's some text — paste it, please”. You have to copy it to the general pasteboard and then forge an event that should generally cause the frontmost app to paste. Charlie's suggestion of ⌘V is one way, albeit tricky; the Dvorak layout puts V on another key, while the “Dvorak QWERTY ⌘” layout puts V-with-⌘ (as opposed to V-without-⌘) on the same key as QWERTY's V.

To forge that ⌘V event, look into CGEventTap. You'll need to use the CGEventCreateKeyboardEvent function to create the event itself, and since that function takes a key code, you'll need to look up the proper key code for the V part of the ⌘V combination, which will require going through Text Input Source Services or Keyboard Layout Services, depending on the layout.

You might at this point think of using Accessibility to find the Paste menu item in the Edit menu and send it an AXPress message, but “Paste” and “Edit” are only English's words for those concepts; if you did this, your app would not work in any other language. You could go by order (third menu, sixth menu item), but then your app would not work in applications without a File menu, or without a Redo menu item, or with two Undo menu items (Photoshop). Forging a ⌘V event really is the way to go.

Tannenberg answered 22/4, 2010 at 16:7 Comment(4)
CGEventSourceRef is not working while I have sandboxed my application. Is there any way to solve the problem?Ectoblast
@iPhoneDv: You should ask a separate question with more information about what you're doing and what problem you encountered.Tannenberg
Here's a non-broken link to KeyboardLayoutServices documentation: developer.apple.com/legacy/library/documentation/Carbon/… (Of course, won't this still fail if the user has disabled or changed the keyboard shortcut for pasting?)Davis
All the old links are broken now. Any new Cocoa API to achieve these pasting on the front most app?Irresistible
S
8

Here's some working code to post the ⌘+key event (assuming a known keycode):

// some common keycodes
#define KEY_CODE_x ((CGKeyCode)7)
#define KEY_CODE_c ((CGKeyCode)8)
#define KEY_CODE_v ((CGKeyCode)9)

void DCPostCommandAndKey(CGKeyCode key)
{
    CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);

    CGEventRef keyDown = CGEventCreateKeyboardEvent(source, key, TRUE);
    CGEventSetFlags(keyDown, kCGEventFlagMaskCommand);
    CGEventRef keyUp = CGEventCreateKeyboardEvent(source, key, FALSE);

    CGEventPost(kCGAnnotatedSessionEventTap, keyDown);
    CGEventPost(kCGAnnotatedSessionEventTap, keyUp);

    CFRelease(keyUp);
    CFRelease(keyDown);
    CFRelease(source);  
}
Smelly answered 2/12, 2010 at 10:30 Comment(2)
There are apps in the appstore that can actually paste data to another app by clicking items in a table. Wondering how they do that ..Secondguess
@cocoa coder They probably are not sandboxed. Apps that were in the store before July this year are allowed to remain unsandboxed.Smelly
P
0

Generally the only way is to write it to the NSPasteboard and then switch to another app and use some Carbon functions to press "Command-V"...

Pollinize answered 21/4, 2010 at 8:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.