Why do I need to add the command “active” to make this script work?

I wrote a script to toggle the “Use dark menu bar and Dock” option from the “General” pane of “System Preferences”.

tell application "System Preferences"
	activate
	set current pane to pane "General"
	tell application "System Events"
		tell application process "System Preferences"
			click checkbox 3 of window "General"
		end tell
	end tell
	quit application "System Preferences"
end tell

This script won’t work on my Mac without the “activate” command in the “System Preferences” tell block.
I’ve written other GUI scripts that control “System Preferences” without the need for the “activate” command, and I prefer to do it that way so you don’t see the “System Preferences” window open when the script runs.

For example, here’s one that toggles the operation of the function keys…

tell application "System Preferences"
	set current pane to pane "Keyboard"
	tell application "System Events"
		tell application process "System Preferences"
			click radio button "Keyboard" of tab group 1 of window "Keyboard"
			click checkbox "Use all F1, F2, etc. keys as standard function keys" of tab group 1 of window Keyboard"
		end tell
		quit application "System Preferences"
	end tell
end tell

Can someone explain why I need to include the “activate” command in order to make the first script work whereas I don’t need it for the second script?

Hi.

Strictly speaking, GUI scripting only controls System Events. It’s System Events which then sends signals to the graphic user interface of process you want to affect. For this to be successful, the targeted UI element in the process has to exist and, sometimes, the process has to frontmost.

In this case, it looks as if your scripts are intended to launch System Preferences if it’s not already running. When this happens, System Preferences initially opens in the background as a hidden process and its window doesn’t actually exist (or at least can’t be accessed) until it becomes visible. Bringing the process to the front ” either by activating the application or setting the process’s ‘frontmost’ to true ” is one way to achieve this. Another way is simply to set the process’s ‘visible’ to true. Not having to bring it to the front makes the window visible for a shorter time in your scripts.

tell application "System Preferences" to set current pane to pane "General"

tell application "System Events"
	tell application process "System Preferences"
		set visible to true
		click checkbox 3 of window "General"
	end tell
end tell

quit application "System Preferences"

Thanks for the reply, and sorry for the late response.

So, basically, when GUI scripting “System Preferences” I can expect some settings to require the “System Preferences” window to be frontmost while others don’t need to be, eh? I would have thought that that would be universal among all “System Preferences” settings.

Regardless, thanks for the help, Nigel.