I’m a heavy user of Screen Sharing in Mac OS X. When I’m in the office, I sit at a workstation with my trusty IBM Model M keyboard, 27″ iMac, Microsoft Wheel Mouse Optical and Apple Magic Trackpad. Off to the side is my mobile environment, the MacBook Pro, open and running, with its display mirrored in a Screen Sharing window on the iMac. At the desk, I do most of my work on the iMac, with the MacBook limited to less-portable applications (Mail, iTunes, and iPhoto) and often displaying a full-screen TweetDeck board. But copying and pasting content between these two environments was a serious multi-click pain until I automated it with AppleScript and Speech. Here’s how I did it.
Update: If you want to do this using a keyboard shortcut instead of speech recognition, see my followup piece, How To Assign Keyboard Shortcuts To AppleScript and Automator Actions
Separate Clipboards
Each Mac maintains its own universal clipboard, and each application interacts with this in its own way. Most applications use similar commands (command-c, command-v, etc) and I use these many times an hour, moving text, addresses, pictures and the like between applications.
But this all breaks down when using two Macs at once. The clipboards are not shared across the network (though some third-party applications allow this), setting up a roadblock to productivity. Since I usually have a Screen Sharing session open, I usually use that application’s “Get Clipboard” and “Send Clipboard” function to move clips between Macs. But these are buried in the “Edit” menu of that one application, forcing me to switch to it, move the pointer to select “Edit”, move it again to select the correct item (“Get” or “Send”), reactivate the original application, and finally do what I want with the clip.
After performing this dance literally hundreds of times a day for months, I decided to try to automate it. First, I thought to bind a keyboard command shortcut to it in System Keyboard Preferences. But this failed miserably – keyboard shortcuts only work with the active application, and Screen Sharing sends all keystrokes through to the remote machine.
Then I thought of the Mac OS X Speech function. It allows an AppleScript script to be run from any application. If I could script Screen Sharing’s Edit menu, I’d have solved about 90% of my issues: I still couldn’t run the script from within a Screen Sharing session, but I could run it from anywhere else.
AppleScript and Screen Sharing
AppleScript is a clever scripting language, allowing most Mac OS X applications to be automated using readable commands. It reminds me somewhat of Microsoft Visual Basic, but is integrated with the operating system. Some applications allow extensive scripting, while others (like Skype) offer a simple command for API access. Then there are those like Screen Sharing that have no AppleScript documentation at all.
Mac OS X comes to the rescue here, allowing AppleScript access to all GUI functions in any application through the “Universal Access” Preferences pane, but these aren’t well-documented. I downloaded the trial version of UI Browser to discover the proper GUI string to access the “Send Clipboard” and “Edit Clipboard” functions in Screen Sharing. Amazingly, it works! I now have an AppleScript to trigger these commands.
But the script includes a statement activating Screen Sharing, so it leaves me there when I’m done rather than the application I was in to begin with. I located a method of determining the current running application (a surprisingly-complex one – where’s the simple command, Apple?) and added a statement reactivating it at the end. Voila! My script was complete!
I saved two scripts to Speech’s Speakable Items folder, one for “get” and another for “send”, and am now able to speak a command to copy items in and out of my remote computer’s clipboard. Excellent!
The Recipe
Here’s what you have to do to duplicate my success:
- Select “Enable access for assistive devices” in the Universal Access pane of System Preferences
- In the “Speech Recognition” section of the Speech pane of System Preferences, turn on “Speakable Items”
- While you’re there, make sure “Global speakable items” is selected under “Commands”
- Open AppleScript Editor and paste in the following script. Save it as “~/Library/Speech/Speakable Items/Screen get clip”
set front_app to (path to frontmost application as Unicode text) set AppleScript's text item delimiters to ":" set front_app to front_app's text items set AppleScript's text item delimiters to {""} --> restore delimiters to default value set item_num to (count of front_app) - 1 set app_name to item item_num of front_app set AppleScript's text item delimiters to "." set app_name to app_name's text items set AppleScript's text item delimiters to {""} --> restore delimiters to default value set MyApp to item 1 of app_name activate application "Screen Sharing" tell application "System Events" tell application process "Screen Sharing" click menu item "Get Clipboard" of menu 1 of menu bar item "Edit" of menu bar 1 end tell end tell activate application MyApp
- Create another AppleScript containing the following content and save it as “~/Library/Speech/Speakable Items/Screen send clip”
set front_app to (path to frontmost application as Unicode text) set AppleScript's text item delimiters to ":" set front_app to front_app's text items set AppleScript's text item delimiters to {""} --> restore delimiters to default value set item_num to (count of front_app) - 1 set app_name to item item_num of front_app set AppleScript's text item delimiters to "." set app_name to app_name's text items set AppleScript's text item delimiters to {""} --> restore delimiters to default value set MyApp to item 1 of app_name activate application "Screen Sharing" tell application "System Events" tell application process "Screen Sharing" click menu item "Send Clipboard" of menu 1 of menu bar item "Edit" of menu bar 1 end tell end tell activate application MyApp
- Enjoy!
This may give you ideas for other AppleScript items. I know it sparked my creativity! Here’s a bonus AppleScript to set my Skype status to “Do Not Disturb”:
tell application "Skype" send command "SET USERSTATUS DND" script name "Set Skype Status Do Not Disturb" end tell
Since Skype has an AppleScript bridge (“send command”) to their API, there’s no need to mess with application switching! I wish more applications exposed their innards like this!
Craig Morgan says
You need to investigate Teleport (http://abyssoft.com/software/teleport/), which is a small utility to enable one keyboard and mouse to drive two or more macs, drop the MBP next to the iMac and sync them up, then you get clipboard sync, drag and drop file transfer and one interface to both systems.
Invaluable for making your mobile a part of your larger desktop experience. Since we switched to iMacs in the desktop, we’ve used Teleport to smooth over the joins when a MBP is brought in.
Make sure to sort the network addresses (ie. fixed DHCP allocation or fixed IP via locations) and its very stable, not had any significant glitches in 18 months on multiple desks here. Extremely highly recommended!
Don’t think I could work without it now, as it releases the maximum screen real-estate as well, I still use screen sharing (well actually JollysFastVNC because its faster) but only for the server access and/or access from iPad.
Try it, you’ll like it …