At the bottom of this page Apple explains how to use UI scripting to automate selecting menu items. There are two hardcoded examples that I'm drawing on in an effort to write a generic library script for use in a number of projects that can choose any menu item from any menu through any hierarchy of submenus.
The TL;DR version of this question is: How do I do that? 😉
But for some more detail, if desired...
...I've made some progress, and come up with a few approaches for this but each of them has one fatal flaw or another...
Option 1.
If all the parameters are text or lists of text: eg:
on ChooseMenuItem(theApp, theMenuName, theSubMenusNamesList, theMenuItemName)
which might be called with eg:
ChooseMenuItem("TextEdit", "Format", {"Font", "Ligatures"}, "Use Default")
then I can use a bunch of text parsing and concatenation etc. -- including a repeat loop through the theSubMenusNamesList
parameter to carefully construct a script in a string something like "tell menu ... click ... tell menu item ... click ... tell menu item ... click ..."
etc. and then:
run script theScript in AppleScript
Voila! And this works. Except when any of those parameters - particularly the menu name - doesn't exist. eg. trying to connect or disconnect a bluetooth device through the bluetooth menu extra. So...
Option 2.
If the menu is nameless then let's change theMenuName to theMenu and pass it in by reference. eg:
tell application "System Events" to tell process "SystemUIServer" to set theMenu to (menu bar item 1 of menu bar 1 whose description contains "bluetooth")
...
ChooseMenuItem("SystemUIServer", theMenu, {"Magic Keyboard"}, "Connect")
Note, here theMenu
variable and parameter as opposed to theMenuName
. After performing the set
statement, theMenu
variable is not text, it's an AppleScript object, something like:
menu bar item 6 of menu bar 1 of application process "SystemUIServer"
Proceeding from here this fails one of three ways.
2a. If I try to construct a script that includes: tell theMenu ...
it tells me, not surprisingly, that ...the variable theMenu is not defined.
2b. If I pull theMenu
out of the quotes: "tell " & theMenu & "..."
or "tell \"" & theMenu & "\"..."
it errors with: Can’t make «class mbri» 6 of «class mbar» 1 of «class pcap» "SystemUIServer" of application "System Events" into type Unicode text.
ie. it can't coerce the aforementioned menu bar item 6 of menu bar 1... into text (unlike in Option 1 where I could call the menu by name).
2c. If I try to pull theMenu's tell statement out of the constructed text script so theScript text variable is something like tell menu item ... click ... tell menu item ... click
(without the initial tell menu ... click
) and then:
tell theMenu
click
run script theScript in AppleScript
end tell
then it tells me the variable "click" is not defined
. I believe it's referring to the first "click" in theScript variable that run script
is trying to ... well ... run. run script...
can't seem to pick up any context from where it's called from, or if it can I haven't figured out how.
Option 3
I've tried to think through how I might somehow include actual tell menu item theSubMenuName ...
statements (ie. not text strings of the same that I then try to run
) inside the above-mentioned repeat
loop, but since it's a hierarchy of tells I can't quite figure out how to make that work. Maybe there's a recursive solution here, but my brain's hurting too much to figure that out.
Conclusion
So, I'm at a loss... I can't figure this out, but I also can't believe there isn't a way to do this. My inclination is that there has to be some way to refer to menu bar item 6 of menu bar 1 of... in my theScript
variable somewhere... but how? Or if really not that, then some other ultimate solution here?