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.
Related
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.
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.
I'm trying to open a messaging application (it does not have an Apple Script Dictionary (command + shift + o)), click on text, and type into the text box, and hit send.
Pop up: Script Error - Telegram got an error: Can't continue click after the application becomes active.
Result Tab: error "Telegram got an error: Can’t continue click." number -1708
P.S., The messaging application is Telegram.
Apple Script:
tell application "Telegram"
activate
delay 1
click on text "chat name"
keystroke "some text"
//assuming this works because text box is the first responder when the chat opens.
click on text "Send"
end tell
If an application lacks an AppleScript dictionary, any command except the standard commands launch, activate, open, reopen and quit will throw an error.
The solution is GUI scripting: The built-in application System Events is the bridge to send mouse clicks and keyboard events to the target application.
I don't know the application Telegram at all, so this code might fail, but it might also be a starting point
activate application "Telegram"
tell application "System Events"
tell process "Telegram"
tell window 1
keystroke "some text"
click button "Send"
end tell
end tell
end tell
You have two choices for a 3rd party app that lacks an AppleScript dictionary.
Option 1:
Use System Events as described above to perform an action on an element, e.g. click a button, keystroke text into a field, etc. The trick is to identify the element in syntax that is recognized by Applescript. Besides UIElementInspector mentioned above, which can be confusing and occasionally wrong/incomplete, you can also run the following commands in a separate Applescript Editor. For example, to get all UI elements for the active window (window 1) in Telegram:
tell application "System Events" to tell application process "Telegram" to tell window 1
UI elements
end tell
To get all UI elements for the main menu bar in Telegram:
tell application "System Events" to tell application process "Telegram" to tell menu bar 1
UI elements
end tell
In each case the Result pane will display a comma delimited list of all available UI elements in that window or menu bar. Moreover, the syntax as listed is guaranteed to be recognizable by Applescript. Just identify the correct element and tell System Events to tell it what to do.
For example if you want to click the Menu item "Format" In TextEdit first run the following:
tell application "System Events" to tell application process "TextEdit" to tell menu bar 1
UI elements
end tell
Among the results in the Result pane will be the following:
menu bar item "Format" of menu bar 1 of application process "TextEdit" of application "System Events"
Convert that to Applescript, run the script and it will click the "Format" Menu:
tell application "TextEdit" to activate --you need TexEdit up and running to click its menu bar
tell application "System Events" to click menu bar item "Format" of menu bar 1 of application process "TextEdit"
For submenus, etc. you just iterate the process asking for UI elements for the submenu. GUI scripting is iterative and empirical.
Option 2:
Download the free Terminal/Command Line app cliclick which allows you to click on any point in the screen. The screen coordinates you want to click can be manually identified with your cursor by holding down command + shift + 4.
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.
Sometimes I use PdaNet to tether using my iPhone. The desktop client for OSX is not as rich as the one for windows. One of the chief differences is, that the OSX does not allow to automatically connect to iPhone as soon as the latter is plugged in.
Would you know of a way using Applescript to click on the PdaNet icon on the Menu Bar and then select and click the 'Connect' option on it ?
Here is what the 'PdaNetMac' application's menu bar icon looks like:
I have looked at the following questions but am an applescript newbie and am not sure how to search for PdaNet's icon on the menu bar:
Click menu item on Mac OSX Lion using AppleScript
Applescript: on clicking Menu Bar item via gui script
Accessing dock icon right-click menu items with AppleScript
I have confirmed that 'Enable Access for assistive devices' is enabled.
Based on the second question above, Here is my current attempt at doing this:
ignoring application responses
tell application "System Events" to tell process "PdaNet"
click menu bar item 1 of menu bar 2
end tell
end ignoring
do shell script "killall System\\ Events"
delay 0.1
tell application "System Events" to tell process "PdaNet"
tell menu bar item 1 of menu bar 2
click menu item "Connect" of menu 1
end tell
end tell
Interestingly, the above script works for me fine when I change PdaNet to Flux.
Thanks!!
You were very close !!
I just downloaded the PdaNet application to test this, and the only edit I had to make to your script was change PdaNet to 'PdaNetMac` ( I was thinking that this is the Process Name and so used the process name displayed in Activity Monitor).
So this works for me:
ignoring application responses
tell application "System Events" to tell process "PdaNetMac"
click menu bar item 1 of menu bar 2
end tell
end ignoring
do shell script "killall System\\ Events"
delay 0.1
tell application "System Events" to tell process "PdaNetMac"
tell menu bar item 1 of menu bar 2
click menu item "Connect" of menu 1
end tell
end tell
Hope this works for you too !!
(Very useful script, btw. Cheers !)