Change Safari Download location

I have a simply script that allows me to change where downloads from Safari are stored. What I cannot figure out is how to close the window after the selection is made. The following script opens the down load window and asks if the location is correct. I have tried repeat loops but the timing just does not seem to work. The script has a 5 second delay which works if I am quick enough but that is a crude solution.

Any suggestions will be very much appreciated .


activate application "Safari"
tell application "System Events"
	tell application process "Safari"
		-- Select General tab
		click menu item 4 of menu 1 of menu bar item "Safari" of menu bar 1
		delay 1
		--Get Name of Download Folder
		set Dl to value of pop up button 2 of group 1 of group 1 of window "General"
		--Check if correct folder
		display dialog "Is this  the correct location for Downloads. " & Dl buttons {"Yes", "No"}
		if button returned of result is "Yes" then
			return
		else
			click pop up button 2 of group 1 of group 1 of window "General"
			--delay 1
			tell application "System Events"
				key code 125
				key code 125
				key code 76
				delay 5
				tell process "Safari"
					click button 1 of window 1
				end tell
				
			end tell
		end if
	end tell
end tell
tell me to activate


Here is an other way to do the job.

set aBundle to ((path to library folder from system domain as text) & "PrivateFrameworks:Safari.framework:") as «class furl»
set general_loc to localized string "General" in bundle aBundle

activate application "Safari"

tell application "System Events"
	tell application process "Safari"
		set frontmost to true
		keystroke "," using {command down}
		repeat 20 times
			try
				if name of buttons of toolbar 1 of window 1 contains general_loc then exit repeat
			on error
				-- here if no window is open
			end try
			delay 0.1
		end repeat
		tell window 1
			if its name is not general_loc then -- It's the General window, no need to switch.
				-- class of UI elements --> {group, button, button, button, toolbar, static text}
				tell toolbar 1
					-- class of UI elements --> {button, button, button, button, button, button, button, button, button, button}
					-- name of buttons --> {"Général", "Onglets", "Remplissage automatique", "Mots de passe", "Recherche", "Sécurité", "Confidentialité", "Sites web", "Extensions", "Avancées"}
					click button general_loc -- select pane "General"
				end tell
				repeat 50 times
					if its name is general_loc then exit repeat
					delay 0.1
				end repeat
			end if
			tell group 1
				-- class of UI elements --> {group}
				tell group 1
					-- class of UI elements --> {button, pop up button, static text, text field, static text, button, static text, checkbox, pop up button, static text, pop up button, static text, static text, static text, pop up button, pop up button, pop up button, static text, static text, static text, pop up button, pop up button}
					-- name of pop up buttons--> {"Au démarrage, Safari ouvre :", "Emplacement de téléchargement des fichiers :", "Supprimer la liste des téléchargements :", "Meilleurs sites affichés :", "Les nouveaux onglets ouvrent :", "Supprimer les éléments de l’historique :", "Favoris affichés :", "Les nouvelles fenêtres ouvrent :"}
					set currentLoc to value of pop up button 2
				end tell -- group
			end tell
			--Check if it's correct folder
			display dialog "Is this  the correct location for Downloads." & linefeed & currentLoc buttons {"Yes", "No"}
			if button returned of result is not "Yes" then
				tell group 1 to tell group 1 to tell pop up button 2
					click it
					tell menu 1
						-- name of menu items--> {"Téléchargements", missing value, "Demander pour chaque téléchargement", "Autre emplacement…"}
						click menu item -1
					end tell -- menu
				end tell
				repeat 20 times
					if exists sheet 1 then exit repeat
					delay 0.1
				end repeat
				delay 0.2
				repeat 600 times
					-- Now the window allowing you to select the destination is open.
					if not (exists sheet 1) then exit repeat
					-- You will stay here as long as you will not validate your choice
					delay 1
				end repeat
			end if
			click button 1 -- close the Preferences window
		end tell
	end tell
end tell

Just for curious readers, here is the beginning of my original proposal, when I hadn’t found how to grab the localized name of the “General” window.

tell application "Safari"
	activate
	set openWith_loc to localized string "100177.title" from table "GeneralPreferences" --> "Au démarrage, Safari ouvre :" 
	-- at least in in High Sierra and Mojave, the English value of this string is not accessible
	if openWith_loc is "100177.title" then set openWith_loc to "Safari opens with:" -- check that it's the correct English spelling
end tell

tell application "System Events"
	tell application process "Safari"
		set frontmost to true
		-- Select General tab
		keystroke "," using {command down}
		delay 1
		tell window 1
			-- class of UI elements --> {group, button, button, button, toolbar, static text}
			tell toolbar 1
				-- class of UI elements --> {button, button, button, button, button, button, button, button, button, button}
				-- name of buttons --> {"Général", "Onglets", "Remplissage automatique", "Mots de passe", "Recherche", "Sécurité", "Confidentialité", "Sites web", "Extensions", "Avancées"}
				click button 1 -- select pane "General"
			end tell
			-- set wName to its name --> "Général"			
			tell group 1
				-- class of UI elements --> {group}
				tell group 1
					-- class of UI elements --> {button, pop up button, static text, text field, static text, button, static text, checkbox, pop up button, static text, pop up button, static text, static text, static text, pop up button, pop up button, pop up button, static text, static text, static text, pop up button, pop up button}
					-- I am unable to extract the localized name of the window "General" so I use a workaround.
					repeat 50 times -- wait for the availability of window "General"
						if exists (first static text whose value is openWith_loc) then exit repeat
						delay 0.2
					end repeat
…

Of course, you may delete the instructions which are disabled.
They were useful to build the script.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 2 mars 2020 19:40:45

Tested on my Mojave system:


set downloadsFolder to quoted form of POSIX path of (choose folder)

tell application "Safari" to quit
tell application "System Events"
	repeat while application process "Safari" exists
		delay 0.1
	end repeat
end tell

do shell script ("defaults write com.apple.Safari DownloadsPath " & downloadsFolder)

-- only to show the result:
display dialog "The Downloads location was changed "

Thank you that is perfect and simple.

You are welcome.

NOTE: for some folders the system asks the user to confirm new downloads location. I don’t know why, and what criteria the system uses. So, the script in the full form should be like this:


-- choose new location
set downloadsFolder to quoted form of POSIX path of (choose folder)

-- quit "Safari" reguired
tell application "Safari" to quit
tell application "System Events"
	repeat while application process "Safari" exists
		delay 0.1
	end repeat
end tell

-- make changes 
do shell script ("defaults write com.apple.Safari DownloadsPath " & downloadsFolder)

-- if the system asks to confirm the new location, then confirm it
tell application "Safari" to activate
tell application "System Events" to tell application process "Safari"
	keystroke "," using command down
	repeat until window 1 exists
		delay 0.1
	end repeat
	if name of window 1 is "Open" then click button "Open" of window "Open"
end tell

-- inform the user above the changes
tell application "Safari"
	display dialog "The Downloads location was changed"
	close windows
end tell

Hi, I apologise but your solution that has been working now does not. I have changed to a MacMini running Ventura 13.2.1 and Safari 16.3. Do you know of any reason your solution would not work. I really am embarrassed to ask but it had taken me a long time until I got your solution.