script works in editor, but not when saved as an application

Sorry if this is a general issue, but I failed to discover the right search terms.

The following applescript moves the frontmost window (I got it from another website). I have two (with different locations) and use them to move in between my two monitors (one is a TV in my exercise room so it isn’t visible from the computer itself where the other monitor is located).

tell application "System Events"
	set theWindow to window 1 of (first process whose frontmost is true)
	set position of theWindow to {0, 15} -- Set this to the appropriate x,y coordinates
end tell

They work fine when run from the script editor (although naturally this means the applescript editor is the window being moved), but when I save them as applications so I can use them with my remote (it has the option to execute an application when a button is pressed), I get the following error. Double clicking or using the remote yields the same behavior.

Can’t get window 1 of <> 1 of application “System Events” whose frontmost = true. Invalid index.

Unfortunately, I’m not knowledgable enough to hazard a guess as to what’s going wrong. Any advice would be greatly appreciated. Thanks very much.

System Events doesn’t have a window. How will your script know which of other open applications “owns” the window you want to move?

Afraid I copied the script from another source, so my understanding of the details is (very) poor. I assumed the “first process whose frontmost is true” part covered selecting the process with the front most window. I’m certainly not wed to this code, but, as I mentioned, It works fine when run in the editor which is perplexing. In case somehow it is useful, here’s where I got it from. It’s in the second reply. Thanks again.

http://emperor.tidbits.com/webx?14@@.3c7b1ae3/5

It means that the frontmost process ” which is no doubt your script application ” doesn’t have a window (open). You could try some variation on this:

tell application "System Events"
	-- Set the visible of (presumaby) the script application to false so that the next frontmost process comes to the front.
	set myProcess to first application process whose frontmost is true
	set visible of myProcess to false
	repeat while (myProcess is frontmost)
		delay 0.2
	end repeat
	
	set theWindow to window 1 of (first application process whose frontmost is true)
	set position of theWindow to {0, 15} -- Set this to the appropriate x,y coordinates
end tell

I didn’t realize “frontmost” would apply to apps without windows, but it makes perfect sense and works great. Thanks!

Oddly, the script works great unless I set the VLC window to fullscreen and then back again (which would be my standard viewing behavior). I can see the script’s application running, and nothing else is being moved, but the VLC window stays put (as does the VLC controller). Clicking on it again to make sure it’s frontmost does not affect it. Other windows will continue to work with the script if I bring them to the fore. Quitting VLC and launching the video again resets things. Any insights as to why this may be occurring? Thanks a lot.

UPDATE: did some testing and going into fullscreen doesn’t affect Google Chrome windows similarly, so somehow VLC is different. This does not bode well.

If you play around with windows a bit, you’ll discover that quite a few applications have different ways of handling them. You really have to special case the apps whose windows you want to deal with. For example on my Leopard machine I get this:

tell application "VLC"
	set W to windows
end tell

W --> {window id 1334, window id -1, window id -1, window id -1, window id 1333, window id -1, window id -1, window id -1}

and only the first of those shown in the list is the VLC media player empty window. Not showing, but in the list are all the others in VLC’s Windows menu.

I really only care about VLC anyway, so I’ll play around with it. Thanks for your help.

Update: It was easy enough once I figured out that “position” wasn’t supported by VLC windows; I just used “bounds”. I changed it to toggle back and forth with a single button press. Fullscreen was weird, so if it’s in that mode, I just turn it off and then on again after the move. If there’s a better way to do any of this, I am all ears (eyes?). Thanks again to everyone who lent a hand; I learned a lot doing this. Pretty simple, but in case it proves useful to anyone else, here it is:

-- width of monitor 1, used to determine which screen the window is on
property monitor1_width : 1680

-- position on monitor1 to move window to
property home1_x : 0
property home1_y : 15 -- clear menu bar

-- position on monitor2 to move window to
property home2_x : 1680
property home2_y : 0 -- no menu bar on HDTV

tell application "VLC"
	set fullSave to fullscreen mode -- preserve fullscreen status
	
	-- if in fullscreen, turn it off (will be restored at the end)
	if fullSave then
		tell application "VLC" to fullscreen
	end if
	
	set W to windows
	repeat with win in W
		if visible of win is true then -- don't move invisible windows
			if (name of win) is not equal to "VLC media player" then -- don't move controls
				
				-- get current bounds of window (position does not apear to be supported in VLC)
				set currbounds to bounds of win
				
				-- assume moving to monitor 1
				set x0 to home1_x
				set y0 to home1_y
				
				-- if already on monitor 1, move to monitor 2
				if item 1 of currbounds < monitor1_width then
					set x0 to home2_x
					set y0 to home2_y
				end if
				
				-- compute window size
				set win_width to (item 3 of currbounds) - (item 1 of currbounds)
				set win_height to (item 4 of currbounds) - (item 2 of currbounds)
				
				-- update window bounds
				set bounds of win to {x0, y0, x0 + win_width, y0 + win_height}
				
			end if
		end if
	end repeat
	
	-- if it was in fullscreen, restore
	if fullSave then
		tell application "VLC" to fullscreen
	end if
	
end tell