Is there a way to send a key code to a specific Safari tab, with Safari staying in the background?

Hello all,

I want to send key code 124 (the right arrow key) to the first tab of window 1, with Safari staying in the background.

Is this possible?

Alternatively—instead of the tab by the position, the tab by its URL (example: overcast.fm).

It does not appear possible in my testing.

You can use GUI scripting with an app that does not have the focus. For example, the following works if Script Debugger has the focus and Safari is also open:

tell application "System Events" to tell process "Safari"
	click menu item "New Window" of menu "File" of menu bar 1
end tell

However, given the same circumstance, the following script moves the cursor down in Script Debugger, which appears contrary to the System Events dictionary. However, it does work if you first set Safari to frontmost, but that’s not what you want.

tell application "System Events" to tell process "Safari"
	-- set frontmost to true -- Safari scrolls if this is enabled
	delay 0.5
	key code 125 -- scrolls down in the script editor with above line disabled
end tell

You could set Safari to frontmost, perform the key code, then switch back to the original app, but that’s pretty kludgey.

tell application "System Events"
	set activeApp to name of first process whose frontmost is true
	tell process "Safari"
		set frontmost to true
		delay 0.3 -- test different values or use repeat loop
		key code 125
	end tell
	delay 0.3 -- test different values or use repeat loop
	tell process activeApp to set frontmost to true
end tell

BTW, I used the down-arrow key because it was easier to test with.

1 Like

And what action would sending this code cause in Safari?
You could try to replicate the result using GUI scripting which doesn’t need the app to be in the front to work.

I was curious which menu commands work without Safari being frontmost, and the only ones I could find were New Tab and New Window. Those that didn’t work include Show Sidebar, Reload Page, Show Next Tab, Close Tab, and Zoom In.

I retested my third script in my earlier post, and on my computer the delays are not necessary. If they are deleted, the screen movement from the active app to Safari and back is almost imperceptible, possibly making this script usable. Unfortunately, the script pauses midpoint if run by way of a keyboard shortcut with FastScripts, although this doesn’t happen if the script is run by way of the Script Menu. I don’t know the reason for this.

No, it’s not possible.

Unlike menu items which have a physical reference and can be accessed even if the app is in the background keystrokes are sent always to the active/ frontmost application.

1 Like

Hello all,

I have figured out a workaround, and will post it below, on the chance that it helps someone in the future.

The challenge arises from the absence of an Overcast app for my Intel MacBook Pro.

Overcast.fm allows me to play my subscribed podcasts on a web page—it syncs up with my iOS Overcast app, which is very useful.

When the Overcast.fm page is at the front, the right arrow key triggers a skip 30 seconds feature, which I use frequently (hence my goal of scripting it).

The Mac’s media key for forward only works if you hold it down, so I wanted to find a way to trigger the 30 second skip, while keeping the overcast.fm web page in the background, while I work in other apps.

The following script uses workarounds to achieve this. Thus far, it tests well, and Safari stays in the background.

First, it locates the tab with Overcast.fm, and makes it the current tab (this tab needs to be the front tab, for the following to work).

Then, it uses a JavaScript line to identify the skip button by its id, and clicks it.

I know that the workaround is a little ugly, but I am happy to have a functional solution. Thank you to all that replied—you kept me working on this.

Here is the script, for those that are interested:

tell application "Safari"
	set windowsList to index of every window
	repeat with i in windowsList
		try
			tell window i
				set current tab to (first tab whose URL contains "overcast.fm")
			end tell
			set index of window i to 1
		end try
	end repeat
	do JavaScript "document.getElementById('seekforwardbutton').click();" in document 1
end tell

Ah, now it’s clear. You, like some here, mean one thing, but ask a completely different question.

1 Like

Unfortunately, the script pauses midpoint if run by way of a keyboard shortcut with FastScripts, although this doesn’t happen if the script is run by way of the Script Menu. I don’t know the reason for this.

When FastScripts detects that it is running a script that synthesizes keystrokes, it waits for keystrokes that invoked the script to be released before continuing execution. This is to prevent the invocation keystrokes from getting combined with the synthesized keystrokes, leading to unexpected results. Maybe this is related to the delay you saw?

1 Like

@redsweater. I think that’s the reason.

I’ve indicated in the following script the point at which the script pauses, and it happens just prior to the synthesized keystrokes.

tell application "System Events"
	set activeApp to name of first process whose frontmost is true
	tell process "Safari"
		set frontmost to true
		delay 0.5
		-- the script stops here until the keyboard shortcut keys are released
		key code 125
	end tell
	delay 0.5
	tell process activeApp to set frontmost to true
end tell

Thanks for the explanation.

1 Like

Glad to hear that explains it! Trust me, you wouldn’t want the script to keep running until you release the keys … one of the many hard-won lessons of developing FastScripts for 20 years! :joy:

1 Like