dual monitor - move window to other display and maximize

I’m looking for a script that will move my active window to the second display (or the opposite) and then maximize that window in the display. I’ve searched the forum and couldn’t find one.

Thanks!

The script below could definitely be put in a more generic form; as it is it has grown by occasional additions and I’ve never taken the time to shrink it where there are obvious repetitions. I use it when I screen share my machine (with dual screens) from a laptop – the second screen does not show up so this script simply moves windows appearing on it to my main screen. It contains all the ingredients you need to do your task except maximizing the window. The script is a derivative of a much more generic approach by Nigel Garvey, so if you search on his name, you might find it.

-- Get screen bounds and origins
set f to (path to preferences from local domain as Unicode text) & "com.apple.windowserver.plist"
tell application "System Events" to set {{|Width|:w1, |Height|:h1, |OriginX|:OX1, |OriginY|:OY1}, {|Width|:w2, |Height|:h2, |OriginX|:OX2, |OriginY|:OY2}} to value of property list items of property list item 1 of property list item "DisplaySets" of property list file f
set SecondaryScreenBounds to {OX2, OY2, OX2 + w2, OY2 + h2}
set RHedge to OX1
set BOTedge to OY1

tell application "Finder"
	-- Get the running apps (excluding those with special windows)
	set |running| to name of processes whose visible is true and name is not "Finder" and name is not "QuickSilver" and name is not "CopyPaste" and name is not "DropCopy" and name is not "iPulse"
	repeat with anApp in |running|
		try -- for a scriptable App with window bounds property
			tell application anApp
				set allWindows to (every window)
				repeat with aWindow in allWindows
					set Wbounds to (get bounds of aWindow)
					if item 1 of Wbounds > RHE or item 2 of Wbounds > BoE then my moveWindows(contents of anApp)
				end repeat
			end tell
		on error -- for an App with window position & size properties
			tell application "System Events"
				tell application process anApp
					set allWindows to (every window)
					repeat with aWindow in allWindows
						set {p1, p2} to aWindow's position
						if p1 ≥ RHedge or p2 ≥ BOTedge then my moveWindows(contents of anApp)
					end repeat
				end tell
			end tell
		end try
	end repeat
	-- for the Finder
	set allWindows to (every window whose visible is true)
	repeat with aWindow in allWindows
		set Wbounds to bounds of aWindow
		if (item 1 of Wbounds) > RHedge or (item 2 of Wbounds) > BOTedge then
			set bounds of aWindow to {200, 200, 1200, 800}
		end if
	end repeat
end tell -- end of Finder
-- for Safari
if "Safari" is in |running| then tell application "Safari"
	set Wind to name of windows
	set Wbounds to bounds of windows
	repeat with k from 1 to count Wind
		set W to item k of Wind
		set B to item k of Wbounds
		if (item 1 of B) ≥ RHedge or (item 2 of B) ≥ BOTedge then
			set bounds of window W to {200, 200, 1200, 800}
		end if
	end repeat
end tell
-- for HoudahSpot
if "HoudahSpot" is in |running| then tell application "System Events" to tell process "HoudahSpot"
	set W to name of windows
	set B to position of windows
	repeat with k from 1 to count W
		if item k of W is not missing value and (item 1 of item k of B) ≥ RHedge then set position of window (item k of W) to {100, 100}
	end repeat
end tell
-- Script Debugger
if "Script Debugger 4.5" is in |running| then tell application "System Events" to tell process "Script Debugger 4.5"
	set W to name of windows
	set B to position of windows
	repeat with k from 1 to count W
		if item k of W is not missing value and (item 1 of item k of B) ≥ RHedge then set position of window (item k of W) to {100, 100}
	end repeat
end tell
-- for Activity Monitor
if "Activity Monitor" is in |running| then tell application "System Events" to tell process "Activity Monitor"
	set W to name of windows
	set B to position of windows
	repeat with k from 1 to count W
		if item k of W is not missing value and (item 1 of item k of B) ≥ RHedge then set position of window (item k of W) to {100, 100}
	end repeat
