I'm working on automating setting system preferences, but I have a problem. This code should select Wi-Fi tab but scroll area 1 does not exist unless I click any element that belongs to scroll area manually. I tried emulating click with many external programs but even then I can't access scroll area
tell application "System Preferences"
activate
reveal pane id "com.apple.preference.dock"
end tell
tell application "System Events" to tell application process "System Preferences"
delay 1
tell scroll area 1 of window 1
select row 3 of outline 1
end tell
end tell
Is there any other way to change Dock & Menu Bar settings or just to access scroll area items?
Edit: The end goal is to hide Wi-Fi icon from menu bar.
The end goal is to hide Wi-Fi icon from menu bar.
UI Scripting of System Preferences in macOS Big Sur has become a nightmare, as many of the methods that used to work in previous versions of macOS just no longer do in macOS Big Sur. Many UI elements report Parent does not report element as one of its children when using Accessibility Inspector of Xcode, which then make it impossible to communicate with them. Or some code may work one time and then not the next. I wrote some code that opened to Wi-Fi and clicked the Show in Menu Bar checkbox. It worked a few times and now it doesn't.
The original code I wrote which sporadically worked I'll not post, however, the following example AppleScript code does consistently work as tested under macOS Big Sur 11.4, albeit it is what I consider kludgy UI Scripting, as it's visible on screen, is prone to failure due to timing issues, or if the hierarchical UI element structures change due to macOS updates/upgrades.
The example AppleScript code, shown below, was tested in Script Editor under macOS Big Sur 11.4 with Language & Region settings in System Preferences set to English (US) — Primary and worked for me without issue1.
1 Assumes necessary and appropriate setting in System Preferences > Security & Privacy > Privacy have been set/addressed as needed.
This script requires that the Use keyboard navigation to move focus between controls checkbox is checked on the System Preferences > Keyboard > Shortcuts tab, and as coded, the script checks its status and toggles the checkbox, as necessary, based on its current status.
This script also first checks to see if the Wi-Fi icon is shown on the Menu Bar and if not, then halt execution of the script, as its purpose is to act only if it is shown on the Menu Bar.
Example AppleScript code:
-- # Get the fully qualified POSIX pathname of the target .plist file.
set thePropertyListFilePath to ¬
the POSIX path of ¬
(path to preferences from user domain as string) & ¬
"com.apple.controlcenter.plist"
-- Get the value of 'NSStatusItem Visible WiFi' to determine if the
-- Wi-Fi icon is showing on the Menu Bar, and if it's not, then halt
-- execution of the script, as its purpose is to act only if it is.
tell application "System Events" to ¬
tell the property list file thePropertyListFilePath to ¬
set |Wi-Fi Menu Bar Icon Status| to the value of ¬
the property list item ¬
"NSStatusItem Visible WiFi"
if |Wi-Fi Menu Bar Icon Status| is false then return
-- # Check to see if System Preferences is
-- # running and if yes, then close it.
-- #
-- # This is done so the script will not fail
-- # if it is running and a modal sheet is
-- # showing, hence the use of 'killall'
-- # as 'quit' fails when done so, if it is.
-- #
-- # This is also done to allow default behaviors
-- # to be predictable from a clean occurrence.
if running of application "System Preferences" then
try
tell application "System Preferences" to quit
on error
do shell script "killall 'System Preferences'"
end try
delay 0.1
end if
-- # Make sure System Preferences is not running before
-- # opening it again. Otherwise there can be an issue
-- # when trying to reopen it while it's actually closing.
repeat while running of application "System Preferences" is true
delay 0.1
end repeat
-- # Get the fully qualified POSIX pathname of the target .plist file.
set thePropertyListFilePath to ¬
the POSIX path of ¬
(path to preferences from user domain as string) & ¬
".GlobalPreferences.plist"
-- # Get the value of AppleKeyboardUIMode to determine if the
-- # 'Use keyboard navigation to move focus between controls'
-- # checkbox is checked on the System Preferences >
-- # Keyboard > Shortcuts tab.
tell application "System Events" to ¬
tell the property list file thePropertyListFilePath to ¬
set keyboardNavigation to the value of ¬
the property list item "AppleKeyboardUIMode"
if keyboardNavigation = 0 then
-- # Check the checkbox.
my toggleKeyboardNavagition()
end if
-- # Open System Preferences to the Dock & Menu Bar pane.
-- #
-- # This UI Script needs it to be visible, hence the activate command.
tell application "System Preferences"
activate
reveal pane id "com.apple.preference.dock"
end tell
tell application "System Events"
set i to 0
repeat until exists window "Dock & Menu Bar" of ¬
application process "System Preferences"
delay 0.1
set i to i + 1
if i ≥ 30 then return
end repeat
end tell
-- # Tab to the 'Show in Menu Bar' checkbox and uncheck it.
tell application "System Events"
key code 48 -- # tab key
delay 0.2
key code 125 -- # down arrow key
delay 0.2
key code 48 -- # tab key
delay 0.2
key code 49 -- # spacebar
delay 0.1
end tell
if keyboardNavigation = 0 then
-- # Uncheck the checkbox if it
-- # was previously unchecked.
my toggleKeyboardNavagition()
end if
delay 0.2
tell application "System Preferences" to quit
-- # Handler(s) #
-- # Toggles checkbox: 'Use keyboard navigation
-- # to move focus between controls'
on toggleKeyboardNavagition()
tell application "System Preferences"
activate
reveal anchor "shortcutsTab" of ¬
pane id "com.apple.preference.keyboard"
end tell
tell application "System Events"
tell front window of ¬
application process "System Preferences"
set i to 0
repeat until (exists checkbox 1 of tab group 1)
delay 0.1
set i to i + 1
if i ≥ 30 then return
end repeat
click checkbox 1 of tab group 1
end tell
end tell
end toggleKeyboardNavagition
Notes:
If the normal state of the Use keyboard navigation to move focus between controls checkbox is unchecked, then do not run the script immediately back to back as it takes a second or two for the value of the property list item "AppleKeyboardUIMode" in the users global preferences file to update the change. I'm mentioning this mainly for when doing testing more so than when in normal production use, as it shouldn't be an issue then.
Note: The example AppleScript code is just that and sans any included error handling does not contain any additional 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. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.
Related
I need to automate the change of locale (Region/Country) for format purpose from:
Region: Americas
Country: United States
to
Region: Europe
Country: Spain
So I have the following code, which seems to work up to the point where the system asks to restart the machine (or not).
property theSettings : {"", ""}
set settings1 to {"Americas", "United States"}
set settings2 to {"Europe", "Spain"}
if running of application "System Preferences" then
try
tell application "System Preferences" to quit
on error
do shell script "killall 'System Preferences'"
end try
delay 0.1
end if
repeat while running of application "System Preferences" is true
delay 0.1
end repeat
tell application "System Preferences"
reveal anchor "Language" of ¬
pane id "com.apple.Localization"
activate
end tell
tell application "System Events"
tell window "Language & Region" of process "System Preferences"
if (value of pop up button "Region:" of tab group 1) is "United States" then
set theSettings to settings2
else
set theSettings to settings1
end if
set {theRegion, theCountry} to theSettings
tell pop up button "Region:" of tab group 1
delay 0.25
click
delay 0.25
click menu item theRegion of menu 1
delay 0.25
click menu item theCountry of menu 1 of menu item theRegion of menu 1
end tell
end tell
delay 1
tell application "System Preferences" to quit
tell sheet 1 of window "Language & Region" of process "System Preferences"
delay 1
keystroke tab
delay 1
keystroke return
end tell
end tell
In the script above, after switching locale, I am trying to click the button Don't Restart. But this does not work as the sheet window does not seem to be active.
Any idea on how to save the settings?
This issue is, at that point the sheet is modal and typically requires physical intervention. In other words, based on its current appearance, normally one would either press enter/return key to accept the default or use the mouse to click either Don’t Restart or Cancel as tabbing in not active by default in this use case.
However, if the [√] Use keyboard navigation to move focus between controls checkbox in System Preferences > Keyboard > Shortcuts is checked, which it is not by default, then one could simply press the space bar as Don’t Restart would have focus even though Restart Now would be, by default, solid blue.
To get past the modality of the situation, one would have to add code that would programmatically check to see that the aforementioned checkbox is checked, and if not check it.
In addition to the check and taking action if necessary, the modifications to your existing code are as follows:
In between:
repeat while running of application "System Preferences" is true
delay 0.1
end repeat
And:
tell application "System Preferences"
reveal anchor "Language" of ¬
pane id "com.apple.Localization"
activate
end tell
Add:
-- # Get the fully qualified POSIX pathname of the target .plist file.
set thePropertyListFilePath to ¬
the POSIX path of ¬
(path to preferences from user domain as string) & ¬
".GlobalPreferences.plist"
-- # Get the value of AppleKeyboardUIMode to determine if the
-- # 'Use keyboard navigation to move focus between controls'
-- # checkbox is checked on the System Preferences >
-- # Keyboard > Shortcuts tab.
tell application "System Events" to ¬
tell the property list file thePropertyListFilePath to ¬
set keyboardNavigation to the value of ¬
the property list item "AppleKeyboardUIMode"
if keyboardNavigation = 0 then
-- # Check the checkbox.
my toggleKeyboardNavigation()
end if
And to the end of the script add:
-- # Handler #
-- # Toggles checkbox: 'Use keyboard navigation
-- # to move focus between controls'
on toggleKeyboardNavigation()
tell application "System Preferences"
activate
reveal anchor "shortcutsTab" of ¬
pane id "com.apple.preference.keyboard"
end tell
tell application "System Events"
tell front window of ¬
application process "System Preferences"
set i to 0
repeat until (exists checkbox 1 of tab group 1)
delay 0.1
set i to i + 1
if i ≥ 30 then return
end repeat
click checkbox 1 of tab group 1
end tell
end tell
end toggleKeyboardNavigation
After making the aforementioned changes, then starting with:
tell application "System Preferences" to quit
Replace it and the ensuing tell block with:
ignoring application responses
tell application "System Preferences" to quit
end ignoring
delay 1
key code 49 -- # space key
Then after the end tell of the primary tell application "System Events" block, the one just below the previous code change, add the following:
repeat while running of application "System Preferences" is true
delay 0.1
end repeat
if keyboardNavigation = 0 then
-- # Uncheck the checkbox if it
-- # was previously unchecked.
my toggleKeyboardNavigation()
delay 0.2
tell application "System Preferences" to quit
end if
Notes:
The example AppleScript code shown herein to check to see if [] Use keyboard navigation to move focus between controls in System Preferences > Keyboard > Shortcuts is checked, can be done differently by opening to that pane and ascertaining whether of not it's checked and act accordingly. The reason I've added the code for it as is, is because I've used it to reset that checkbox later on in the script in the past. If the checkbox is already checked then one doesn't have to see the extra changing of panes.
I am trying to automate via AppleScript the addition and the selection of a specific language in macOS Big Sur (for example Spanish) from System Preferences > Language & Region.
I can display the UI via this code, but I cannot get the "+" button to click.
tell application "System Preferences"
reveal anchor "Language" of pane id "com.apple.Localization"
activate
tell application "System Events"
tell window 1 of application process "System Preferences"
set i to 0
repeat until exists button 1 of group 1
delay 0.1
set i to i + 1
if i ≥ 30 then return
end repeat
-- # Click the [+] button.
click button 1 of group 1
end tell
end tell
end tell
The example AppleScript code, shown below, was tested in Script Editor under macOS Big Sur with Language & Region settings in System Preferences set to English (US) — Primary and worked for me without issue1.
1 Assumes necessary and appropriate settings in System Preferences > Security & Privacy > Privacy have been set/addressed as needed.
The value of the property thisLanguage needs to be set to that which will show in the list of the Select a preferred language to add: sheet, as it is set to the value of the text box on the Select a preferred language to add: sheet. This is necessary so AppleScript does not have to spend a lot of time searching the entire list as the target should now be it the top portion of the list.
Note that for, e.g., Español this script as is, is all that was necessary, however, on some languages one may get an additional sheet to reply to. For example, with 简体中文 (Simplified Chinese) one gets an additional Select input sources to add: sheet, and you will need to add additional code to handle it. You should be able to, from the example AppleScript code shown below, figure out how to deal with it as there is already an example therein.
Example AppleScript code:
property thisLanguage : "Español"
-- # Check to see if System Preferences is
-- # running and if yes, then close it.
-- #
-- # This is done so the script will not fail
-- # if it is running and a modal sheet is
-- # showing, hence the use of 'killall'
-- # as 'quit' fails when done so, if it is.
-- #
-- # This is also done to allow default behaviors
-- # to be predictable from a clean occurrence.
if running of application "System Preferences" then
try
tell application "System Preferences" to quit
on error
do shell script "killall 'System Preferences'"
end try
delay 0.1
end if
-- # Make sure System Preferences is not running before
-- # opening it again. Otherwise there can be an issue
-- # when trying to reopen it while it's actually closing.
repeat while running of application "System Preferences" is true
delay 0.1
end repeat
-- # Reveal the General tab of the Language
-- # & Region pane in System Preferences.
tell application "System Preferences"
reveal anchor "Language" of ¬
pane id "com.apple.Localization"
activate
end tell
-- # System Events handles the rest.
tell application "System Events"
launch
delay 0.2
tell application process "System Preferences"
-- # Click the [+] button.
click button 1 of group 2 of tab group 1 of window 1
-- # Wait for sheet 1 to be available.
set i to 0
repeat until exists text field 1 of sheet 1 of window 1
delay 0.1
set i to i + 1
if i ≥ 30 then return
end repeat
-- # Search for: thisLanguage
set the value of ¬
text field 1 of ¬
sheet 1 of ¬
window 1 to ¬
thisLanguage
delay 1 -- # May need to be increased.
-- # Get the row that matches thisLanguage.
set theTargetRow to ¬
the first row of ¬
table 1 of ¬
scroll area 1 of ¬
sheet 1 of ¬
window 1 whose value of ¬
static text 1 of ¬
UI element 1 is thisLanguage
-- # Select the row that matches thisLanguage.
select theTargetRow
-- # Click the Add button.
click button 3 of sheet 1 of window 1
-- # Wait for the sheet to change.
set i to 0
repeat until exists ¬
button "Use English (US)" of ¬
sheet 1 of window 1
delay 0.1
set i to i + 1
if i ≥ 30 then return
end repeat
-- # The button for thisLanguage
-- # should have focus, press enter.
keystroke return
end tell
end tell
delay 0.2
tell application "System Preferences" to quit
Notes:
The use of the launch command after tell application "System Events" is to try and help with a systemic issues in UI Scripting as a result of changes Apple had made in macOS Big Sur.
Also note that UI Scripting is often kludgy and prone to failure for a variety of reasons and why I have used the error handling that I have, however, one may need to add addition error handling and or delay commands and or adjust the value of existing ones, as needed.
Note: The example AppleScript code is just that and sans any included error handling does not contain any additional 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. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.
I have tried looking through many answered questions and wasn't able to fix my specific issue, the issue is telling applescript to look through Extensions in system preferences and untick this check box
I am unable to help applescript locate the checkbox through Extensions>Added Extensions>Core Sync>Finder Extensions, I'm not sure how to go about this.
I am able to open the extensions tab and have the checkbox the first thing that is infront, this is my code that does that:
tell application "System Preferences"
activate
reveal (pane id "com.apple.preferences.extensions")
end tell
The checkbox im trying to untick
The example AppleScript code, shown below, was tested in Script Editor under macOS Big Sur with Language & Region settings in System Preferences set to English (US) — Primary and worked for me without issue1.
1 Assumes necessary and appropriate settings in System Preferences > Security & Privacy > Privacy have been set/addressed as needed.
Since the target extension is the first one in the list, I've coded the example AppleScript code for that particular checkbox. Additional coding would be necessary to enumerate and target an extension by name.
Example AppleScript code:
-- # Check to see if System Preferences is
-- # running and if yes, then close it.
-- #
-- # This is done so the script will not fail
-- # if it is running and a modal sheet is
-- # showing, hence the use of 'killall'
-- # as 'quit' fails when done so, if it is.
-- #
-- # This is also done to allow default behaviors
-- # to be predictable from a clean occurrence.
if running of application "System Preferences" then
try
tell application "System Preferences" to quit
on error
do shell script "killall 'System Preferences'"
end try
delay 0.1
end if
-- # Make sure System Preferences is not running before
-- # opening it again. Otherwise there can be an issue
-- # when trying to reopen it while it's actually closing.
repeat while running of application "System Preferences" is true
delay 0.1
end repeat
-- # Open to the Extensions pane in System Preferences.
tell application "System Preferences" to ¬
reveal pane id "com.apple.preferences.extensions"
tell application "System Events"
tell application process "System Preferences"
-- # Wait until target UI element is available.
set i to 0
repeat until ¬
exists ¬
checkbox 1 of ¬
UI element 1 of ¬
row 2 of ¬
table 1 of ¬
scroll area 1 of ¬
group 1 of ¬
window 1
delay 0.2
set i to i + 1
if i ≥ 20 then return
end repeat
-- # Click the first checkbox.
click ¬
checkbox 1 of ¬
UI element 1 of ¬
row 2 of ¬
table 1 of ¬
scroll area 1 of ¬
group 1 of ¬
window 1
end tell
end tell
delay 0.2
tell application "System Preferences" to quit
Note: The example AppleScript code is just that and sans any included error handling does not contain any additional 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. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.
This code from here works perfect, but doesn't work in Firefox. Why and how to fix it in applescript?
tell application "Google Chrome"
repeat until (loading of tab 1 of window 1 is false)
1 + 1 --just an arbitary line
end repeat
loading of tab 1 of window 1 --this just returns final status
end tell
As Firefox does not contain a specific AppleScript dictionary, e.g. Firefox.sdef file, it is not considered to be AppleScript scriptable in the same way as e.g. Google Chrome, and while it will respond to some of the basic commands, such as activate, quit, etc., it will require UI Scripting to do what you are asking.
The following example AppleScript code requires Firefox version 87 or newer, and setting its accessibility.force_disabled preference to: -1
First, in Firefox, in the Address/Search combo box, type about:config and press enter.
If applicable, click the Accept the Risk and Continue button.
In the Search preference name text box, type accessibility.force_disabled and press enter.
Click the Edit button and change its value to: -1
Click the the Save button.
Here is an example of how I would instruct Firefox to open a new window to a given URL and wait for the page to finish loading.
Example AppleScript code:
set theURL to "https://news.google.com/"
tell application "Firefox" to activate
delay 0.5 -- # Value may need to be adjusted if Firefox is closed.
my clickApplicationMenuCommand("Firefox", "File", "New Window")
delay 0.5
my setURLofFirefoxFrontWindowTo(theURL)
my waitForFirefoxPageToFinishLoading()
say "foobar"
-- # Handler(s) #
to clickApplicationMenuCommand(appName, appMenuName, appMenuCommand)
tell application appName to activate
delay 0.25
tell application "System Events" to ¬
click ¬
menu item appMenuCommand of ¬
menu appMenuName of ¬
menu bar item appMenuName of ¬
menu bar 1 of ¬
application process appName
end clickApplicationMenuCommand
to setURLofFirefoxFrontWindowTo(theURL)
tell application "System Events"
tell application process "Firefox"
set the value of UI element 1 of ¬
combo box 1 of toolbar "Navigation" of ¬
first group of front window to theURL
key code 36 -- # enter key
end tell
end tell
end setURLofFirefoxFrontWindowTo
to waitForFirefoxPageToFinishLoading()
-- # Requires Firefox version 87 or newer.
-- # Requires accessibility.force_disabled set to: -1
tell application "System Events"
tell application process "Firefox"
repeat until exists UI element "Reload" of ¬
toolbar "Navigation" of group 1 of window 1
delay 0.1
end repeat
repeat while (name of UI elements of ¬
toolbar "Navigation" of group 1 of ¬
window 1 whose description is "Reload") ¬
is not {"Reload"}
delay 0.1
end repeat
end tell
end tell
end waitForFirefoxPageToFinishLoading
Notes:
The example AppleScript code, shown above, was tested in Script Editor under macOS Catalina with Language & Region settings in System Preferences set to English (US) — Primary and worked for me without issue1.
1 Assumes necessary and appropriate settings in System Preferences > Security & Privacy > Privacy have been set/addressed as needed.
Tested using Firefox version 91.0 (64-bit).
Note that UI Scripting is very kludgy and is prone to failure, especially as the version of the OS and or application change, or the value of the delay commands are not sufficient. That said however, with Firefox, this as described herein is what it takes.
Note: The example AppleScript code is just that and sans any included error handling does not contain any additional 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. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.
I'm newbie to Appplescript. I need to automate certain actions on my computer related with my Bluetooth keyboards.
I want to be able to click on the remove or connect button of a keyboard in the following dialog window of the System Preferences Panel.
Dialog window
My code until this moment is as follows:
try
tell application "System Preferences"
activate
set current pane to pane "com.apple.preference.keyboard"
end tell
tell application "System Events"
tell process "System Preferences"
click button "Set Up Bluetooth Keyboard…" of window "Keyboard"
end tell
end tell
tell application "System Events"
tell group 1 of window 1 of application process "System Preferences"
click button "remove" of "Home Keyboard"
end tell
end tell
end try
My problem is related with the remove button since is unidentified cell of an unidentified table. With unidentified, I mean without description. Maybe there is an easy solution, but I'm not able to find it. Furthermore, It could happen that more than one keyboard exists, so I need to identify the cell from the Keyboard name.
Do you know any hint related with this issue?
Thanks in advance
Here is a sample script I used to reconnect a specific mouse via Bluetooth :
tell application "System Events"
tell application "System Preferences"
activate
reveal anchor "MouseTab" of pane id "com.apple.preference.mouse"
end tell
tell application process "System Preferences"
click button "Configuration of Bluetooth mouse…" of window 1 -- see note 1
delay 1
select (first row of table 1 of scroll area 1 of sheet 1 of front window whose value of item 1 of static text of UI element 1 contains "Mouse") -- see note 1
get value of item 1 of static text of UI element 1 of row 2 of table 1 of scroll area 1 of sheet 1 of front window
click button "Done" of sheet 1 of front window -- see note 1
end tell
tell application "System Preferences" to quit
end tell
Note 1 : Be careful about the 3 lines with comment 'see note 1' : the value of the string may be different for your local language. Please adjust these 3 values.
I think for keyboard, concept should be very similar. Because it is using GUI scripting, if Apple changes the layout of Bluetooth screen preferences, it must be adjusted. This script works from Yosemite to ElCaptain.I can't test it for next systems.