looking for a script to Copy current text selection into a new Sticky

This script will be called by a script that waits for a mouseDown on selected text. I’ve got that part working and just need the AS to put the selection into the Sticky.

Thanks.

Why not use the OS built in Service ?? Shift-Command-Y makes a new Sticky from your selection. Granted it doesn’t work in all apps (like Java apps) but it works like a charm in most.

Enjoy!

Thanks for the suggestion, but I find the built in Services to be the most aggravating “feature” of OSX. The never work. Or almost never. Once in a great while I get a response from one of the Services but for the most part the menu selections are all grayed out and they’re just a total waste of space. It looked like such a great idea, but I don’t even try them any more because they’re so flakey. Also, on the occasions that the Sticky Service is available (not grayed out) sometimes it has the Cmd-Shift-Y shortcut shown and sometimes there’s NO shortcut shown. So aside from the fact that it would be crazy-making to use a shortcut that sometimes worked and sometimes not, the biggest turn off for me is that the Sticky Service doesn’t work with Firefox, and that’s the main place I’d be using this shortcut when/if I get it working. So I’m still looking.

This one requires that GUI scripting is turned on (System Preferences > Universal Access, check “Enable access for assistive devices.”)

The script must be saved as an application (for the “keystroke tab using command down” command to work), and the text in question must be already highlighted:

tell application "System Events"
keystroke tab using command down
keystroke "c" using command down
tell application "Stickies" to activate
tell process "Stickies"
keystroke "n" using command down
keystroke "v" using command down
end tell
end tell

Did you try it? When I save that script as an application and then call it with text selected in the front app, it creates a new page in the front app instead of always creating a new Sticky (unless Stickies is the front app, and then it gets it right :wink: ). And then it pastes ALL the text from the front app, i.e. it doesn’t pay any attention to text selections.

For instance if TextEdit is the front app, with some text selected, when I run your script it creates a new TextEdit page and pastes the entire contents of the existing TextEdit page. No Sticky, no selected text.

If Script Editor is the front app, then your script creates a new Script Editor page and pastes in the entire script that was showing.

Yes, I use it often.

I use this script, which I’ve named “Clipboard to New Sticky,” as well as two others: “Clipboard to TextEdit,” and “Clipboard to Script Editor,” each of which I might employ when the situation demands (the only difference among the three scripts in the way they’re written being the name of the target application process).

These scripts work as expected for me when saved as standalone applications, run from the dock, e.g.

I can’t guarantee that “Clipboard to New Sticky” would work if you’re calling it from within a script; you might try adding the following code somewhere in your main script:

tell application "Clipboard To New Sticky"
launch
delay 0.5
run
end tell

I added a half-second delay here to give the original script time to load. Feel free to add your own delay(s) to the original “Clipboard to New Sticky” and adjust any delay time(s) as you see fit. I saved this second script as an app and ran it as a standalone from the dock. It, too, worked – it called the original “Clipboard to New Sticky” and copied the selected text in the frontmost app to a new Sticky note.

Good luck.

That delay was all it needed and now it works great. That was a good guess on the 0.5 sec. because it needs it all. 0.4 doesn’t work. I’m wondering what the delay actually does because even when Stickies is running and doesn’t need extra startup time it still needs that delay. Anyway, problem solved. Thanks a bunch.

BTW, have you come across a good substitute for Stickies? That continual asking me if I’m sure I want to close a Sticky gets really old after a while.

Edit:
BTW2, is there any way those 2 scripts can be merged into one?

I haven’t really looked, but I suppose you could check with Versiontracker.com or MacUpdate.com and see what’s available.

In a nutshell, delays are often necessary in GUI scripting in order to slow a script down to a point where it won’t trip over itself and stall out at run-time. Placement and duration of delay times are key, with success usually found through trial and error.

I would imagine calling a saved GUI AppleScript app from within another script is going to be a dicey situation at best, GUI scripts being as prone to failure as they are. A lot would depend on how elaborate your script needs to be in order to achieve your ultimate goal.

That said, here is an example where the saved “Clipboard to New Sticky” script app can be called from within another script. Let’s say you were interested in copying to a new sticky note the entire contents of a .txt or .rtf file, a file that would open in TextEdit by default. In this example you would choose a text file from the Choose-a-File dialog window, hit the Choose button, and the script would do the rest:

