2

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.

10
  • What are you actually trying to set? Have you considered defaults write instead?
    – Tetsujin
    Jun 10 at 8:06
  • I'm trying to hide Wi-Fi icon from menu bar.
    – Maciej
    Jun 10 at 10:36
  • Ah, that one's not so easy because it's an array - see superuser.com/questions/398071/… You could do it in a GUI script though - macscripter.net/viewtopic.php?pid=205986
    – Tetsujin
    Jun 10 at 10:58
  • Please include your OS version as System Preferences change routinely.
    – Mockman
    Jun 11 at 11:09
  • 1
    @Tetsujin, RE: "sorry, my hands-on experience with Big Sur is almost nil" -- Understandable, and I just wanted you to know. -- The issue the OP is having is due to the changes Apple has made in macOS Big Sur compared to previous version of macOS and I mention that in my answer and why kludgy UI Scripting needs to be used in this use case. Even writing directly, e.g. defaults write com.apple.controlcenter "NSStatusItem Visible WiFi" -bool false requires a reboot, as I've not found killing any particular process to force it to use the new value works. Jun 11 at 14:04
0

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .