Show/hide Finder, and create new window if none exist via AppleScript - applescript

I'd like to create an AppleScript to trigger via key command in Keyboard Maestro that allows me to toggle showing or hiding the Finder window(s) directly. And if when toggling to show the Finder, if there are no existing windows, create one and open it up to my home directory.
The following AppleScript works. However, there seems to be a race condition between activating the finder and detecting if there are any open windows with if not (window 1 exists), hence the delay 0.5.
The problem (which I think is a race condition in detecting the presence of an existing Finder window) results in this script frequently creating new Finder windows when one already existed. The if not (window 1 exists) doesn't always get it right.
Any thoughts, tweaks, or affirmations that this is just the way it is would be appreciated!
tell application "System Events"
set activeApp to name of application processes whose frontmost is true
if ((activeApp as string) is equal to "Finder") then
set visible of process "Finder" to false
else
tell application "Finder"
activate
delay 0.5
if not (window 1 exists) then
make new Finder window
set thePath to POSIX file "/Users/jon"
set the target of the front Finder window to folder thePath
end if
end tell
end if
end tell

Please try this simpler syntax, it uses only Finder terminology
tell application "Finder"
if frontmost then
set visible of process "Finder" to false
else
if (count windows) is 0 then reveal home
activate
end if
end tell
Edit:
To run a Keyboard Maestro macro, open Keyboard Maestro Editor, select the macro and then select Copy as > Copy UUID from the Edit menu.
Then in AppleScript write
tell application "Keyboard Maestro Engine" to do script "<Script-UUID>"
replacing <Script-UUID> with the copied real UUID

Ultimately I needed to activate Finder before running the count windows command or I'd get inconsistent window counts. Sometimes it'd be 0 even when there was a window open already. This code is working well for me so far.
tell application "Finder"
if frontmost then
set visible of process "Finder" to false
else
activate
if (count windows) is 0 then
open home
tell application "Keyboard Maestro Engine" to do script "<Script-UUID>"
end if
end if
end tell

Related

With Applescript I need to use System Events to navigate a Finder Window that opens within an application

I'm currently writing some Applescript to import some material into software which doesn't have much applescript support and virtually no documentation on Applescript. The two methods are to somehow adapt this script to work:
on adding folder items to this_folder after receiving these_items
try
tell application "Isadora"
import media into document 1 from these_items
end tell
on error msg
display dialog "Error importing file into Isadora: " & msg
end try
end adding folder items to
However when I try to use "import media into document 1 from ________" I always get an error, in every incarnation of that combination.
My second approach then is using System Events to navigate through the menu bar to import everything. When I get to the import part of things where I can navigate and select the files, a finder window pops up. My question is:
How do I navigate this finder window within the application? This is like the inception of scripts. A finder window within a program.
I tried a few simple things like calling the front window of finder to navigate somewhere and what not. The current script that gets me to the import window is:
tell application "IsadoraCore"
activate
delay 2
tell application "System Events"
click menu bar item "File" of menu bar 1 of application process "IsadoraCore"
click menu item "Import Media..." of menu "File" of menu bar item "File" of menu bar 1 of application process "IsadoraCore"
end tell
end tell
Any help would be appreciated!
I would guess the "import media" window is a Finder window where you select a file to import. This window is easy to handle. To select the file you must have the posix path of the file. In that window if you keystroke "shift-command-g" then you get a text field where you can keystroke the posix path. For example, let's say I want to open a file in TextEdit. The file is on my desktop with the name test.txt. I can do this...
set filePath to (path to desktop as text) & "test.txt"
set posixPath to POSIX path of filePath
set aShortDelay to 0.5
tell application "TextEdit" to activate
delay aShortDelay
tell application "System Events"
keystroke "o" using command down -- bring up the "open dialog window"
end tell
delay aShortDelay
tell application "TextEdit" to activate
delay aShortDelay
tell application "System Events"
keystroke "g" using {shift down, command down} -- bring up the "goto folder sheet" in the open dialog window
delay aShortDelay
keystroke posixPath -- enter the posix file path
delay aShortDelay
keystroke return -- dismiss the "goto folder sheet"
delay aShortDelay
keystroke return -- dismiss the "open dialog window"
end tell
Notice I have delays after every command. That is good practice when you're using this type of scripting. You don't want the code to run faster than the computer can perform the tasks so the delay gives the computer time to keep up with the code. Notice that I use a variable for the delay. This way I can play with aShortDelay making it longer or shorter as needed to make the script run properly.
Good luck.
Aren’t you asking Isadora to import a list of folders? Perhaps it can only handle one folder at a time?
I don’t have Isadora to test, but you might try this:
on adding folder items to this_folder after receiving these_items
try
tell application "Isadora"
repeat with the_item in these_items
import media into document 1 from the_item
end repeat
end tell
on error msg
display dialog "Error importing file into Isadora: " & msg
end try
end adding folder items to

