AppleScript toggling checkmarks beside menu items - macos

This is an extension of a previous question
Applescript: on clicking Menu Bar item via gui script
On the highlighted menu item below for the f.lux menu bar, if you click it, there will be a checkmark indicating that the "Disable for an hour" feature has been enabled. What I'm trying to do is write a GUI AppleScript for f.lux where the user can decide to toggle the check mark by typing a keyword in Alfred followed by a 1 or a 0 where 1 serves to enable the "Disable for an hour" and 0, serves to keep it unchecked.
This is a screen shot of the menu bar for f.lux
I am however having a hard time figuring out what attribute to adjust for the "Disable for an hour" menu item in order to toggle the checkmark. Here is the code, but I get an unexpected token error when compiling it via applescript editor. So far what I'm trying to do is target the "menu item mark character" attribute indicated by the arrow in screenshot above, but I'm not sure if this is the right approach to toggle the "Disable for an hour" item. Can someone please give me advice?
on alfred_script(q)
set myOption to q as integer
ignoring application responses
tell application "System Events" to tell process "Flux"
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 "Flux"
tell menu bar item 1 of menu bar 2
if myOption is 1 then
set ✓ to value of attribute "AXMenuItemMarkChar" of menu item "Disable for an hour" of menu 1
else if myOption is 0 then
set nil to value of attribute "AxMenuItemMarkChar" of menu item "Disable for an hour" of menu 1
end if
end tell
end tell
end alfred_script

This seems to work:
tell application "System Events" to tell process "Flux"
tell menu bar item 1 of menu bar 2
set v to (value of attribute "AXMenuItemMarkChar" of menu item "Disable for an hour" of menu 1) as string
if (v = "" and myOption = 1) or (v is not equal to "" and myOption = 0) then
click menu item "Disable for an hour" of menu 1
else
key code 53
end if
end tell
end tell

Related

Applescript Click item in system menu bar after opening it

I can open the bluetooth dropdown menu item with this code but I don't know how to actually click on any of the items in the menu.
tell application "System Events" to tell process "ControlCenter"
click menu bar item "Bluetooth" of menu bar 1
end tell
What would be a command to click on something in the open bluetooth menu?
This following AppleScript code should accomplish what you are trying to achieve. Just replace the "Mac Pro" part of the code with the name of the item you want to click.
tell application "System Events" to tell process "ControlCenter"
click menu bar item "Bluetooth" of menu bar 1
repeat until exists of checkbox 1 of scroll area 1 of window 1
delay 0.1
end repeat
click checkbox "Mac Pro" of scroll area 1 of window 1
key code 53 -- Press escape key
end tell
This following AppleScript code will return the names of the checkboxes so you can easily know your options to use in the first code.
tell application "System Events" to tell process "ControlCenter"
click menu bar item "Bluetooth" of menu bar 1
repeat until exists of checkbox 1 of scroll area 1 of window 1
delay 0.1
end repeat
set checkBoxNames to name of checkboxes of scroll area 1 of window 1
end tell

How to use AppleScript check if a menu item checked

see my image
I want to get the value of the menu item "Set as system proxy" (whether if it has been checked).
The problem is if I want to get that value I have to click that menu first and find the menu item. But I want it to be done in the background since I want it to be executed every 5 seconds.
My code goes like this
tell application "System Events"
tell process "ClashX"
click (menu bar itm 1 of menu bar 2)
get value of attribute "AXMenuItemMarkChar" of menu item "Set as system proxy" of menu 1 of menu bar item 1 of menu bar 2
end tell
end tell
(^^^^ This opens that menu over and over again)
and when I delete the line "click (menu bar itm 1 of menu bar 2)", which is
tell application "System Events"
tell process "ClashX"
get value of attribute "AXMenuItemMarkChar" of menu item "Set as system proxy" of menu 1 of menu bar item 1 of menu bar 2
end tell
end tell
the script cannot be done, error "System Events got an error: Can’t get menu 1 of menu bar item 1 of menu bar 2 of process "ClashX". Invalid index." number -1719 from menu 1 of menu bar item 1 of menu bar 2 of process "ClashX"
If you want to know whether or not the Set as system proxy menu item is checked for ClashX, you can check the value of the proxyPortAutoSet key in its preferences plist file, e.g.:
In Terminal:
defaults read com.west2online.ClashX 'proxyPortAutoSet'
Returns 1 when checked, and 0 when not checked.
If you want to use it in AppleScript, use a do shell script command, e.g.:
set menuItemIsChecked to ¬
(do shell script ¬
"defaults read com.west2online.CrashX 'proxyPortAutoSet'") ¬
as boolean
if menuItemIsChecked then
# Your code goes here.
end if

How to use applescript to control the noise canceling of AirPods Pro?

I want to implement a alfred workflow to control my AirPods Pro to switch between "Transparency Mode" and "ANC Mode". How can I write an apple script to simulate click on "audio" menu bar to switch noise-canceling. Or there is a better solution?
I also had this problem, so I solved it in this way (with the error handling if the AirPods are not connected + popups):
tell application "System Events"
tell process "SystemUIServer"
click (menu bar item 1 of menu bar 1 whose description contains "volume")
try
click menu item "nestim AirPods Pro" of menu 1 of result
if value of attribute "AXMenuItemMarkChar" of menu item "Transparency" of menu 1 of result is "✓" then
click menu item "Noise Cancellation" of menu 1 of result
display notification "Noise Cancellation active" with title "Noise control:"
return "Noise Cancellation active"
else
click menu item "Transparency" of menu 1 of result
display notification "Transparency mode active" with title "Noise control:"
return "Transparency mode active"
end if
on error
tell application "System Events"
key code 53
display notification "Something went wrong" with title "Noise control:" sound name "Submarine"
return "Something went wrong"
end tell
end try
end tell
end tell
I found a simple apple script solution after trying.
tell application "System Events"
tell process "SystemUIServer"
click (menu bar item 1 of menu bar 1 whose description contains "volume")
click menu item "your AirPods name" of menu 1 of result
click menu item "noise control mode" of menu 1 of result
end tell
end tell
Change the your AirPods name to your AirPods name and change the noise control mode to which you want to (like Off, Noise Cancellation, or Transparency, or to your language as 关闭,降噪,通透模式 in Chinese).
Inspired by anton-uspehov's answer. I updated the script to automatic connect AirPods when it is not connected.
tell application "System Events"
tell process "SystemUIServer"
click (menu bar item 1 of menu bar 1 whose description contains "volume")
try
click menu item "your AirPods name" of menu 1 of result
click menu item "noise control mode" of menu 1 of result
on error
key code 53
click (menu bar item 1 of menu bar 1 whose description contains "bluetooth")
click menu item "your AirPods name" of menu 1 of result
click menu item "Connect" of menu 1 of result
end try
end tell
end tell
Or if your want to auto switch between Noise Cancellation and Transparency
tell application "System Events"
tell process "SystemUIServer"
click (menu bar item 1 of menu bar 1 whose description contains "volume")
try
click menu item "your AirPods name" of menu 1 of result
if value of attribute "AXMenuItemMarkChar" of menu item "Transparency" of menu 1 of result is "✓" then
click menu item "Noise Cancellation" of menu 1 of result
else
click menu item "Transparency" of menu 1 of result
end if
on error
key code 53
click (menu bar item 1 of menu bar 1 whose description contains "bluetooth")
click menu item "your AirPods name" of menu 1 of result
click menu item "Connect" of menu 1 of result
end try
end tell
end tell
For macos Big Sur (10.14) users, use the following script
set AirPodsName to "Your AirPods name"
tell application "System Events"
tell application process "ControlCenter"
set volMenu to menu bar item "volume" of menu bar 1
tell volMenu to click
set btCheckbox to checkbox 1 of scroll area 1 of group 1 of window "ControlCenter" whose title contains AirPodsName
set btCheckboxValue to value of btCheckbox
tell btCheckbox to click
delay 0.1
set checkbox_anc to checkbox 1 of scroll area 1 of group 1 of window "ControlCenter" whose title contains "Noise Cancellation"
if exists checkbox_anc then
if value of checkbox_anc is 1 then
set checkbox_transparent to checkbox 1 of scroll area 1 of group 1 of window "ControlCenter" whose title contains "Transparency"
tell checkbox_transparent to click
else
tell checkbox_anc to click
end if
end if
tell volMenu to click
end tell
end tell

Applescript: on clicking Menu Bar item via gui script

I'm trying to make an applescript for an application called F.lux that clicks the menu item "Disable for an Hour" as indicated in the screenshot below:
The element path is indicated in the screenshot below:
Here is my code thus far:
tell application "System Events"
tell process "Flux"
click (menu bar item 1 of menu bar 2)
click menu item "Disable for an hour" of menu 1 of menu bar item 1 of
menu bar 2
end tell
end tell
Everything compiles fine, however I keep getting the error message below when I attempt to run the script:
error "System Events got an error: Can’t get menu 1 of menu bar item 1 of menu bar 2 of process "Flux". Invalid index." number -1719 from menu 1 of menu bar item 1 of menu bar 2 of process "Flux"
Can someone pinpoint where I'm going wrong with this?
This worked for me, but there is a delay of about 5 seconds after the first click command.
tell application "System Events" to tell process "Flux"
tell menu bar item 1 of menu bar 2
click
click menu item "Disable for an hour" of menu 1
end tell
end tell
One workaround is to use ignoring application responses and terminate System Events after the click command:
ignoring application responses
tell application "System Events" to tell process "Flux"
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 "Flux"
tell menu bar item 1 of menu bar 2
click menu item "Disable for an hour" of menu 1
end tell
end tell

In Applescript, how can I find out if a menu item is selected/focused?

I have a script for OS X 10.5 that focuses the Search box in the Help menu of any application. I have it on a key combination and, much like Spotlight, I want it to toggle when I run the script. So, I want to detect if the search box is already focused for typing, and if so, type Esc instead of clicking the Help menu.
Here is the script as it stands now:
tell application "System Events"
tell (first process whose frontmost is true)
set helpMenuItem to menu bar item "Help" of menu bar 1
click helpMenuItem
end tell
end tell
And I'm thinking of something like this:
tell application "System Events"
tell (first process whose frontmost is true)
set helpMenuItem to menu bar item "Help" of menu bar 1
set searchBox to menu item 1 of menu of helpMenuItem
if (searchBox's focused) = true then
key code 53 -- type esc
else
click helpMenuItem
end if
end tell
end tell
... but I get this error:
Can’t get focused of {menu item 1 of menu "Help" of menu bar item "Help" of menu bar 1 of application process "Script Editor" of application "System Events"}.
So is there a way I can get my script to detect whether the search box is already focused?
I solved my problem by working around it. I still don't know how to check if a menu item is selected though, so I will leave this topic open.
You need to use attribute AXMenuItemMarkChar.
Example:
tell application "System Events"
tell process "Cisco Jabber"
set X to (value of attribute "AXMenuItemMarkChar" of menu item "Available" of menu "Status" of menu item "Status" of menu "File" of menu bar item "File" of menu bar 1) is "✓" -- check if Status is "Availible"
end tell
end tell
If the menu item is checked, the return value is ✓, otherwise it is missing value.
Note: This test only works if the application whose menus are being inspected is currently frontmost.
The built in key shortcut Cmd-? (Cmd-Shift-/) already behaves like this. It moves key focus to the help menu's search field if it is not already focused, and otherwise dismisses the menu.
Using /Developer/Applications/Utilities/Accessibility Tools/Accessibility Inspector.app you can use the built-in accessibility system to look at properties of the UI element under the mouse. Take special note of the cmd-F7 action to lock focus on an element and the Refresh button. Sadly the element and property names don't directly match those in the script suite, but you can look at the dictionary for System Events or usually guess the right terminology.
Using this you can determine two things. First, the focused property isn't on the menu item, but rather there is a text field within the menu item that is focused. Second, the menu item has a selected property.
With this, I came up with:
tell application "System Events"
tell (first process whose frontmost is true)
set helpMenuItem to menu bar item "Help" of menu bar 1
-- Use reference form to avoid building intermediate object specifiers, which Accessibility apparently isn't good at resolving after the fact.
set searchBox to a reference to menu item 1 of menu of helpMenuItem
set searchField to a reference to text field 1 of searchBox
if searchField's focused is true then
key code 53 -- type esc
else
click helpMenuItem
end if
end tell
end tell
Though this still doesn't work. The key event isn't firing as far as I can tell, so something may still be hinky with the focused property on the text field.
Anyway, your click again solution seems much easier.
I just came across the need to do this myself for some file processing in Illustrator.
Here is what I came up with:
tell application "Adobe Illustrator"
activate
tell application "System Events"
tell process "Illustrator"
set frontmost to true
set activeMenuItem to enabled of menu item "Unlock All" of menu "Object" of menu bar item "Object" of menu bar 1
if activeMenuItem is true then
tell me to beep 3
else
tell me to beep 2
end if
end tell
end tell
end tell
Done.
This worked with no problem and could be used to iterate a file. I'll probably have to do this many more times in my future automation.
Good luck!
This worked for me to toggle between two menu items, based on which one is selected, using the "selected" property:
tell application "System Preferences"
reveal anchor "keyboardTab" of pane "com.apple.preference.keyboard"
end tell
tell application "System Events" to tell process "System Preferences"
tell pop up button 2 of tab group 1 of window 1
click
delay 0.2
set appControl to menu item "App Controls" of menu 1
set fKeys to menu item "F1, F2, etc. Keys" of menu 1
if selected of appControl is true then
click fKeys
else
click appControl
end if
end tell
end tell

Resources