set theFile to choose file with prompt "Please Choose a Text File..." without invisibles
tell application "TextEdit"
	activate
	open theFile
	tell application "System Events"
		tell process "TextEdit"
			keystroke "a" using command down
			keystroke "c" using command down
		end tell
	end tell
end tell
tell application "Clipboard To New Sticky"
	launch
	delay 0.5
	run
end tell

Hi.

Thanks for pointing out this key combination, which is one I hadn’t learnt in eleven years as a Mac User! On a Tiger machine, until the Command key’s released, it cycles through the “foreground” processes in the order they were most recently the frontmost process. (On a Jaguar machine, it follows the Dock order.) Pressing Shift at the same time reverses the cycle direction.

The problem with an ordinary compiled script here (if it’s invoked from Script Menu) is apparently because it’s run by System Events, which, even when it’s frontmost, is a “background” process. It’s therefore ignored by Command-tab, which brings the second-frontmost “foreground” process to the front.

The following works well for me in both script and applet form when invoked from Script Menu on my Tiger machine. (Double-clicking the applet would temporarily bring the Finder to the front and upset the process order.)

tell application "System Events"
	-- Get the process running this script.
	set frontProcess to first application process whose frontmost is true
	-- If it's System Events, this is a compiled script.
	set ImAScript to (frontProcess's name is "System Events")
		
	-- Command-tab to bring the second-frontmost foreground process to the front.
	keystroke tab using command down
	repeat while (frontProcess's frontmost)
		delay 0.2
	end repeat
	
	-- If this is a compiled script, repeat the keystroke to bring the originally frontmost foreground process to the front.
	if (ImAScript) then
		set frontProcess to first application process whose frontmost is true
		keystroke tab using command down
		repeat while (frontProcess's frontmost)
			delay 0.2
		end repeat
	end if
	
	-- Command-c to effect a copy to clipboard.
	keystroke "c" using command down
	delay 0.2
end tell
	
-- Make sure Stickies is running.
tell application "Stickies" to run
tell application "System Events"
	-- Bring Stickies to the front, create a new window, and paste into it.
	set frontmost of application process "Stickies" to true
	keystroke "nv" using command down
end tell

Specifically, the problem is that GUI scripting is scripting-by-proxy. When scripted directly, an application lets the script know when it’s completed each individual command and the script then goes on to issue the next one. With GUI scripting, System Events is told to plant click or keystroke data into the application’s user interface. System Events reports back when it’s done this, but neither it nor the script gets any feedback about if, how, or when the application has responded to the input. The script continues after System Events’s acknowledgement, not necessarily after the application has completed the required action.

Delays give an application time to act before the script continues. But setting them absolutely isn’t a great idea, because the times needed vary from machine to machine and may even vary between runs if something holds up the application for any reason. If a GUI command has a consequence that can be tested for ” such as a new front window, or a changed value, or (as above) a new front process ” then a conditionally repeated short delay can be used. This involves more scripting, but avoids having an absolute time that might be too short or unnecessarily long.

Nigel,

Thanks for your enlightening and informative post. Your explanation of the delay times used in GUI scripting was especially detailed and thorough.

I stumbled upon keystroke tab using command down several months ago after having had no luck getting tell application “System Events” to get name of first application process whose frontmost is true (or some variation of that) to work in a script saved as an application. After Googling using the search string: get name frontmost application applescript, I eventually found what I needed.

I see now that I’m not limited to saving scripts which use keystroke tab using command down as applications. As your script clearly demonstrates, with its ImAScript variable and if statement, they can be saved as compiled scripts and run from the script menu as well. Now I’ve got a folder full of GUI scripts which will be getting a second look… :slight_smile:

Thanks again.

Browser: Safari 525.22
Operating System: Mac OS X (10.4)

Of course, if my brain had been fully functional, I’d have made that:

tell application "System Events"
	-- Get the process running this script.
	set frontProcess to first application process whose frontmost is true
	-- If it's System Events, this is a compiled script.
	set ImAScript to (frontProcess's name is "System Events")

And I shall now edit my post above to this effect. :slight_smile: