Using Accessibility Inspector, a part of Xcode, it shows that some of the time the Announce the time: checkbox reports "Parent does not report element as one of its children" and as such will cause AppleScript code to fail under certain conditions, and under other conditions not fail. In other words, writing my own code I can get it to check that checkbox sometimes and not other times.
In trying to ascertain a pattern to see how to workaround this situation I came to the conclusion that using fully visible UI Scripting was the most reliable way. It's also unfortunately an ugly way and requires letting the script finish without interruption once started, otherwise it will fail for sure. Such are the pitfalls of fully visible UI Scripting.
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 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.
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
-- # 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 Clock row of the Dock & Menu Bar pane.
-- #
-- # This UI Script needs it to be visible, hence the activate command.
tell application "System Preferences"
activate
reveal anchor "Clock" of ¬
pane id "com.apple.preference.dock"
end tell
delay 1
-- # Tab to the 'Announce the time:' checkbox and toggle it.
tell application "System Events"
repeat 9 times
key code 48 -- # tab key
delay 0.2
end repeat
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.5
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 ≥ 20 then return
end repeat
click checkbox 1 of tab group 1
end tell
end tell
end toggleKeyboardNavagition
- Note that because of the comments and coding style the script is long. It ends with
end toggleKeyboardNavagition
, so make sure you highlight all of it when copying and pasting to Script Editor for testing.
Notes:
In the tell application "System Events"
block in with there is the repeat 9 times
loop that does the tabbing in order to toggle the Announce the time: checkbox, the value of the delay
command may need to be adjusted.
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.