Can I manipulate the location of a dialog displayed through osascript? - macos

I've been playing around with various UNIX commands and came across this one to display a dialog:
osascript -e 'tell app "System Events" to display dialog "Hello World"'
I'd like to change the position of the dialog. For most commands, I can just use man command to figure out how to do something for that command. However, man osascript doesn't tell me how I can change the position of the dialog box. How can I modify the command to put the dialog in a different place?

First, to get help with applescript just open the AppleScript Editor application and look under the help menu. The applescript language guide is in there and other tools. Also under the file menu is "Open Dictionary" which will show you the specific commands for applications.
To see the information about display dialog, open the dictionary of StandardAdditions and use the search field to find the command.
To answer your question, no, you cannot specify the location of a "display dialog" window. There are no parameters in that command for positioning the window, as you'll see in the dictionary. In addition, no other commands will help you either because you can't issue other commands while the dialog window is open because the code pauses while the window is open waiting for a response from the dialog window (like when you press the OK button).
If you need to set the position of a window to display information to a user then you'll need to use some other dialog tool other than "display dialog". You could create your own window in cocoa or google for some alternatives like cocoaDialog, SKProgressBar, and Notification Center.

There is a round-about way to go about this, which may be useful in some scenarios. Try the following:
on displayMessage(msg)
tell application "Finder"
activate
set c to (count windows)
ignoring application responses
display dialog msg with icon note
end ignoring
end tell
tell application "System Events"
tell application process "Finder"
repeat until ((count windows) > c)
delay 0.2
end repeat
set position of window 1 to {0, 22}
end tell
end tell
end displayMessage
displayMessage("I'm over here!")
Credit for this little script goes to a post here.
In implimenting this myself, I found it was limited to whether or not the application that is being called (Finder, in the example) supports the count window command (or whether it has API support at all).
I realise I've dragged up a question from 2013. I am posting this answer here in case it is of use to the OP or, more likely, someone else with a similar question.

Related

How do I tell if the frontmost window is a NSOpenPanel / file open dialog in MacOS using Applescript?

I'm trying to automatically change the directory of the frontmost "file open dialog" or NSOpenPanel dialog with AppleScript, whether that window is part of any application. The idea is that I hit a hotkey, and it will control that dialog to switch to a particular folder.
I can't seem to find out how to find the attributes of a window that would filter it for a "file open dialog". Using the Accessibility Inspector I can find that the "class" is NSOpenPanel. How can I get the class of a window using Applescript?
If you run the following AppleScript, you can see the properties of the foremost window:
tell application "anApp" to activate
delay 1
tell application "System Events"
tell process "anApp"
properties of window 1
end tell
end tell
The app has to be active to see the properties of the windows; You will not get consistent results if the app is in the background.
The NOOpenPanel ought to be recognizable by testing for some combination of the following properties:
role description:"dialog"
title:"Open"
subrole:"AXDialog"
name:"Open"
description:"dialog"
Personally, I'd probably rely on name and role description, which should be the same anytime an app throughs up a standard 'Open' dialog. 'Save' dialogs will be the same, except that title and name will be 'save' rather than 'open'.
If you have an app that presents a open or save sheet (a sub window attached to the titlebar), not a separate dialog, then you'll shift things a little. The AppleScript to get the properties looks like this:
tell application "anApp" to activate
delay 1
tell application "System Events"
tell process "anApp"
tell window 1
properties of sheet 1
end tell
end tell
end tell
and the relevant testable properties are as follows:
accessibility description:"save"
role description:"sheet"
role:"AXSheet"
description:"save"
You'll probably have to add logic to test whether the front window has a sheet, which should distinguish between dialogs and sheets.
Some apps use non-standard open/save dialogs, and you'll have to account for them on a case-by-case basis. There's no magic bullet for that.

`AXFocusedUIElement` <- does not get focused element (folder, file), it points to `Finder` menu

trying to reproduce right-click context menu on my Mac.
I found such an article:
https://beebom.com/how-right-click-using-keyboard-mac/
I did accordingly but when I click my keyboard shortcut I get Finder menu not a currently selected file/folder menu.
This is an apple script used,
on run {input, parameters}
tell application "System Events" to set frontApp to name of first process whose frontmost is true
tell application "System Events"
tell application process frontApp
set _selection to value of attribute "AXFocusedUIElement"
tell _selection to perform action "AXShowMenu"
end tell
end tell
return input
end run
Spent hours trying to get this basic and obvious to every Windows user functionality to work, lost of time and very frustrating!
I think code is correct, maybe there is something specific on my computer that stops it from working as expected?
Please help :-)
Not sure i understood what is actually not working for you, but i had problem to reproduce the same script, once i wrote it in Automator.app i tried to press "play" button to see if the script was working and it was telling me something like "syntax error, can't get attribute AXFocusedUIElement of application process Automator" (from memory, not sure it's exactly what was written)
and struggled for a while as well untill i realised there was a pop window that i didn't see, saying me that "automator wants permission to control this computer using accessibility features (this thing in the system preference, security and privacy, privacy, accessibility), so i opened, there was a list of apps allowed to control my computer, i ticked Automator.app and after that it worked
Then every app that i was trying to do a right click was showing me the same pop up and i had to do the same for each one (safari, finder etc...)
And then it worked
Hope might help you!
Encountered same issue.
Allow 'Finder' to control computer at System Preferences>Security & Privacy>Privacy>Accessibility.
Worked for me

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 API documentation

I want to make an AppleScript to automate the task of switching resolution on the MacBook Pro Retina.
Searching the internet for "applescript system preferences" I came across a page where some preferences are show. Being the scaled resolution thing new, it is not documented.
This brings to a bigger problem I have with AppleScript (mind that apart from copy-pasting something I never really programmed in it). Where is the documentation that tells me, for instance, tha the System Preferences object is actually called "System Preferences", that it has objects called "pane", that they have an id and that the expose id is "com.apple.preference.expose"?
It seems like there must be some sort of "secret" documentation for every program, and they must be huge, mapping all the object hierarchies and possible actions. In the end, AppleScript core is minimal and all you do is manipulate such programs. But where are they documented?
Ok this is how it works:
Where is the documentation that tells me, for instance, tha the System Preferences object is actually called "System Preferences"
The object is called "System Preferences" because that is the exact name of the application. What you're telling Applescript with this is I want to speak to the application named System Preferences (tell application "System Preferences" ...)
that it has objects called "pane"
Now it's the fun part. If you open your Library window (in Applescript Editor, Window > Library) you will see that there is a collection of scriptable applications available, the thing is that 'System Preferences' is not there. So let's find it: File > Open Dictionary > System Preferences. Now you got a window that both lets you drill down all available classes/commands/properties of the app and also a split window with relevant documentation (if you click on SSystem Preferences you'll see Cpane and by clicking on this you'll see Pid among others). The id of the pane for once more would be the name of the pane (lowercased and concatenated - I'm still looking into documentation for a strict definition on this). I hope that this will get you started.
S:Suite
C:Class
P:Property
(the 'C' inside a circle stands for Command)
You're exactly right. Each program does have its own documentation for applescript. It's called its applescript dictionary. You can see the dictionary of any application by any of the following...
1) in AppleScript Editor, under the File menu, choose "Open Dictionary...". You can select an application from there and it will show its dictionary.
2) drag/drop an application onto the AppleScript Editor's icon.
3) there's a list of frequently-used dictionaries for fast access. Under the Window menu in AppleScript Editor choose "Library". You can double-click an application in that list. You can also modify that list to contain dictionaries that you want in the list.
Good luck.
You can ask AppleScript to tell you the ids for each of the panes.
tell application "System Preferences" to get the id of every pane
This is particuarly handy as it will tell you the ids for any third-party preference panes you have installed. For instance, I was able to work out that the pane for my Microsoft Natural keyboard is called com.microsoft.microsoftkeyboard
I haven't really explored this much yet, but I would expect that similar syntax exists to identify the objects within any scriptable application.
I have another issue but you can have a look to my question as there is some hint in my script about your issue
HOW TO: display a check mark, disable a menu item, refresh a menubar
For instance:
tell application "System Preferences"
reveal anchor "displaysDisplayTab" of pane id "com.apple.preference.displays"
end tell
This code should directly put you in the resolution preferences of the system preference.
Then you can make a code to recuperate all the UI elements of the pane so that you now which action to trigger. Something like this should also work:
tell application "System Events"
tell application process "System Preferences"
set frontmost to true
delay 1
return every UI element of front window
return name of every UI element of front window
end tell
end tell
Hope it helps

Simple GUI scripting question

I am trying this simple GUI script to open a new window of Safari:
tell application "Safari"
activate
end tell
tell application "System Events"
tell process "Safari"
try
tell menu bar 1
tell menu bar item 3
click menu item 1
end tell
end tell
on error theError
display dialog ("An error occurred while performing requested action" & theError) buttons "OK" default button "OK"
end try
end tell
end tell
but it is giving this error message:
Expected end of line but found """
Can anyone suggest me where I may be wrong?
Thanks,
Miraaj
Wow, that was weird. Your script broke AppleScript Editor. After running your script and it not working... I tried to recompile the script and then the error you posted starting showing up. So somehow your code caused AppleScript editor to break and thus the error. I had to quit and relaunch AppleScript Editor to get it working again.
I used the application UI Browser and found the problem. Your reference to the menu item was wrong. There's an extra menu in there that we can't see... and you didn't reference that extra menu. This is the problem with gui scripting. And even if a gui script works it may break at some future date as an application is updated. As such avoid gui scripting if at all possible.
Anyway, here's what your code should look like...
tell application "Safari"
activate
end tell
tell application "System Events"
tell process "Safari"
try
tell menu bar 1
tell menu bar item 3
click menu item 1 of menu 1
end tell
end tell
on error theError
display dialog ("An error occurred while performing requested action " & theError) buttons "OK" default button "OK"
end try
end tell
end tell
EDIT:
As I mentioned in my comment below, if you can't find a native command from an application's dictionary, the next most reliable method is using keyboard shortcuts. Most menu items have them. For example, if I wanted to open a new tab in a window that menu item has the keyboard shortcut command-t. So we can use that like this. Note there is a native command to open a new tab without using keystrokes, I'm just showing this as an example.
tell application "Safari" to activate
tell application "System Events"
keystroke "t" using command down
end tell
end
Keyboard commands don't usually change between application updates whereas gui commands often do because programmers redesign their interface in updates... and when that happens gui scripting goes haywire. One of the gotcha's with both gui scripting and keystrokes is that sometimes the script goes too fast and these techniques can't keep up with the speed of the program, so they often error. When this happens you need to slow down the script using small delays to allow the interface to keep up with the script.

Resources