Get selected text from any application

Hi, I was just wondering how to get the selected text from any application, just like when you make services in Automator, you can set the input to text from any application.

Any help would be appreciated!

Thanks,
Magikseb

The problem here is that every application is not scriptable and the ones that are use different commands. Therefore there is not a single way to do what you’re asking. Apple can do it through the Services menu because they have access to a lot of things that we don’t have access to through applescript.

However, there’s a descent work-around. Virtually every application has an edit menu and under the edit menu is the command “copy” which uses the keyboard shortcut cmd-c. So you can use that to copy the selection to the clipboard and then get the clipboard in your applescript:

tell application "System Events"
	keystroke "c" using command down
end tell
set theText to the clipboard

One thing you must be careful of… when you keystroke something the keystrokes are sent to the frontmost application. Sometimes when you run an applescript, the script actually becomes the frontmost application and thus the keystrokes are sent to the script instead of the application you’re targeting. You can avoid the problem of your script becoming frontmost by saving the code as a regular script (not an application) and running it from the script menu.

Ok, thanks for the advice and help! :slight_smile:

I used that as part of an ASOC application that runs in the menu bar, with a pop-down menu.

on newTodo_(sender)
        try
            tell application "System Events"
                keystroke "c" using command down
            end tell
            set theText to the clipboard as Unicode text
            
            tell application "iCal"
                tell calendar "Personal"
                    make new todo at end with properties {summary:theText}
                    --Could also have: with properties {summary:theSumm, due date:dueDate, url:theUrl, priority:thepriority}
                end tell
            end tell
        on error (err)
            activate me
            display dialog "An error was encountered: " & return & err buttons {"OK"}
            
        end try
    end newTodo_

But sometimes the code doesn’t work. Like if I launch my application, select some text select the “New Todo” option and it makes the new todo. Then I select something else and it won’t work, it’ll create a new todo with the old text until I press it for a second time.

Any ideas why and how to fix it?

Sure. A couple things…

  1. whenever you use gui scripting techniques like these keystrokes, sometimes you need to put small delays in the script so applications have time to switch, clipboards get set properly etc. So first thing to try is to put a delay before and after each of the commands I showed you. Maybe by slowing the process down it will work more reliably. Also, if other people are using this then you can never be sure about the speed of their computer, so you should error on the safe side with your delays.

  2. you should also check the front application. If your application is the front application then you know the keystroke command won’t work properly. So if your app is frontmost just before you issue the command you can make it not frontmost. Something like this might work:

set myAppName to name of (get path to me)
tell application "System Events"
	set frontApp to name of first process whose frontmost is true
	if frontApp is myAppName then
		set visible of process myAppName to false
	end if
end tell

With something like this, if your app is frontmost then it will hide itself and thus the previous frontmost app will come to the front… then issue your keystroke command.

So between the two you can probably get it working.

This application is probably only going to be for personal use by the way. Also, I have added in info.plist “Application is agent (UIElement)” so that it doesn’t appear when switching applications eg. with cmd-tab.

I added in two short delays and now it works perfectly! Thanks for all the help! :smiley:

Great. Glad to hear it. I thought the delays were the primary reason. Good luck.