I’m trying to write a script that would change sound volume level and/or display resolution etc. using the items to the right on the menu bar. I know how to access normal menus, such as e.g. File, Edit etc. for a process either by name or number. However I cannot find how to access the special items at the far right on the menu bar. When I specify a number, counting Apple as 1, it says “invalid index”. When I try using a name such as “volumecontrol” it says that it cannot get it.
Another but related question “ how do I specify menu bar without specifying process? I don’t know what process will be in the foreground when the script is supposed to run.
Any comments and/or advice would be greatly appreciated.
The menu items at the right side belong to SystemUIServer, and these are very tricky scriptable,
here an example to run the menu item “Sync Now” of the sync menu
tell application "System Events"
tell process "SystemUIServer"
repeat with mni in (get menu bar items of menu bar 1)
if (value of attribute "AXDescription" of mni as string) is "" then
perform action "AXPress" of mni
set NameList to name of menu items of menu of mni
if item 1 of item 1 of NameList begins with "Last .Mac" then
perform action "AXPress" of menu item "Sync Now" of menu of mni
exit repeat
end if
end if
end repeat
end tell
end tell
If you have the Sound and Display icons already in your menubar, you can do everything you ask without AppleScript.
If you don’t have those icons in your menubar, go to their respective panes in System Preferences and click “Show Icon in Menubar”.
@Stefan
Many thanks Stefan! Controlling volume using menu bar was mostly an exercise before the real thing which is changing resolution and mirroring (among other things). But even the volume using set volume may come handy when automating a set up for a particular user task. I adapted your script to set resolution to 1680x1050:
tell application "System Events"
tell process "SystemUIServer"
repeat with mbi in menu bar items of menu bar 1
if value of attribute "AXDescription" of mbi as string is "displays" then
click mbi
repeat with mi in menu items of menu of mbi
try
set miname to name of mi as string
if word 1 of miname is "1680" then
if word 3 of miname is "1050" then
click mi
exit repeat
end if
end if
error
-- less than 3 words in miname
-- do nothing
end try
end repeat
exit repeat
end if
end repeat
end tell
end tell
The crux was process “SystemUIServer” and attribute “AXDescription” as you exemplified. The rest is plain vanilla (after you adapt your vocabulary from Java and C++ to AppleScript).
The next step is to figure out how to execute such a script before a particular application starts and then execute another script when that app ends or perhaps to start execution using a remote control. The app is this case FR.
@Harry
Yes, of course, there are Sound Volume and Displays items in the menu bar; otherwise you cannot get references to them. Yes, of course, you can control them manually by hand. The purpose of a script is to automate a longer sequence of user actions - a sequence that always is to be performed before a particular task. So that the user can focus on the task at hand instead of all the clicking and mousing around required before he/she begins the actual task.
On a related point, I’ve done a script to turn bluetooth on and connect to the net using my bluetooth enabled mobile phone, and another script to disconnect and turn off bluetooth.
With those now in place, the only thing I need is the fact that the modem status menu item shows how long I’ve been connected, which is useful so I don’t stay connected too long for financial reasons. Is there any way I can automate the showing of the modem status menu and make it hide too? I ask as it’s an option in the network preference pane which I’ve already managed to script a bit of.
The alternative would perhaps be a growl status which showed the time connected, maybe every 5 minutes, but that’s way beyond me…:rolleyes:
I haven’t been using Bluetooth in this way (yet) so could you clarify it to me please. What would you do manually in order to achieve what you want to achieve? Starting from that sequence of manual actions it should be possible to design a script.
Now I can automate connecting to the net, I don’t need the Modem Status Menu Extra for any other reason than to show the time I’ve been connected. When I’m not online, I don’t need the menu extra at all, and would like to have shot of it.
So, what I’d like to do is have a script which makes the modem status menu extra visible, and then can turn it off later. If it was something I’d be doing normally, I’d go to the network prefpane, and select ‘show modem status in menu bar’.
Well then, this is what your script has to do. Here is one example that I found on the net (it changes energy saver prefs):
tell application "System Preferences"
activate
end tell
tell application "System Events"
tell process "System Preferences"
set frontmost to true
click menu item "Energy Saver" of menu "View" of menu bar 1
tell window "Energy Saver"
-- click the "Options" tab
-- choose "highest" from the processor performance menu
end tell
end tell
end tell