How can I use AppleScript to address dialog box in Ableton Live?

I have a collection of Ableton Live files (extension ".als") that I need to cycle through while playing a show. I'd like to dedicate a keyboard shortcut to launch each one, and had intended to use AppleScript for this.
The issue is that each file gets changed as I go through the process of playing the associated song, so that when I press the keyboard shortcut to launch the .als associated with the next song in my set, Ableton opens the "Save changes before closing?" dialog box (at which point what I want to do is select "Don't Save").
Simply pressing command + D at this point will do the trick, but I'd really like to automate this keypress. I can't seem to figure out how to get applescript to do this. I'm an applescript noob, and clicking the "Open Dictionary" option in AS seems to show that Ableton is not officially a scriptable app.
Any thoughts on this? Here's an example of an AppleScript I've been trying. This starts the process of opening the next .als in my set list, but won't click the "Don't Save" button.
tell application "Finder"
activate
open document file "Song 1.als" of folder "Desktop" of folder "User" of folder "Users" of startup disk
end tell
tell application "System Events"
keystroke "d" using command down
end tell
Interesting!
Finally came across tips that made it work:
Add both the Script Editor and Ableton Live to the Accessibility API:
System Preferences > Security & Privacy > Privacy...
Ignore application responses to continue the script during dialog.
LiveLoader.scpt:
-- open file
ignoring application responses -- don't wait for user input
tell application "Ableton Live 9 Suite" to open "Users:username:Desktop:LiveSet Project:LiveSet.als"
end ignoring
-- use delay if needed
-- delay 0.5
-- skip saving file
tell application "System Events"
set frontmost of process "Live" to true
key code 123 -- left
key code 123 -- left
keystroke return -- enter
end tell
Note:
Consider possible security impact.
Perhaps simply disable apps in Privacy List after use. (Could be scripted ;)
Can now also send mouse clicks, for more creativeness. :)
I know this is old. but in the interest of helping others who might find themselves here... heres what i have done.
use a program call Qlab. the free version will be fine.
make an applescript Cue. go to the 'trigger' tab. select midi trigger. hit the midi key you would like to assign the command too. this cue will now launch when it receives this midi note - even when running in the background.
go to the 'script' tab. copy and paste the script below.
you can make the relevant adjustments for each song. Basically each key will close all current ableton files without saving - as requested. and then launch a specific live set. which ever one you have assigned. in this case, the song 'Less Than Nothing'
the code...
tell application "System Events"
set frontmost of process "Live" to true
keystroke "q" using command down
tell application "System Events" to keystroke (ASCII character 28) --left arrow
tell application "System Events" to keystroke (ASCII character 28) --left arrow
keystroke return
end tell
delay 2.0
do shell script "open '/Users/CamMac/Desktop/Less Than Nothing 2 .als' "

Applescript - Close Pages Document Automatically

I am trying to create a script that will automatically close the frontmost window of Apple Pages.
on run {}
tell application "System Events"
if (window 1 of process "Pages" exists) then
try
tell application "Pages"
--display dialog "Hello World!" --TODO: remove, test code only.
--Keywords I have tried: file, document, window,
close window 1 saving no
end tell
--close window 1 of process "Pages" saving no
on error errMsg
display dialog "ERROR: " & errMsg
end try
end if
end tell
end run
Whenever I run this, it gives me the following error:
ERROR: Pages got an error: window 1 doesn’t understand the “close”
message.
I have looked at this article, and have used the following command:
sudo defaults write /Applications/Pages.app/Contents/Info NSAppleScriptEnabled -bool YES
However, it still fails to work. Any advice?
Details:
System Version: OS X 10.9.1 (13B42)
Kernel Version: Darwin 13.0.0
Pages: 5.0.1
If Pages isn't scriptable, you're kind of out of luck. If it were scriptable, you wouldn't need System Events to close a window; that kind of functionality is usually included in a scriptable app's dictionary.
System Events can help with apps that aren't scriptable, but you have to rely on the actual UI. But if that's the solution, you can't use tell application "Pages" for the inner block (like you have it); you have to use:
tell process "Pages"
If you go that route, now you have to use either the close button on window 1 or use the close menu command. Something like:
activate application "Pages"--note that this will probably be NECESSARY (if it's not frontmost, it prob won't work)
tell application "System Events"
tell process "Pages"
click menu item "Close" of menu "File" of menu bar item "File" of menu bar 1 of it
end tell
end tell
BUT then you have to come up with the problem of what happens if the window hasn't been saved (has been modified) -- which in a scriptable app uses the construction you were originally trying. When using System Events, you can do:
activate application "Pages"--note that this will probably be NECESSARY (if it's not frontmost, it prob won't work)
tell application "System Events"
tell process "Pages"
click menu item "Close" of menu "File" of menu bar item "File" of menu bar 1 of it
delay .5
keystroke "d" using command down
end tell
end tell
But then again how do you make the script smart enough to know if the window has been modified or not? Or maybe you use System Events to see if the window has been killed after the close command, and if it hasn't, it does the keystroke thing. This kind of thing can be done by doing something like:
activate application "Pages"
tell application "System Events"
tell process "Pages"
set frontMostWinName to name of window 1
click menu item "Close" of menu "File" of menu bar item "File" of menu bar 1 of it
tell me to delay 0.5
if exists window 1 then
if name of window 1 = frontMostWinName then keystroke "d" using command down
end if
end tell
end tell
I don't have Pages, but this works with another non-scriptable app, Bean (although I should mention that Bean uses tabs, and I had to move a tab to a window to get this to work*, and I don't know how Pages works in this regard).
[EDIT: *actually, this is not true; this works in Bean regardless of tabs/windows]

