Re: how can I copy from another app?
Re: how can I copy from another app?
- Subject: Re: how can I copy from another app?
- From: Jim Thomason <email@hidden>
- Date: Thu, 05 May 2011 11:39:18 -0500
I was finally able to get it to "work".
As others have pointed out, and rightfully so, there be dragons here.
The following all constitutes godawful hacks and abuse of the system.
I'm gonna file a feature request that services should be configurable
with variable input/output so I can chuck this whole mess.
Honestly? The end results are pretty slick, but it's done in a fragile
and brittle way. I'll leave it to other devs discretion if that's
worth the risk in their own apps. For myself, I'm able to make some
assumptions about how my users will interact with my app and where
I'll be copying from that'll allow it to work most of the time. Not
ideal but feasible.
The mess of an applescript that "works" is this:
tell application "%@"
activate
tell application "System Events"
tell application process "%@"
set frontmost to true
keystroke "c" using command down
tell menu bar 1
tell menu bar item "Edit"
tell menu "Edit"
click menu item "Copy"
end tell
end tell
end tell
set fnar to the clipboard
end tell
end tell
set clip_data to (the clipboard) as text
end tell
Yes, that does issue a command-C and follow it by explicitly looking
for an Edit Menu and clicking on a copy command. I could only get it
to work consistently if I issued both. Bugger all if I know.
Further, I had to issue that from a delayed selector with at least a
0.1 second gap, preferably 0.2. Hacks on top of hacks on top of hacks.
So I've already run into hassles because I'm forcing my UI to pause
briefly here. But even worse is that applescript is just dog slow.
Admittedly, I'm running on a several years old 2.4ghz core2 duo, but a
0.6 second (on average) duration for the applescript to execute is
just ridiculous.
It added up to nearly a second pause before the app could do anything
usable, but it also had the side-effect of shifting focus out of my
app and into the calling application, so for that brief second
anything the user tried to do wouldn't go to me and would instead go
to the original app. Bad bad bad.
w/o any way to speed up the applescript (and the original clean(-ish)
script now a steaming mess), I shifted gears to a different approach
and directly simulated the pressing of command-C via a suggestion
found here:
http://stackoverflow.com/questions/2379867/simulating-key-press-events-in-mac-osx
(to spare looking it up, the standard qwerty keycodes for C and V are
8 and 9, respectively)
I still needed to add a 0.1 second delay after sending the fake
keystroke, presumably to give it time to reach the pasteboard, but
other than that it works swimmingly. The 0.1 second pause isn't
noticeable, since it happens before my app appears, and I (so far) am
not having any issues with it.
Of course, this approach opens up a whole different can of worms in
that in addition to being fragile in all the ways the applescript
approach was, it'll break very spectacularly with non-qwerty keyboards
since it's relying upon the raw keycode values, as opposed to just
sending the appropriate character.
I think I'm just gonna add a toggle to turn off the functionality if
the user has a non-qwerty keyboard, at least for now. Presumably, I
can have them explicitly map the keys or otherwise divine them myself,
but man what a nuisance.
Implement any of this at your own risk, and be sure to understand the
consequences of doing it. This is only gonna work with a very narrow
focus.
-Jim....
> On 4 May 2011, at 22:46, Jim Thomason wrote:
>
>> I know this has been asked a bajillion times before, yet here we are.
>>
>> So it turns out that my simple little applescript to copy in from
>> another app was ineffective. Lots more digging around led me to create
>> this:
>>
>> tell application "Xcode"
>> activate
>> tell application "System Events"
>> tell application process "Xcode"
>> set frontmost to true
>> keystroke "c" using command down
>> end tell
>> end tell
>> display dialog (the clipboard)
>> set foo to path to frontmost application
>> display dialog foo
>> end tell
>>
>> which is currently hardwired to Xcode and has a couple of dialogs for
>> debugging purposes. Yes, yes, I know that blissfully assuming that
>> command-C performs a copy operation is less than ideal. Best option
>> I've seen so far.
>>
>> Here's the annoying bit - this works just fine when run from the
>> Script Editor. But when I run it within my app by firing it off via an
>> NSAppleScript call, it fails and copies no text. I even tried saving
>> it as a separate script and invoking it via osascript and had no luck.
>> Again, that works just fine on the command line calling it directly,
>> but not from within the app.
>>
>> I'm utterly stumped. Is there something simple I'm missing? An option
>> to turn on?
>>
>> Is there some other approach I should try instead?
>>
>> -Jim....
>> _______________________________________________
>>
>> Cocoa-dev mailing list (email@hidden)
>>
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>>
>> ________________________________________________________________________
>> This e-mail has been scanned for all viruses by Star. The
>> service is powered by MessageLabs. For more information on a proactive
>> anti-virus service working around the clock, around the globe, visit:
>> http://www.star.net.uk
>> ________________________________________________________________________
>
>
> ________________________________________________________________________
> This e-mail has been scanned for all viruses by MessageLabs.
> ________________________________________________________________________
>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden