Access context menu items by name using AppleScript - macos

I'm trying to use AppleScript to click on context menu items in Logic Pro, preferably by simply providing the name of the menu item. It seems like this should be possible because I'm able to set up keyboard shortcuts for these context menu items using system preferences and providing the name of the command.
For instance, if you right click on the main editing window in Logic, a menu pops up with an option called "Add Audio File..." If I create a system preferences keyboard shortcut for Logic and give it this menu item name, it's able to execute just fine. I'd like to recreate this with a script. I'm familiar with accessing normal menu items using the hierarchy like so:
tell process "Logic Pro"
tell menu bar 1
tell menu bar item "File"
tell menu "File"
click menu item "Save"
but as far as I know, there's no way to access the context menu (right click menu) that I want like this. It seems there should be a way to simply access a non-menu-bar menu item by name since system preferences is obviously able to do so.

Logic pro is not scriptable so my suggestion would be that you set a keyboard shortcut in the system preferences then use system events to use said shortcuts.
for example to enter find mode (assuming there is a find mode since i don't own Logic Pro)
tell application "Logic Pro" to activate
tell application "System Events"
tell application process "Logic Pro"
keystroke "f" using command down
end tell
end tell

I don’t think you need to use the context menus. “Add Audio File…” is available in other parts of the Logic Pro X user interface. If you open the Project Audio window, there is an “Audio File” menu button with an “Add Audio File…” button in it. So this AppleScript will activate the “Add Audio File…” command:
tell application "System Events"
tell application "Logic Pro X" to activate
tell process "Logic Pro X"
tell menu bar 1
click menu item "Open Project Audio" of menu "Window"
end tell
delay 1
tell window 1
click menu button "Audio File" of group 1 of group 1
click menu item "Add Audio File..." of menu 1 of menu button "Audio File" of group 1 of group 1
end tell
end tell
end tell
One thing to keep in mind if distributing a GUI script is that the above script will only work in Logic Pro X running on a Mac set to US English (and maybe other kinds of English) because the names of the menus change if the system is set to another language. What you can do is replace the names in the above script with numbers, which is a totally experimental process, as far as I know. You have to try different numbers and see which continues to work.
So you may be able to replace:
menu button "Audio File" of group 1 of group 1
… in the above script with:
menu button 1 of group 1 of group 1
… and get the same functionality, and the script would work on any Mac. Or you may need to use “menu button 2.” Same goes for the other named items in the above script.
Also keep in mind that the user you distribute this script to has to give System Events permission to control their Mac in the Security pane of System Preferences or this script won’t work. That can be a giant obstacle to distributing GUI scripts. And if you save your script as an Application, you have to digitally sign it or it won’t run on other people’s computers, and that can be complicated.

Related

Shutdown function causes reboot

I'm running Big Sur on a new T480 laptop and porting over a shutdown script from a different laptop running Mojave. The script is assigned to F5 using Quicksilver and can't be simplier.
tell application "System Events"
shut down
end tell
Shutting down works 100% of the time (laptop turns off) but in 70% the laptop reboots and bios starts again. Reboot doesn't happen in Mojave.
Applescript coding isn't my forte so I tried a different script to select Shut Down... from the Apple menu but that produces
"error "System Events got an error: Can’t get menu bar 1." number -1728 from menu bar 1"
tell application "System Events"
tell menu bar item "Apple" of menu bar 1
click
click menu item "Shut Down..." of menu 1
end tell
end tell
Hoping for some guidance to either of the approaches.
The menu bar is not independent, it belongs to an application process, such as the Finder. System Events is a faceless background app that provides access to various functions and attributes, including terms and events for controlling processes.
A menu item can also be a menu, which contains menu items, and so on, so the full hierarchy needs to be used. Another thing to watch out for is that menu item titles typically use an ellipsis punctuation mark rather than periods, so your script can be reduced to something like:
tell application "System Events" to click menu item "Shut Down…" of menu "Apple" of menu bar item "Apple" of menu bar 1 of application process "Finder"
There is also the shutdown command, but you may need to check the bios settings, as the Finder menu, System Events command, and shell utility all essentially do the same thing.

How to click on a button in an app from the status bar with Apple Script

I have see how to click on menu items but this application does not have those. I was wondering how to click on the button Connect
I tried click at {818, 320} but it did not work
Here is the scrip, i was able to open the app with this
tell application "System Events"
tell UI element "Hotspot Shield"
tell menu bar item 1 of menu bar 2
click
delay 2
get the actions of button "Connect"
end tell
end tell
end tell
FWIW One would not normally use tell UI element "Hotspot Shield" rather use tell application process "Hotspot Shield", however, looking at this through Accessibility Inspector, I do not see a way to click the "Connect" button. Even using a Watch Me Do action in Automator, while it will record the process, it won't play it back successfully.
That said, here is a workaround solution that works for me on macOS Mojave using AppleScript and the third-party command line utility Cliclick.
Looking at the cropped screen shot in your OP and using the approximate center of the Connect button to be at 320 for the y axis and using AppleScript to get the position of the menu bar item for use as the approximate x axis, the following example AppleScript code should work for you too.
tell application "System Events" to ¬
tell application process "Hotspot Shield" to ¬
tell menu bar item 1 of menu bar 2
set xPos to first item of (get its position)
click
end tell
delay 0.5
do shell script "/Applications/cliclick c:" & xPos & ",320"
Note that the value of the delay command may need to be adjusted to ensure the Connect button is visible before the click event takes place using cliclick.
Adjust the path to cliclick as needed. I placed it in /Applications just for testing purposes.
The usual caveats, regarding System Preferences > Security & Privacy > Privacy, apply.
I am not affiliated with the developer of Cliclick, just a satisfied user of the product.
Note: The example AppleScript code is just that and does not contain any error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors.

Perform actions on a certain window of the application with AppleScript

I'm building a macOS app for managing locations sent to an iOS device via GPX file in Debug mode, so I need to have to Xcode windows opened for each project. I got an AppleScript which presses Debug -> Simulate Location -> "my gpx file name" for continuous location updates. However, it works only if the window with an iOS project (through which I simulate the location) is frontmost.
I want the script to be able to perform said actions just on a window with a certain name (or rather whose name contains ...), no matter of the hierarchy. I don't want it to be brought to the front or activated, as I might be coding something in a second one while the script runs.
I tried many ways, but with my limited understanding of AppleScript I either get an error (like "Can't locate menu item 1 in bla-bla-bla of the process Xcode) or the window activates and doesn't work in the "background".
repeat while true
tell application "System Events" to tell process "Xcode"
click menu item "MyLocation" of menu 1 of menu item "Simulate Location" of menu 1 of menu bar item "Debug" of menu bar 1
end tell
delay 0.2
end repeat
Is it even possible to perform any action on inactive window? I thought it is since the system lets you scroll without focusing the window.

How to send a menubar app (with no menubar menu items) a command in AppleScript?

I would like to control an application (Shady.app) with an AppleScript command. Unfortunately it doesn't have the standard menubar items such as File, Edit, View, etc.
My goal is to somehow issue a command to the app through AppleScript such that it will toggle the "Turn Shady On" & "Turn Shady Off" command:
NOTE: "Turn Shady On" is the OFF state and it turns to "Turn Shady Off" when Shady is in the ON state.
How can you create a script that toggles this both directions based on it's current state in AppleScript? Or is there a better way than AppleScript to control this programmatically?
This AppleScript will "Turn Shady Off"
tell application "System Events"
try
click menu item "Turn Shady Off" of menu 1 of menu bar item "Shade" of menu bar 1 of application process "Shady"
click menu bar item 1 of menu bar 2 of application process "Shady"
end try
end tell
This AppleScript will "Turn Shady On"
tell application "System Events"
try
click menu item "Turn Shady On" of menu 1 of menu bar item "Shade" of menu bar 1 of application process "Shady"
click menu bar item 1 of menu bar 2 of application process "Shady"
end try
end tell
Assuming it's being run in the status bar.
This will toggle on and off
on toggle()
tell application "System Events"
try
click menu item "Turn Shady On" of menu 1 of menu bar item "Shade" of menu bar 1 of application process "Shady"
end try
try
click menu item "Turn Shady off" of menu 1 of menu bar item "Shade" of menu bar 1 of application process "Shady"
end try
click menu bar item 1 of menu bar 2 of application process "Shady"
end tell
end toggle
toggle()
Save it as an application In ScriptEditor or as a service in Automator or whatever you choose. No need for FastScripts.
The standard way to send a command via short-cut is by:
System Preferences > Keyboard > Shortcuts > App Shortcuts
Click the + and select Shady, then you'll be able to define the short-cut you want to use. Keep in mind you'll need to use ⌘ + Tab to switch to Shady first, then use the short-cut.
If you use an application like FastScripts then you can create a global short-cut without having to switch to the application first which is sometimes better if the app doesn't have focus.
You can do something like this via Keyboard Maestro. Here's an image demonstrating what you want in action:
For the record, I also thought this was so awesome that I also included a way to create a darken/lighten global shortcut:
You've also gotta have "Show Dock Icon" turned on in system preferences for this to work!
See this post on the forums for more info. I'll go ahead and paste it here as well for convenience's sake and to circumvent link rot:
sonicly:
I have an application that runs only as a menubar app. It has a simple command that is essentially "Turn App On"/"Turn App Off". Is there a way to make Keyboard Maestro set up a global hotkey to initiate the command in this app?
I just ran across this topic which addresses your issue: osx - How to send a menubar app (with no menubar menu items) a command in AppleScript? - Stack Overflow
I don't know if you are the OP or not, and I have NOT tested the suggested solution. But maybe it will at least get you started.
sonicly:
So I can enable it to show up on the Dock and with that I was able to set keyboard shortcuts that work... But I have to get focus on the app first (i.e., cmd-tab). That's a hassle and I'd rather just issue something like command-option-shift-space to turn it on and then to toggle it back off again. That seems doable with KM, but I'm not sure how to make the Maestro do that per se
This is very easy in KM, just use the
Activate a Specific Application action (KM Wiki)
Type a Keystroke action (KM Wiki) to issue the shortcut key.
Another option is to use the Select or Show a Menu Item action (KM Wiki), but I'm not sure if it will work in this situation.

Applescript to de-authorize a computer for iTunes

I have a computer (Mac) that is authorized to play music through iTunes which I want to disable. But, I only have ssh access to the machine. Is there an applescript I can run remotely (eg via the terminal) that I can use to de-authorize the machine?
I know that I can unauthorize all the machines I have authorized, but I would prefer to use this solution if it is possible.
I don't see any properties to authorize/deauthorize in iTunes dictionary but I just played around with GUI scripting and came up with a solution. So, the target Mac will have to have GUI Scripting enabled for the script below to work.
tell application "System Events"
tell process "iTunes"
click menu item "Deauthorize This Computer…" of menu 1 of menu bar item "Store" of menu bar 1
delay 1
set frontmost to true
click menu 1 of menu bar item "Store" of menu bar 1
set value of text field 1 of window "Deauthorize This Computer" to "password"
click button "Deauthorize" of window "Deauthorize This Computer"
end tell
end tell
You could leave that AppleScipt on your target Mac and then just use the open command to launch it. Or you could copy the above AppleScript and paste it into a shell script and use the HEREDOC method with osascript.
The full example of this looks like this:
osascript<<END
tell application "System Events"
tell process "iTunes"
click menu item "Deauthorize This Computer…" of menu 1 of menu bar item "Store" of menu bar 1
delay 1
set frontmost to true
click menu 1 of menu bar item "Store" of menu bar 1
set value of text field 1 of window "Deauthorize This Computer" to "password"
click button "Deauthorize" of window "Deauthorize This Computer"
end tell
end tell
END
The above method works well with Apple Remote Desktop's Send Unix feature as well.
Also, note that the password is included in this script which I don't recommend
but it is needed on the deauthorize window. If you put the password in the script make sure to secure that script so no one gets ahold of your Apple password.

Resources