AppleScript Clicking On dialog box

In PCSX, (ps1 emulator), i'm trying to automate the steps to play an iso. So, i'm doing this:
set thepath to path to me
set thesecondpath to POSIX path of thepath
set thethirdpath to "Contents/PSX/ROMS/img.bin"
set thefourthpath to "/Contents/PSX/PCSX.app"
set thefifthpath to thesecondpath & thefourthpath
set theultimatepath to thesecondpath & thethirdpath
tell application thefifthpath
activate
tell application "System Events"
keystroke "i" using {command down}
keystroke theultimatepath
delay 1.0
tell process "PCSX"
click button "Go"
end tell
key code 53
end tell
end tell
Running from the AppleScript Editor won't work. I made it to work running from the App it creates. PCSX and the img.bin are inside the Generated Package.
after pressing command+i, it opens a "Go to the folder" dialog, and i need to click Go and then Open
But doing this way, it won't find the dialog box. What am i doing wrong?
If Go and Open are the default buttons, try:
tell application "System Events"
keystroke return
delay 2
keystroke return
end tell
Although I don't have PCX installed here is an example of how to click the Go button from Finder's Go to Folder command.
tell application "System Events"
tell process "Finder"
click button "Go" of window "Go to Folder"
end tell
end tell
The reason your script won’t work from AppleScript Editor is that the “me” in “path to me” is the application that ran the AppleScript. When you are running the AppleScript in AppleScript Editor, that means AppleScript Editor itself. When you saved your AppleScript as a script application and ran it, the path to me pointed to your script application, because it was running its own AppleScript.
Also, this is incorrect:
tell process "Finder"
click button "Go" of window "Go to Folder"
end tell
The “Go” button is not on the window “Go to Folder.” It’s on a sheet which is attached to a Finder window which has the name of whatever folder is currently being viewed. So you have to describe the button as being on sheet 1 of window 1:
tell application "System Events"
tell process "Finder"
click button "Go" of sheet 1 of window 1
end tell
end tell
… but keep in mind that in another app, a similar looking button on a sheet may be on sheet 1 of group 1 of group 2 of window 3. UI Scripting is complicated.

AppleScript -> Activate window of a non-scriptable application

I have opened 2 "Finder" window A & B, A is in the front while B underneath, the following snippet brings B to the front the topmost:
tell application "Finder"
activate
activate window 2
end tell
But for applications that do not support scripting, the code just mentioned won't help.
Any ideas for activating a window of non-scripting application.
You can usually turn to system events in these cases. System events knows about the windows of running processes and you can usually manipulate those windows. Something like this will show you some of the things you can do. Just play around with the code and see if you can do what you want.
tell application "System Events"
tell process "Whatever"
properties of windows
end tell
end tell
EDIT: One of the properties of a window is its "title". So you might be able to use that. This approach uses the fact that many applications have a "Window" menu and under that menu many times the name of the windows are listed and you can switch windows by clicking the approprite menu item. So something like this might work... my example uses TextEdit.
tell application "TextEdit" to activate
tell application "System Events"
tell process "TextEdit"
set windowTitle to title of window 2
click menu item windowTitle of menu 1 of menu bar item "Window" of menu bar 1
end tell
end tell
What is your definition of non-scriptable? Just about everything is scriptable to some degree, but for the sake of an example lets use, does not contain an AppleScript dictionary, e.g. AppName.sdef within its application bundle.
For example, the macOS included Stickies application does not contain the Stickies.sdef file, and when trying to add it to the Library in Script Editor is says, "Unable to add the item because it is not scriptable."
In a case such as this, then System Events is needed to talk to the application process, e.g.:
Example AppleScript code:
if running of application "Stickies" then
tell application "System Events"
tell application process "Stickies"
set frontmost to true
if exists window 2 then ¬
perform action "AXRaise" of window 2
end tell
end tell
end if
Notes:
I've included error handling in the example AppleScript code, which can be removed if you prefer.

Resources