end tell
-- for 1Password
if "1Password" is in |running| then tell application "System Events" to tell process "1Password"
	set W to name of windows
	set B to position of windows
	repeat with k from 1 to count W
		if item k of W is not missing value and (item 1 of item k of B) ≥ RHedge then set position of window (item k of W) to {100, 100}
	end repeat
end tell
-- for iCal
if "iCal" is in |running| then tell application "iCal"
	set iCB to bounds of window "iCal"
	if item 1 of iCB ≥ RHedge or item 2 of iCB ≥ BOTedge then
		set bounds of window "iCal" to {100, 100, 1200, 1000}
	end if
end tell
-- for a Help Window
tell application "System Events"
	if exists process "Help Viewer" then tell process "Help Viewer"
		set W to windows
		repeat with w1 in W
			set position of w1 to {200, 200}
		end repeat
	end tell
end tell

to moveWindows(anApp)
	tell application "System Events"
		if anApp is "ScriptLight" then
			tell process "ScriptLight" to set position of window 1 to {200, 200}
		else if anApp is "PowerKey" then
			tell process "PowerKey" to set position of window "PowerKey" to {200, 200}
		else if anApp is "Script Debugger 4" then
			tell application process "Script Debugger 4"
				set allWindows to (every window)
				repeat with aWindow in allWindows
					set {p1, p2} to aWindow's position
					if p1 ≥ 1680 or p2 > 1050 then set aWindow's position to {100, 100}
				end repeat
			end tell
		end if
	end tell
end moveWindows

thanks a lot, i’ll see if i can make it work!

ok so i wasn’t able to get Adam’s script to work, however I’ve got something that’s pretty close. My left display is 1680x1050 and my right display is 1050x1680. this script is working for windows in the left display, but windows in the right display seem to be moving in the wrong direction (to the right instead of left)…I think the math might be wrong. Any ideas?

EDIT: I realized that even windows on the left display are moving too far to the right (almost off the viewport) before they are maximized.

tell application "System Events"
	set hasNowindow to {}
	repeat with i in (get processes)
		try
			if (frontmost of i is true) then
				set frontWindow to window 1 of i
				set frontWindowPos to position of window 1 of i
				set appname to name of i
				set W to item 1 of frontWindowPos
				set h to item 2 of frontWindowPos
				if (W > 1680) then -- then it is in the right window
					set newWidth to (((W - 1680) / 1050) * 1680)
					set newHeight to ((((h + 520) / 1680) * 1050) + 22)
					
				else --then it is in the left
					set newWidth to (((W / 1680) * 1050) + 1680)
					set newHeight to (((h / 800) * 1680) - 548)
				end if
				-- display dialog appname
				
				-- choose from list frontWindowPos
				tell application appname
					set position of frontWindow to {newWidth, newHeight}
				end tell
			end if
			--exit repeat -- have the frontmost
		on error
			set end of hasNowindow to name of i
		end try
	end repeat
	
	
	tell application "System Events" to click (first button whose subrole is "AXZoomButton") of (first window whose subrole is "AXStandardWindow") of (first process whose frontmost is true)
	
end tell

What does this much of my script tell you? I assume you have rotated one of your screen into a portrait position, but don’t know what the window server does with that.

set f to (path to preferences from local domain as Unicode text) & "com.apple.windowserver.plist"
tell application "System Events" to set {{|Width|:w1, |Height|:h1, |OriginX|:OX1, |OriginY|:OY1}, {|Width|:w2, |Height|:h2, |OriginX|:OX2, |OriginY|:OY2}} to value of property list items of property list item 1 of property list item "DisplaySets" of property list file f
set SecondaryScreenBounds to {OX2, OY2, OX2 + w2, OY2 + h2}

it outputs: {1680, 0, 2730, 1680}

my right display is portrait btw. left display is the primary (in landscape).