How to script Safari to bring to front and focus on a specific window?

Kind of a rudimentary question, but I did a Search and found no answer. When you have several windows open in Safari, how do you bring a specific window (whose window title/name you know) to the front and get Safari to give it the focus? Thanks!

Hello.

This should help you, the take away, is that you set the index of a Safari window to 1 in order to bring it to front.

tell application "Safari"
	set {theUrl, foundwin} to {URL of its document 2, 0} # 2 is the number of the window we are looking for . . . 
	repeat with i from 1 to count its windows
		try
			if URL of current tab of its window i = theUrl then
				set foundwin to id of window i
				exit repeat
			end if
		end try
	end repeat
	
	if foundwin is not 0 then
		set newdoc to make new document
		set index of its window id foundwin to 1
		close newdoc
	end if
end tell

Edit

Added Chris Stone’s way of making activating another window work.

there is no actual benefit of using its everywhere.
It’s only needed in case of a reference ambiguity, but there in none in Safari

That is right, but it is very annoying when you have left out an “its” you should have written.
I am lazy with “its”, and “my” too, it probably adds a couple of bytes of compiled code, and adds probably some milliseconds to the execution speed, whereas finding the culprit may take somewhat longer to figure out and fix. :slight_smile:

Besides that, I actually like to write AppleScript with more complete “sentences”, whether the articles and preposititions are necessary or not.

“complete sentences” is


activate  application "Safari"
	set {theUrl, foundwin} to {URL of  document 2 of application "Safari", 0} # 2 is the number of the window we are looking for . . . 
	repeat with i from 1 to count windows of application "Safari"
		try
			if URL of current tab of window i of application "Safari" = theUrl then
				set foundwin to i
				log "fond: " & foundwin
				exit repeat
			end if
		end try
	end repeat
	
	if foundwin is not 0 then
		set index of window foundwin of application "Safari"  to 1
	end if


But of course this does not compile

Now adding “its” makes the stream of speech pretty bumpy

:wink:

Thanks McUsrII. Your script brings the desired window to the front, visibly, but it does not “focus” it (ie, make it active). The title bar is grey, and a different window behind it actually has the focus. I’m looking for a method that is equivalent to clicking on a window so that it both comes to the front and has the focus. Maybe it can’t be done? Thanks again.

Hello.

There is actually a way that still works, it is the one that ccstone uses in his choose safaritabs script. I have updated the script above, using his way of creating a new document, and then closing it, to make the “activated one” stick! :slight_smile:

Success, McUsrII!

It’s not a direct command as I had hoped, but once you get the window you want visibly in front it’s just as you wrote:

 	set newdoc to make new document
close newdoc 

and voila, the front window now also has the focus.

Many thanks!

Hi,

Another way to do it is use the visible property. Suppose you have three windows and want to move window 2 to front:

tell application "Safari"
	activate
	set visible of window 2 to false
	-- window 2 becomes last window
	set visible of window 3 to true
	-- window 2 becomes window 1 and window 1 becomes window 2
end tell

So, all you need to do is set visible of the window that you want frontmost to false. Then set visible of the last window to true.

I don’t know which is best or quicker.

Edited: rewrote it using the window count:

tell application "Safari"
	activate
	set c to count (windows)
	set visible of window 3 to false
	set visible of window c to true
end tell

gl,
kel

Rewrote example script:

tell application "Safari"
	activate
	-- get window names
	set window_names to name of every window
	-- choose a random window name
	set rand_window_name to some item of window_names
	-- count the windows
	set window_count to count window_names
	-- get window index
	repeat with i from 1 to window_count
		if rand_window_name is item i of window_names then exit repeat
	end repeat
	-- move the window to last window
	set visible of window i to false
	-- bring last window to front
	set visible of window window_count to true
end tell

Thanks kel1. When I set the visible of a Safari window to false, it doesn’t go to the back, it just closes. This is on Mavericks 10.9.4 with the WindowMizer app running.

If you want to identify the window by name (title), this works in 10.9


tell application "Safari"
	try
		set theWindow to 1st window whose name begins with "MacScripter"
		activate
		set index of theWindow to 1
	end try
end tell

Hi Stefan,

Yes, I originally was thinking that. Thanks!

Edited: updated script:

tell application "Safari"
	activate
	-- get window names
	set window_names to name of every window
	-- choose a random window name
	set rand_window_name to some item of window_names
	-- count the windows
	set window_count to count window_names
	-- get window index
	set window_index to index of first window whose name is rand_window_name
	-- move the window to last window
	set visible of window window_index to false
	-- bring last window to front
	set visible of window window_count to true
end tell

Have a good day,
kel

Hello kel.

Nice that you figured out another way to do it, that doesn’t involve creating and closing documents. However ever, it would be even better if you accessed the window by name, instead of using two different indexes, since there may be hidden documents and windows in Safari that aren’t for the user (at least it was like this in earlier versions, maybe with the usage of add-ons). That way, you’ll always end up with the correct window in front.

Edit

If you know for sure that the window will be put at the last position when visible is set to false, also when other windows are invisible, then please disregard this post.

Hi McUsr,

Yes, I thought about the fact that there may be other hidden windows. That needed more looking into. Perhaps looking into ‘exists some window whose visible is false’. What I was thinking was that I don’t hide windows, so it is mainly for my preference. Also, was thinking about your check if there are no windows (i.e. the count is zero).

It seems to me that we have discussed these same issues about windows in the past. :slight_smile: A quick search through Macscripter showed many posts on this subject. I was also looking into the AXRaised and other System Events actions and I’ve noticed that ui scripting has changed drastically in Yosemite. Also, looked into javascript window.focus(). It doesn’t work in Safari.

It’s fun checking out this new system.

Edited: just remembered one thing I was thinking about the visible method. Switching windows might be taking time. I might have to bring out the timer. :smiley:

Have a good day,
kel

It’s hard to time this. In the first place, how do you know the name of the window?

Edited: for instance, it can be hard coded into the script.

Hi kerflooey,

Personally, I would try to upgrade everything as soon as possible. Then, you can work out the kinks. To me it’s better to try to roll your own apps, then you can modify them and also don’t need to wait for updates. It’s hard man.

Edited: and also, you can always get help here if you need it! Most of the time. :slight_smile:

gl,
kel