Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Clipboard access #31

Open
MaKleSoft opened this Issue Feb 22, 2012 · 21 comments

Comments

Projects
None yet
4 participants

Support for reading from and writing to the clipboard would be awesome.

Contributor

liamks commented Feb 22, 2012

Once my file api pull-request is accepted I'll tackle this (it should be easy). I was thinking of the following api:

macgap.clipboard.read()
macgap.clipboard.write('asdf')

//OR

macgap.app.readClipboard()
macgap.app.writeToClipboard('asdf')

That would be great. Thanks!

Any news on this? If not, can maybe anyone maybe give me some quick instructions on how to implement something like this myself?

Contributor

liamks commented Feb 29, 2012

I'm working on this right now, I'll provide an update when I'm done.

Contributor

maccman commented Feb 29, 2012

liamks are you sure there isn't already a 'paste' event?

Contributor

liamks commented Feb 29, 2012

It looks like there might be: http://www.quirksmode.org/dom/events/cutcopypaste.html

It looks like it would only access the clipboard within a single window - would that be sufficient to avoid having to add this feature?

Actually what I am looking for is not a way to capture when a user copies or pastes data (e.g. via cmd + v) but to programmatically write or read data from/to the clipboard. Not sure if that is clear here. @liamks If you do implement it, could you please also update the macgap generator project? I'm having trouble with compiling xcode projects right now. (Which is part of the reason why I havent tackled this myself yet) Thanks!

Contributor

maccman commented Feb 29, 2012

I'm not sure it's a good idea to separate clipboard access from ctrl c - what's the use case?

There's a lot of use cases, actually. The most straightforward would be a clipboard manager. In my case I'm trying to give the user a convenient way of copying data from a password manager to the clipboard. Simply tap on a field to copy it to the clipboard. There is an API for that in Chrome and Titanium Desktop and I'm sure in most other web app packagers, too, so I don't see why there shouldn't be one in MacGap.

Contributor

maccman commented Feb 29, 2012

Ok, interesting. Perhaps we should copy Titanium's API for writing.

Contributor

liamks commented Mar 6, 2012

@maccman what portion of Titanium's API should I set out for?

http://developer.appcelerator.com/apidoc/mobile/1.7.1/Titanium.UI.Clipboard-module

I can most likely give it a shot this Wednesday. Next week I'm away, but I'd like to get this resolved soon.

getText and setText would be sufficient for me. Though I dont understand why you need to look at the Titanium API at all. Can't you find everything that you need here? https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/PasteboardGuide106/Introduction/Introduction.html

Contributor

maccman commented Mar 6, 2012

Yes, @MaKleSoft's right - we should follow the webview API.

I havent noticed this before but normal copy and paste from inputs doesnt work either.

Contributor

liamks commented Mar 8, 2012

It appears that the WebKit API already works within MacGap.

document.body.oncopy = function(e){
  e.preventDefault();
  console.log(e.clipboardData.setData("text/plain","asdf"))
}

The above will intercept a copy event and write "asdf" to the clipboard (and print true to the console).

More info:
http://www.javascriptbank.com/javascript/article/how-to/accessing-the-system-clipboard-content-with-javascript/preview/en/
https://developer.apple.com/library/safari/#documentation/appleapplications/Conceptual/SafariJSProgTopics/Tasks/CopyAndPaste.html
http://almaer.com/blog/supporting-the-system-clipboard-in-your-web-applications-what-a-pain

@liamks I don't think we understand each other. I dont want to intercept the copy or paste event. That would require the user to do a cmd + c or cmd + v.What I want to do is to manipulate the clipboard contents at ANY time, e. g. when the user presses a button. Now I've allready figured out the copying and pasting portion of the code. For example the obj-c function for writing a text to the clipboard would be

- (void) setClipboard:(NSString*)text {
    NSPasteboard *pasteboard;
    pasteboard = [NSPasteboard generalPasteboard];

    NSInteger changeCount = [pasteboard clearContents];

    NSArray *objectsToCopy = [NSArray arrayWithObjects:text,nil];;
    [pasteboard writeObjects:objectsToCopy];
}

The only thing I can't figure out is how to create a bridge between the javascript call (e.g. macgap.app.setClipboard()) and the obj-c function. If anybody can explain to me how that works then I'll be happy to implement it myself.

Also, as I mentioned before, copying and pasting via cmd + c and cmd + v doesn't work for me at all (the oncopy event doesn't get fired, either). Can you confirm this?

Contributor

liamks commented Mar 9, 2012

cmd + c and cmd + v work fine for me, that's how I was able to test the above code. The reason I posted the above code was not because I misunderstood you but because Webkit's API is entirely event based for copy and paste (as far as I can tell). In Internet Explorer one can modify the clipboard without events, but it appears that the only way to access the clipboard is through events in Webkit. What your asking for is a deviation from Webkit, which may be fine, but I wanted to explore native solutions first. For instance can you trigger the 'oncopy' event within your button/link click handler? If so then you don't need the objective-c code.

On a side node to bridge the gap between obj-c and javascript look at the classes within Classes/Commands, Then to bridge one of those classes look at 'WebViewDelegate.m' and add line like:

    if (self.clipboard == nil) {
        self.clipboard = [Clipboard new];
    }

Make sure you have @synthesize clipboard; at the top of the .m file and @property (nonatomic, retain) Clipboard *clipboard; in the .h file.

There actually is a way of doing it in webkit itself, albeit a rather hacky one. To write something to the clipboard you can use a hidden input element, fill it with the desired text, put focus on it and then call

document.execCommand("copy");

The same thing works with

document.execCommand("paste");

Unfortunately this does not seem to work in Macgap. Maybe you just have to change some parameter in the webview object to make this work, but I just don't know enough objective c to investigate this.

Its weird that normal copying and pasting works for you but not for me. Maybe it has something to do with the fact that I'm compiling the project on Lion using XCode 4.3? Or could there be any other reason?

Thanks for the directions! Say I simply want to add the functions to the macgap.app namespace, would I just need to add the corresponding methods to the App class then? Because that hasn't worked for me last time I tried.

Contributor

liamks commented Mar 9, 2012

If you plan on adding it to macgap.app then you'll also need to make modifications to the + (NSString*) webScriptNameForSelector:(SEL)selector method in App.m. Also make sure that you include the signatures of the methods that you are adding to the header file (App.h) to make them public.

Contributor

Macmee commented Sep 30, 2012

Has there been any progress with this? Is there a way to copy something to the user's clipboard using a function call within javascript?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment