OS X – applescript to move all windows onto the screen

When switching from multiple monitors to a single monitor, some windows may be inaccessible due to being off the screen. They can be brought back by knowing the keyboard shortcuts for moving windows, but that’s a pain. Here’s an applescript that will bring them all back onto the visible screen:

-- original script from http://www.macosxtips.co.uk/index_files/move-all-windows-to-main-display.php
-- thanks to Matt Swain

-- Script modified and error handling added by Dustin Caldwell

-- put processes not to move into this array
property processesToIgnore : {}

-- get the bounds of the desktop
tell application "Finder"
	set desktopBounds to bounds of window of desktop
	set screenWidth to item 3 of desktopBounds
	set screenHeight to item 4 of desktopBounds
end tell

set r1 to "" -- return value
set crlf to (ASCII character 10)
set showAADError to 1 -- if every attempt to look at a window fails, then show error dialog at the end

tell application "System Events"
	set newWindowLeft to 0
	set newWindowTop to 22
	set allProcesses to application processes
	set r1 to r1 & (count allProcesses) & " processes to check" & crlf
	-- loop through all processes looking for windows to move
	repeat with i from 1 to count allProcesses
		try -- catch any errors nicely

			-- check the list of processes to ignore
			set doIt to 1
			repeat with z from 1 to count processesToIgnore
				if process i = process (item z of processesToIgnore) then
					set doIt to 0
				end if
			end repeat

			if doIt = 1 then
				tell process i
					-- loop through all windows for this process to see if any are off the screen
					repeat with x from 1 to (count windows)
						try
							set winPos to position of window x
							set winLeft to item 1 of winPos
							set winTop to item 2 of winPos
							set winSize to size of window x
							set winRight to (item 1 of winSize) + winLeft
							set winBottom to (item 2 of winSize) + winTop
							if ((winLeft < 0) or (winTop < 0) or (winRight > screenWidth) or (winBottom > screenHeight)) then
								set position of window x to {newWindowLeft, newWindowTop}
								set r1 to r1 & " moved window " & title of window x & crlf
								-- offset each window by 10 pixels for a nice effect
								set newWindowLeft to newWindowLeft + 10
								set newWindowTop to newWindowTop + 10
								-- if there are so many windows that they'd be moved off the screen, start again at the top left
								if (newWindowLeft > (screenWidth - 200)) or (newWindowTop > (screenHeight - 200)) then
									set newWindowLeft to 0
									set newWindowTop to 22
								end if
							end if
							set showAADError to 0 -- if we moved a window, then this isn't a problem
						on error errText
							set r1 to r1 & " ERROR " & errText & " for window " & title of window x & crlf
						end try
					end repeat
				end tell
			end if
		on error errText number errorNumber
			set r1 to r1 & " ERROR " & errText & " NUM=" & errorNumber & " for process " & title of process i & crlf
		end try
	end repeat
end tell
-- display a friendly message if access for assistive devices is disabled.
if (showAADError is equal to 1) then
	display dialog "Unable to move any windows. Access for assistive devices may be disabled. You must enable that for this script to run. You can do that in System Preferences -> Universal Access -> check box at bottom of window. (for OS X Lion)"
end if
-- uncomment the below to see the results in a dialog
-- display dialog r1
return r1

Revisions

No comments yet.

Leave a Reply