Move iTunes visualizer to second display

Hi,

Just figured out that I can drag the visualizer to the second display with Mission Control. Does anyone know how to do this programatically? Maybe there’s a cocoa method?

Thanks,
kel

Just thought of something that might work. Turn on Accessibilities’ drag lock. Then, somehow move the cursor to the second display. Yeah, I think it probably needs Accessibility. Hmmm, maybe.

Edited: somehow, it needs to get rid of the menu bar shadow in the visualizer, if possible.

Edited: I wonder if it’s possible to turn the menu bar background to black?

Edited: or transparent.

Later,
kel

Hello kel.

Maybe you can use this, combo of a library for figuring out the screens, (it stores a script later on in the caches directory, containing your current setup) It tests against this setup for each run, so that you have always the current configuration available, -it will rewrite the cache when said monitor configuration change, also with regard to resolution.

The second part is a teleport script, which moves a window from 1 screen to the other, placing it in the same position.

I hope you can use those bits, to move the iTunes window where you like to have it. Feel free to modify the scripts to suit your own needs. :cool:


# Most of the code Copyright McUsr (c) 2012 All rights reserverved.
# Version 17, there is a bug here, regarding minimized windows.
script Screens2
	property parent : AppleScript
	property _physScreens : (path to library folder from user domain as text) & "caches:" & "net.mcusr.screens"
	
	property numberOfScreens : missing value -- 1 for 1, 2 for 2
	
	property physScreens : missing value
	
	-- basis function
	
	to calcY for aScreen by aWinHeight given fromCenter:fromCenter, fromBottom:fromBottom -- for aWinPos	
		if fromBottom then
			-- PROBLEM:
			return ((_y of aScreen) + (_height of aScreen) - aWinHeight)
			-- return ((_height of aScreen) - aWinHeight)
		else if fromCenter then
			return ((((_y of aScreen) + ((_y of aScreen) + (_height of aScreen))) / 2) - aWinHeight / 2)
		end if
	end calcY
	
	to calcX for aScreen by aWinWidth given fromCenter:fromCenter, fromRight:fromRight
		
		if fromRight then
			return (((_x of aScreen) + (_width of aScreen)) - aWinWidth)
		else if fromCenter then
			return ((((_x of aScreen) + ((_x of aScreen) + (_width of aScreen))) / 2) - (aWinWidth / 2))
		end if
		
	end calcX
	
	
	
	to findAllWins for theScr from anApp
		-- bruken av denne rutinen:
		-- vi skal finne all vinduer på skjermen, slik at vi kan flytte alle sammen til venstre eller
		-- høyre for den saks skyld.
		-- kontekst er at vi har kalt opp rutinen etter at vi har "funnet" det første vinduet 
		-- og skjermen.
		
		-- tileggs problemer : filtrere utvinduer som ikke er på denne skjermen!
		
		-- utvidelser: 
		-- Kunne ekskludere, includere, og bare levere minimerte vinduer!
		
		
		-- nå ville det ha vært ok, å ha screen nummer her, når vi skal kikke etter vindu
		-- om vinduet er til venstre eller noe?
		global wc, psts, i, theId
		set psts to {}
		
		
		script o
			property m : missing value
		end script
		
		-- Find the frontmost
		
		set o's m to getVisibleWins for anApp
		if o's m = null then return null
		set wc to count o's m
		if wc = 0 then return null
		
		-- hit, nå har det seg så at vi skal filtrere 
		-- dette skal gå så fort som mulig, tror ikke filter er bra her, siden har to lister!
		
		set foundIt to false
		set i to 2
		repeat while i ≤ wc -- the first is the one we already got!
			set thisScr to findScreen for item 2 of item i of o's m with topleftcorner
			
			if nr of theScr = nr of thisScr then
			else
				set item i of o's m to missing value
			end if
			set i to i + 1
		end repeat
		
		set o's m to o's m's lists
		if o's m = {} then return null
		set o's m to reverse of o's m
		-- correct z-ordering for processing 
		return o's m
		
	end findAllWins
	
	to getVisibleWins for anApp
		local wnList, wn2list, wc, wc2
		
		set {failure, wc2} to {false, 0}
		set {wnList, wn2list} to {{}, {}}
		try
			tell application "System Events" to tell application process anApp to set wn2list to (get {name, position} of its every window)
			
			if wn2list is {} then
				return null
			else
				set wc2 to count item 1 of wn2list
				try
					using terms from application "TextEdit"
						tell application anApp
							set wnList to get {name, id} of (every window whose miniaturized is false and visible is true)
						end tell
					end using terms from
				on error e number n
					try
						using terms from application "Script Debugger 4.5"
							tell application anApp
								set wnList to get {name, id} of (every window whose minimized is false and visible is true)
							end tell
						end using terms from
					on error e number n
						try
							using terms from application "Finder"
								tell application anApp
									set wnList to get {name, id} of (every window whose collapsed is false and visible is true)
								end tell
							end using terms from
							-- we patch here for any  Spotlight windows
							if anApp is "Finder" then -- Smile also uses collapsed!
								set i to 1
								local wnname
								repeat wc2 times
									
									if item i of item 1 of wnList is "" then
										tell application "Finder" to set wnname to displayed name of target of Finder window index i
										set item i of item 1 of wnList to wnname
										set item i of item 1 of wn2list to wnname
									end if
									set i to i + 1
								end repeat
							end if
						on error e number n
							set failure to true
						end try
					end try
				end try
			end if
		end try
		
		set AppleScript's text item delimiters to "" -- convenience during debugging
		if failure then -- we have dealt with an we have to get the rest of the data, so we can do something meaningful
			try
				tell application "System Events"
					tell application process anApp to set wnList to (get {name, position} of its every window whose visible = true)
					
				end tell
			on error
				try
					tell application "System Events"
						tell application process anApp to set wnList to (get {name, position} of its every window)
					end tell
				end try
			end try
			set wc to count item 1 of wnList
			if wc = 0 then return null
			
			set wnList to transposeList(wc, item 1 of wnList, item 2 of wnList)
			return wnList
			
		else if wc2 = 0 then
			return null -- should have found 1 window before calling this one
		end if
		
		script o
			property sewl : wn2list
			property tsewl : missing value
			property apwl : wnList
			property tapwl : missing value
			property winIdList : {}
		end script
		set wc to count item 1 of wnList
		
		(* So what we want is a list with just visible, and not minimized windows 
	so, we'll make a list for every window that is visible and not minimized.
	Facts:
	The windows are layerd, the first window we get is the first window we get returned.
	the windows that will appear after the windows returned after system events by the application, is the windows not being in the current space.

	Conclusion:
	we have to filter and build the list we want based on those facts:
	*)
		
		
		set o's tsewl to transposeList(wc2, item 1 of o's sewl, item 2 of o's sewl)
		
		set o's tapwl to transposeList(wc, item 1 of o's apwl, item 2 of o's apwl)
		
		set i to 1
		repeat wc2 times
			set res to my getSingelton(o's tapwl, item 1 of item i of o's tsewl)
			if res = null then
			else
				set end of o's winIdList to {res, contents of item 2 of item i of o's tsewl}
				set o's tapwl to rmSublistByItem2(res, o's tapwl)
			end if
			set i to i + 1
		end repeat
		return o's winIdList
		
	end getVisibleWins
	
	
	to findScreen for winParams given topleftcorner:topleftcorner
		-- best to use just number outside?
		-- assumes that the window is capable of giving bounds object!
		if topleftcorner then
			
			if ((((item 1 of winParams) ≥ _x of physScreens's screen1) and (item 1 of winParams) < ((_x of physScreens's screen1) + (_width of physScreens's screen1))) and (((item 2 of winParams) ≥ _y of physScreens's screen1) and (item 2 of winParams) < ((_y of physScreens's screen1) + (_height of physScreens's screen1)))) then
				return physScreens's screen1
				
			else if ((item 1 of winParams) < _x of physScreens's screen1) and (item 2 of winParams) < ((_y of physScreens's screen1) + (_height of physScreens's screen1)) then
				
				return physScreens's screen1
				
			else if Screens2's numberOfScreens = 2 then
				
				if ((item 1 of winParams) ≥ _x of physScreens's screen2) then
					
					if (item 1 of winParams) < ((_x of physScreens's screen2) + (_width of physScreens's screen2)) then
						if (((item 2 of winParams) ≥ _y of physScreens's screen2) and (item 2 of winParams) < ((_y of physScreens's screen2) + (_height of physScreens's screen2))) then
							return physScreens's screen2
							
						else if ((item 1 of winParams) < (_x of physScreens's screen2)) then
							
							if ((_width of physScreens's screen2) + (_width of physScreens's screen1)) > (_width of physScreens's viritualScreen) then
								return physScreens's screen2
							end if
						end if
					end if
					
				else if ((item 1 of winParams) < (_x of physScreens's screen2)) then
					
					if ((_width of physScreens's screen2) + (_width of physScreens's screen1)) > (_width of physScreens's viritualScreen) then
						return physScreens's screen2
					else if ((_height of physScreens's screen2) + (_height of physScreens's screen1) + 22) = (_height of physScreens's viritualScreen) then
						return physScreens's screen2
					else if ((_height of physScreens's screen2) + (_height of physScreens's screen1) + 22) > (_height of physScreens's viritualScreen) then
						if ((_y of physScreens's screen2) < (item 2 of winParams)) and ((item 2 of winParams) < 0) then
							return physScreens's screen2
						end if
					end if
				end if
			end if
			
		else -- decide by proportions 
			-- if the window is more than half way into the second screen choose second screen for centering.
			if (item 1 of winParams) + (item 3 of winParams) / 2 > _width of physScreens's screen1 then
				if Screens2's numberOfScreens = 2 then
					return physScreens's screen2
				else
					return physScreens's screen1
				end if
			else
				return physScreens's screen1
			end if
		end if
		
	end findScreen
	
	to findNextWin for theScr from anApp against tPosition
		
		-- nå ville det ha vært ok, å ha screen nummer her, når vi skal kikke etter vindu
		-- om vinduet er til venstre eller noe?
		local wc, psts, nams, i, theId
		set psts to {}
		set nams to {}
		script o
			property m : missing value
			property n : missing value
		end script
		
		-- Find the frontmost
		
		
		tell application "System Events" to set wc to (count every window of application process anApp)
		if wc = 1 then return null -- it is the window we got!
		
		-- sjekk om det er noen flere vinduer på denne skjermen, og få de opp og frem!
		
		tell application "System Events" to tell application process anApp to set {psts, nams} to (get {position, name} of its every window)
		set o's m to psts
		set o's n to nams
		
		set foundIt to false
		set i to 2
		repeat while i ≤ wc -- the first is the one we already got!
			set thisScr to findScreen for item i of o's m with topleftcorner
			if nr of theScr = nr of thisScr then
				set foundIt to true
				exit repeat -- found a nother window!
			else
				set i to i + 1
			end if
		end repeat
		
		if not foundIt then return null -- out of luck!
		
		-- we want the id of the window, so we can activate it.
		
		--		tell application anApp to set theId to id of window (item i of o's n)
		
		return {item i of o's m, item i of o's n}
		
	end findNextWin
	
	-- initialize
	
	on checkState() -- Fetches ScreenData<
		local vScreen
		try
			-- stage 1: we get the desktop bounds for convenience up front!
			tell application "Finder"
				local newdtBounds
				set newdtBounds to (get bounds of window of its desktop)
				set vScreen to my mkScreen({originX:item 1 of newdtBounds, originY:item 2 of newdtBounds, theHeight:((item 4 of newdtBounds) - (item 2 of newdtBounds)), theWidth:((item 3 of newdtBounds) - (item 1 of newdtBounds))})
			end tell
			
			-- stage 2: do we have anything at all? 
			set my physScreens to load script alias _physScreens
			-- stage 3: when stage 1 went ok. compares old new finder bounds
			if not screensAlike(vScreen, physScreens's viritualScreen) then error number 3001
			
		on error
			local pScreen1, pScreen2
			
			set details to getScreens()
			
			set pScreen1 to mkScreen({originX:item 1 of details, originY:item 2 of details, theHeight:item 5 of details, theWidth:item 7 of details})
			set isMain of pScreen1 to true -- the screen with the menu!
			
			set pScreen2 to mkScreen({originX:item 3 of details, originY:item 4 of details, theHeight:item 6 of details, theWidth:item 8 of details})
			set my physScreens to mkPhysScreens()
			set defacto1 of physScreens to screensAlike(vScreen, pScreen1)
			-- store script physScreens in _physScreens replacing yes
			
			
			-- we have the current physical screen configuration. Some facts before we get the actual screen sizes!
			-- - and the layout we are going to make it into the logical screens.
			
			-- fact a: if bounds of the desktop mactches crt1, then there is one screen, if not we have two!
			-- whether we have two screens and have replicated the other, there will be one!
			
			-- fact b: the monitor with a menu on will be returned as screen 1 from window server,
			-- regardless if it is the internal display or not!
			
			-- fact c: we can drag the external monitor to the left of the current, and have a menubar on it, and everything will 
			-- be just good from the finder, with regards to coordinates.
			
			-- fact e:		
			-- there are 11 different ways to organize one or two screens, even before considering
			-- different resolutions.
			
			-- fact f: the coordinates of the screen having the menubar, ALLWAYS start at 0,22!
			
			-- Conventions:
			-- the logical first screen, is the one to the left! or the one on top --> in that order!
			
			if defacto1 of physScreens = true then
				-- for consistency!
				copy pScreen1 to screen1 of physScreens
				set nr of (screen1 of physScreens) to 1
				copy pScreen2 to screen2 of physScreens
				set nr of (screen2 of physScreens) to 2
				set _y of (screen1 of physScreens) to 22 -- menubar 
				set _height of (screen1 of physScreens) to (get _height of (screen1 of physScreens)) - 22
				
			else if _x of vScreen < 0 then
				
				copy pScreen2 to (screen1 of physScreens)
				set nr of (screen1 of physScreens) to 1
				-- logicalScreen1 is now the one without menu
				copy pScreen1 to (screen2 of physScreens)
				set nr of (screen2 of physScreens) to 2
				-- we swap the screens, so that we number them from left to right and  top to bottom, should the one with the menu be under and not to the left of the one without menu!
				
				-- horizontal adjustments _x 
				set _x of (screen1 of physScreens) to _x of vScreen
				
				if _y of vScreen < 0 then set _y of (screen1 of physScreens) to _y of vScreen
				
				set _y of (screen2 of physScreens) to 22 -- menubar
				set _height of (screen2 of physScreens) to (get _height of (screen2 of physScreens)) - 22
				
				
			else if _y of vScreen < 0 and _width of vScreen = _width of pScreen1 then
				
				copy pScreen2 to (screen1 of physScreens)
				set nr of (screen1 of physScreens) to 1
				-- logicalScreen1 is now the one without menu
				copy pScreen1 to (screen2 of physScreens)
				set nr of (screen2 of physScreens) to 2
				
				-- we swap the screens, so that we number them from left to right and  top to bottom, should the one with the menu be under and not to the left of the one without menu!
				
				-- the physical screen with a menu is placed below,
				
				-- vertical adjustments _y
				set _y of (screen1 of physScreens) to _y of vScreen
				
				set _y of (screen2 of physScreens) to 22 -- menubar
				set _height of (screen2 of physScreens) to (get _height of (screen2 of physScreens)) - 22
				
			else
				copy pScreen1 to (screen1 of physScreens)
				set nr of (screen1 of physScreens) to 1
				copy pScreen2 to (screen2 of physScreens)
				set nr of (screen2 of physScreens) to 2
				
				set _y of (screen1 of physScreens) to 22 -- menubar 
				set _height of (screen1 of physScreens) to (get _height of (screen1 of physScreens)) - 22
				
				if _y of vScreen < 0 then
					set _y of (screen2 of physScreens) to (_y of vScreen)
					-- dette må bli riktig! 
				else
					set _y of (screen2 of physScreens) to (_height of vScreen) - (((screen1 of physScreens)'s _height) + 22)
				end if
				
				set _x of (screen2 of physScreens) to (_width of vScreen) - ((screen1 of physScreens)'s _width)
				
			end if
			
			
			set viritualScreen of physScreens to vScreen
			-- set defacto1 of physScreens to practicallyOneScreen
			--			set screen1 of physScreens to logicalScreen1
			-- 	set screen2 of physScreens to logicalScreen2
			store script physScreens in _physScreens replacing yes
			-- you now can use the physical coordinates to calculate logical width and usable coordinates.
			-- there are caveats with negative coordinates, that must be adressed!
		end try
		
		-- soft settings... Calculating the Dock! those can be changed on the fly! easier than the monitors!
		
		-- fact a: if monitors are organized vertically, or diagonally, (without a common glitch)  then the dock will be stuck
		-- on the monitor with the menubar.
		
		-- fact b: if monitors are aligned horizontally the dock setting left, and right
		-- will put the dock on the left side of the monitor to the left, and to the right
		-- of the monitor to the right respectively, but the bottom setting will always be put
		-- on the monitor with the menubar!
		
		-- fact c: if the dock is hidden at the moment (autohide), then we don't have to do anything!
		
		-- This code only works from Leopard onwards!
		local theAutoHide, theOrientation
		tell application "System Events"
			tell dock preferences
				local thePosition
				set theAutoHide to autohide
				if theAutoHide is false then
					set thePosition to (get screen edge)
					if thePosition = left then
						set theOrientation to 1
					else if thePosition is bottom then
						set theOrientation to 2
					else
						set theOrientation to 3
					end if
				end if
			end tell
		end tell
		
		-- we elevate stuff into us, the "run-time object"
		
		if defacto1 of physScreens is true then
			
			if theAutoHide = false then
				if my GUIScripting_status() = false then error number -128
				adjustForDock({orient:theOrientation, overlap:false, screen1:screen1 of my physScreens, screen2:null})
			end if
			set numberOfScreens to 1
		else
			-- more than one screen!
			-- idea: record windows so that you record a setup of applications!
			
			if theAutoHide = false then
				if my GUIScripting_status() = false then error number -128
				-- we first find out how little we can get away with!
				local totHeight
				
				set totHeight to (_height of screen1 of physScreens) + (_height of screen2 of physScreens) + 22
				
				# How do I at this state reckognize which monitor is which???
				
				if _height of vScreen < totHeight then
					-- We do have overlapping monitors and the dock will use both!
					
					adjustForDock({orient:theOrientation, overlap:true, screen1:(screen1 of my physScreens), screen2:(screen2 of my physScreens)})
					-- Screen1 is the one to the left, if not,then the one on top ( aligned)
					
				else -- the dock will be placed on the monitor with the menu!
					
					if isMain of screen1 of my physScreens then
						adjustForDock({orient:theOrientation, overlap:false, screen1:(screen1 of my physScreens), screen2:null})
					else
						adjustForDock({orient:theOrientation, overlap:false, screen1:(screen2 of my physScreens), screen2:null})
					end if
				end if
				
			end if
			set numberOfScreens to 2
			
		end if
	end checkState
	
	-- PRIVATE ROUTINES.
	
	on mkPhysScreens()
		script __physScreens
			property parent : AppleScript
			property screen1 : missing value
			property screen2 : missing value
			property viritualScreen : missing value
			property defacto1 : missing value -- if just one screen!
		end script
	end mkPhysScreens
	
	script screenObj
		property parent : AppleScript
		property isMain : missing value
		property nr : missing value
		property _x : missing value
		property _y : missing value
		property _height : missing value
		property _width : missing value
		
		-- Screendata
		
		to screenX1()
			return my _x
		end screenX1
		
		to screenY1()
			return my _y
		end screenY1
		
		to bottomEdge()
			return ((my _y) + (my _height))
		end bottomEdge
		
		to rightEdge()
			return ((my _x) + (my _width))
		end rightEdge
		
		
		
		to screenY2()
			return ((my _y) + (my _height))
		end screenY2
		
		to screenHeight()
			return my _height
		end screenHeight
		
		to screenWidth()
			return my _width
		end screenWidth
		
		to screenOldCoords() -- X1,y1,x2,y2
			return {my _x, my_y, ((my _x) + (my _width)), ((my _y) + (my _height))}
		end screenOldCoords
		
		to screenCocoaCoords() -- x1,y1,width,height
			return {my _x, my_y, my _width, my _height}
		end screenCocoaCoords
		
		-- Frame data:
		
		to getCenter()
			set ctr_X to (my _x) + ((my _width) / 2) as integer
			set ctr_Y to (my _y) + (my _height) / 2 as integer
			return {ctr_X, ctr_Y}
		end getCenter
		
		to getX2()
			return ((my _x) + (my _width))
		end getX2
		
		on getLeftHalf() -- {startX,startY,width,height}
			local theC, botE
			set theC to (my _x) + ((my _width) / 2) as integer
			set botE to ((my _y) + (my _height))
			return {my _x, my _y, theC, botE}
		end getLeftHalf
		
		to getRightHalf() -- {startX,startY,width,height}
			local theC, botE, righte
			set theC to (my _x) + ((my _width) / 2) as integer
			set botE to ((my _y) + (my _height))
			set righte to ((my _x) + (my _width))
			return {theC + 1, my _y, righte, botE}
		end getRightHalf
		
	end script
	
	
	on mkScreen(r)
		-- { originX:theX,originY:theY: theHeight:_height, theWidth:_width }
		script aScreen
			property parent : screenObj of Screens2
			property isMain : false
			property nr : 0 as number
			property _x : originX of r as number
			property _y : originY of r as number
			property _height : theHeight of r as number
			property _width : theWidth of r as number
		end script
	end mkScreen
	
	to getScreens()
		-- NG http://macscripter.net/viewtopic.php?id=17701
		set f to (path to preferences from local domain as Unicode text) & "com.apple.windowserver.plist"
		tell application "System Events"
			set {{|OriginX|:x1, |OriginY|:y1, |Width|:w1, |Height|:h1}, {|OriginX|:x2, |OriginY|:y2, |Width|:w2, |Height|:h2}} to value of property list items of property list item 1 of property list item "DisplaySets" of property list file f
		end tell
		return {x1, x2, y1, y2, h1, h2, w1, w2}
	end getScreens
	
	to adjustForDock(r)
		-- {orient:theOrientation, overlap:true,screen1:screen1 of my physScreens,sceen2:screen2 of my physScreens }
		-- adjust the size of screen real estate for the dock, that is there when this handler is called!
		local dockWidth, dockStartY
		-- orient: 1 : left, 2 : bottom, 3 : right
		if orient of r = 1 or orient of r = 3 then
			tell application "System Events"
				tell process "Dock"
					set dockWidth to (((item 1 of (get value of attribute 9 of its list 1)) * 84) / 87) as integer
				end tell
			end tell
			if orient of r = 1 then
				set _x of (screen1 of r) to (get (_x of (screen1 of r)) + dockWidth)
				set _width of (screen1 of r) to (get (_width of (screen1 of r)) - dockWidth)
				
			else
				if overlap of r is true then
					
					set _width of (screen2 of r) to (get (_width of (screen2 of r)) - dockWidth)
				else
					set _width of (screen1 of r) to (get (_width of (screen1 of r)) - dockWidth)
					
				end if
			end if
			
		else -- orientation = 2 
			
			tell application "System Events"
				tell process "Dock"
					set dockStartY to item 2 of value of (get properties of attribute 8 of its list 1)
				end tell
				
			end tell
			if overlap of r is true then
				if isMain of screen1 of r then
					set _height of (screen1 of r) to dockStartY - 22
				else
					set _height of (screen2 of r) to dockStartY - 22
				end if
			else
				set _height of (screen1 of r) to dockStartY - 22
			end if
			
		end if
		
	end adjustForDock
	
	on screensAlike(screen1, screen2)
		if _x of screen1 = _x of screen2 then
			if _y of screen1 = _y of screen2 then
				if _height of screen1 = _height of screen2 then
					if _width of screen1 = _width of screen2 then
						return true
					else
						return false
					end if
				else
					return false
				end if
			else
				return false
			end if
		else
			return false
		end if
	end screensAlike
	
	on GUIScripting_status()
		-- http://web.archive.org/web/20081223062546/http://www.apple.com/applescript/uiscripting/index.html
		-- check to see if assistive devices is enabled
		tell application "System Events"
			set UI_enabled to UI elements enabled
		end tell
		if UI_enabled is false then
			tell application "System Preferences"
				activate
				set current pane to pane id "com.apple.preference.universalaccess"
				display dialog "This script utilizes the built-in Graphic User Interface Scripting architecture of Mac OS x which is currently disabled." & return & return & "You can activate GUI Scripting by selecting the checkbox \"Enable access for assistive devices\" in the Universal Access preference pane." with icon 1 buttons {"Cancel"} default button 1
			end tell
		end if
		return UI_enabled
	end GUIScripting_status
	
	to getFrontmostWindow()
		local wc, frontApp, prev_active, p1, p2, s1, s2
		
		set prev_active to ""
		-- Find the frontmost
		tell application "System Events"
			set frontApp to name of first application process whose frontmost is true and visible is true
			set wc to (count every window of application process frontApp)
			if wc = 0 then
				set prev_active to name of application process frontApp
				
				set visible of application process frontApp to false
				
				repeat with i from 1 to (count (every application process whose visible is true))
					set frontApp to item i of (get name of every application process whose frontmost is true and visible is true)
					set wc to (count every window of application process frontApp)
					if wc > 0 then exit repeat
				end repeat
			end if
			
			tell application process frontApp
				tell window 1
					set {{p1, p2}, {s1, s2}, tApp} to {position, size, contents of frontApp}
				end tell
			end tell
			
		end tell
		return {{p1, p2}, {s1, s2}, frontApp, prev_active}
		
	end getFrontmostWindow
	
	to transposeList(ctr, list1, list2)
		-- tested 05/09/12
		script o
			property newL : {}
			property m : list1
			property n : list2
		end script
		local i
		set i to 1
		repeat ctr times
			set end of o's newL to {contents of item i of o's m, contents of item i of o's n}
			set i to i + 1
		end repeat
		return o's newL
	end transposeList
	
	on rmSublistByItem2(what, L)
		-- tested 05/09/12
		local ct, i
		set ct to count L
		set i to 1
		repeat ct times
			
			if (item 2 of item i of L as text) is what then
				if i = 1 then
					return rest of L
				else if i = ct then
					return items 1 thru -2 of L
				else
					return items 1 thru (i - 1) of L & items (i + 1) thru -1 of L
				end if
			end if
			set i to i + 1
		end repeat
		return
	end rmSublistByItem2
	
	to getSingelton(the_list, item_a)
		-- tested 05/09/12
		local p, q, tids
		-- Nigel Garvey
		set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, return}
		
		set the_list_as_string to the_list as text
		set AppleScript's text item delimiters to item_a
		try
			if text item 1 of the_list_as_string = "" then
				set q to paragraph 2 of text item 2 of the_list_as_string
			else
				set p to (count paragraphs of text item 1 of the_list_as_string) mod 2
				set q to paragraph (p * 4 - 2) of text item (p + 1) of the_list_as_string
			end if
			set AppleScript's text item delimiters to tids
		on error
			set AppleScript's text item delimiters to tids
			return null
		end try
		if q is item 1 of last item of the_list then
			if item_a is item 2 of last item of the_list then
				return q
			else
				return null
			end if
		else
			return q
		end if
	end getSingelton
	
	to logit(log_string, log_file)
		do shell script ¬
			"echo `date '+%Y-%m-%d %T: '`\"" & log_string & ¬
			"\" >> $HOME/Library/Logs/" & log_file & ".log"
	end logit
end script

You’ll have to load the screens script into the teleport script, since I use the load mechanism of Script Debugger.

-- Teleport positions a screen at the other screen
# Copyright McUsr (c) 2012 All rights reserverved.
property toplevel : me
# write load statement here.
script telePort
	property parent : AppleScript
	on run
		local tPosition, tSize, tApp, pApp, theScr, otherScr, lbound
		toplevel's Screens2's checkState()
		if toplevel's Screens2's numberOfScreens = 1 then return 0
		set {tPosition, tSize, tApp, pApp} to toplevel's Screens2's getFrontmostWindow() -- get postion and extent of window
		
		set theScr to findScreen of (toplevel's Screens2) for tPosition with topleftcorner
		# Find the other window
		if nr of theScr = 1 then
			set otherScr to getsecondscreen() of (toplevel's Screens2)
		else
			set otherScr to toplevel's Screens2's getfirstscreen()
		end if
		
		# Must adjust for menubar and Dock
		# I need to know if the dock is not there (0), to the left(1), bottom(2) or right(3)
		# AND I need to now the *space* it takes. Because it needs to be added before
		# We calculate the proportions: They are now intialized to zero, there are still
		# some logic to be dealt with 
		local _Xfactor1, _Xfactor2, _Yfactor1, _Yfactor2
		set {_Yfactor1, _Yfactor2} to {0, 0}
		if isMain of theScr = true then #menu ok!
			
			if _dockPos of theScr = 2 then
				set _Yfactor1 to (_dockSpace of theScr) + 22
			else
				set _Yfactor1 to 22
			end if
			set _Yscale to calcprops((_height of theScr) + _Yfactor1, _height of otherScr)
			
			if _dockPos of theScr = 1 or _dockPos of theScr = 3 then
				set _Xfactor1 to _dockSpace of theScr
			else
				set _Xfactor1 to 0
			end if
			
			if _dockPos of otherScr = 3 then
				set _Xfactor2 to _dockSpace of otherScr
			else
				set _Xfactor2 to 0
			end if
			set _Xscale to calcprops((_width of theScr) + _Xfactor1, (_width of otherScr) + _Xfactor2)
		else
			
			if _dockPos of otherScr = 2 then
				set _Yfactor2 to (_dockSpace of otherScr) + 22
			else
				set _Yfactor2 to 22
			end if
			set _Yscale to calcprops((_height of theScr), (_height of otherScr) + _Yfactor2)
			
			if _dockPos of otherScr = 1 or _dockPos of otherScr = 3 then
				set _Xfactor2 to _dockSpace of otherScr
			else
				set _Xfactor2 to 0
			end if
			
			if _dockPos of theScr = 3 then
				set _Xfactor1 to _dockSpace of theScr
			else
				set _Xfactor1 to 0
			end if
			set _Xscale to calcprops((_width of theScr) + _Xfactor1, (_width of otherScr) + _Xfactor2)
		end if
		# Distance calculations: We are always moving from theScreen to theOther
		# To get the true distance do we need to consider the Dock? for the width? 
		
		if _dockPos of theScr = 1 then
			set _Xdist to ((_x of theScr) - _Xfactor1) - (_x of otherScr)
		else if _dockPos of otherScr = 1 then
			set _Xdist to (_x of theScr) - ((_x of otherScr) - _Xfactor2)
		else
			set _Xdist to (_x of theScr) - (_x of otherScr)
		end if
		# The dock at the bottom can't really inflict on the y positons, but the menu can!
		
		if isMain of theScr = true then
			set _Ydist to ((_y of theScr) - 22) - (_y of otherScr)
		else
			set _Ydist to (_y of theScr) - ((_y of otherScr) - 22)
		end if
		
		# Every factor calculated, it is time to do the actual translation
		
		local newX, newY, newWidth, newHeight
		
		set newX to (((item 1 of tPosition) - _Xfactor1 + _Xfactor2) * _Xscale) - _Xdist
		set newY to (((item 2 of tPosition) - _Yfactor1 + _Yfactor2) * _Yscale) - _Ydist
		set newWidth to ((item 1 of tSize) + _Xfactor1 - _Xfactor2) * _Xscale
		set newHeight to ((item 2 of tSize) + _Yfactor1 - _Yfactor2) * _Yscale
		
		tell application id "com.apple.systemevents"
			
			tell application process (item 2 of tApp)
				set position of window 1 to {newX, newY}
				set size of window 1 to {newWidth, newHeight}
			end tell
		end tell
		postProcessAllWindows of (toplevel's theWin) for item 2 of tApp without all
		-- 		if (item 1 of pApp) ≠ "" then
		-- 			tell application id (item 1 of pApp) to activate
		-- 		else
		-- 			tell application id (item 1 of tApp) to activate
		-- 		end if
	end run
	
	
	to calcprops(sc1, sc2)
		return (sc1 / sc2)
	end calcprops
	
end script

tell telePort to run


Edit
Added copyright statements.

Hi McUsr,

At a quick glance, it looks like there might be some things there. :cool:

What I was thinking was that iTunes would play and the visualizer would start. Then the visualizer would shift to the second display. The way it works is that the computer opens a new space for the full screen visualizer in the second display. It does that automatically, so that’s not needed in the script.

It’s too bad that Mission Control is not scriptable!

In my research on the internet, I haven’t seen anybody who knows how to place the visualizer in the second display. To me that is strange after all these years. I was thinking that maybe Mission Control is new and Apple is working on it.

We’ll get this, because many people want it which is very logical.

Thanks and have a good day,
kel

Hello.

Maybe it can help if you move a regular itunes window to the second display first, and then start the visualizer?

  • Also see to that you have no iTunes windows on your main display?

I really don’t use iTunes that much, so I can’t help you there. :slight_smile:

Hi McUsr,

I did that before and it doesn’t work. When you run iTunes from the second display, the visualizer opens in the first display! :confused: Strange how different iTunes is. Well actually, several apps behave in the same manner I think. :expressionless:

Later,
kel

ps. Ive been trying to help someone else on the Apple site, so posts might be a little delayed.

Does anyone know how to make the menu bar invisible?

Hello Kel.

Maybe you can fix your original problem with changing main display to the external monitor in System Preferences. What I mean is that you drag over the menu bar over to the other display, in the screens preferences. Maybe that will work. Good luck.

Hi McUsr,

Good idea about changing the Display arrangement with the menu bar. I’ll try that later and see what happens.

Thanks a lot,
kel

Think I might have something with the menu bar. Need to experiment with:

Edited: it almost worked. I dragged the Xcode app to the second display and ran it. Only that space didn’t have the menu bar and not the visualizer. Back to the drawing board. I think it has to be done in iTunes.

Success!!! :smiley:

Here’s what you do. After dragging the visualizer to the second display with Mission Control, go to System Preferences. In the Accessibility pane select Display. Then, check Invert colors. Then, uncheck it. All spaces return to default, but the visualizer menu bar disappears I think (or remains black). Quite sure the procedure went like that.

gl,
kel

Finally figured out the easier way. Didn’t know how to make the visualizer not come out of full screen. It needed to be done in the visualizer. This makes it easier. Now just need to move the window. Getting there.

Hi McUsr,

I decided to go with the quick and dirty ui element scripting Dock along with scripting iTunes for now. :slight_smile: The big algorithm had too many pieces. I have most of them, but haven’t put them all together and don’t know what kind of speed I’ll get. Will look into that later.

Will post the quick and dirty and local (according to my setup on the computer) in a little while. Maybe someone can use it as an algorithm for their own setup.

Thanks for the script. I’ve read your posts before and looked at the script about moving the window. That’s what I’m doing with Dock ui element scripting.

Edited: and one thing. I don’t have Script Debugger, so couldn’t run it, but the part about the windows looks interesting.

Edited: thought of a new library script to add to Script Libraries, ScreenLib. That might come in handy later.

Thanks a lot,
kel

Hello Kel.

Add a property named Screens2 right below the toplevel property in the teleport script.
This property should load the screens2. script object.

Then everything should work as expected.

I will convert it into a script library, when I change it for some reason.

Hi McUsr,

Will try the property. Thanks.

Here’s the roughly working quicky in my setup :slight_smile: :

-- macro
tell application "System Events"
	tell process "Dock"
		tell list 1
			tell UI element "iTunes"
				perform action "AXShowMenu"
				tell menu 1
					tell menu item "Options"
						click
						tell menu "Options"
							tell menu item "Desktop on Display 2"
								click
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

-- if full screen is true,
-- then that means that the visualizer might have opened in display 1
-- then, need to put the visualizer back in the window
-- then, re-full screen
tell application "iTunes"
	launch
	activate
	set visuals enabled to true
	if full screen then
		say "full screen off" -- this delay maybe needed here
		set full screen to false
	end if
	say "full screen on" -- this delay needed here
	set full screen to true
end tell
delay 2 -- this delay maybe needed here

-- macro
tell application "System Events"
	tell process "Dock"
		tell list 1
			tell UI element "iTunes"
				perform action "AXShowMenu"
				tell menu 1
					tell menu item "Options"
						click
						tell menu "Options"
							tell menu item "Desktop on Display 1"
								click
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

tell application "iTunes"
	play
end tell
-- Remember to return focus to iTunes (if you prefer).
-- Activate doesn't work because the focus is already on iTunes in the visualizer.
-- Maybe you can use this as a feature?
-- Remember to reset menu to what it was before.

Needs a lot of tweaking.

Have a good day, :smiley:
kel

Have a good day you too kel, and good luck! :slight_smile:

Thanks McUsr.

Think I have a new idea. I’m wondering if visible is set and unset then the focus will change to the browser. Hope I can sleep. :slight_smile: Nice puzzle.

Later,
kel

Think I have the solution. Need to keystroke out of the visualizer’s space!

Edited: no can’t do that. Then, the visualizer won’t show! How to shift out of display 2? That’s the question.

Edited: by Jove, think I’ve got it. Use the same method!

Edited: figured how to move the focus with keystrokes!!!

Hi McUsr,

We’ve got it now!!! To open iTunes in space 6 on the second display from the first display:

tell application "System Events"
	launch
	key code 22 using control down --  Space 6
	key code 26 using control down -- Space 7
	key code 22 using control down -- Space 6
end tell
tell application "iTunes"
	launch
	activate
end tell

Keystrokes don’t work, but key codes do. Also, if on the second display, space 6 is already the selected space, then nothing will happen with just:

key code 22 using control down --  Space 6

So we need to key code to space 7 and then back to space 6.

This makes everything very easy!!! :smiley:

The only hard part is that I want to move the browser back to the first display. That’s all that is left to do.

Have a good day, :slight_smile:

Edited: it didn’t work. :frowning: The browser still opens in where it was closed. :confused: Back to the drawing board.
Have a good day anyway. :slight_smile:

kel

Hi,

What I wanted to do was Open iTunes browser in Display 1 - Space 5 and the visualizer in Display 2

Here’s the working script if anyone wants to play around with it. I’m running it in AppleScript Editor in Space 4.

-- iTunes' browser opens in the display where it was closed.
-- Set iTunes to open in display 2.
tell application "System Events"
	tell process "Dock"
		tell list 1
			tell UI element "iTunes"
				perform action "AXShowMenu"
				tell menu 1
					tell menu item "Options"
						click
						-- might need delay here
						tell menu "Options"
							tell menu item "Desktop on Display 2"
								click
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

-- First move to space 5 where we want iTunes to open.
tell application "System Events"
	key code 23 using control down
end tell

-- Open iTunes and enable the visualizer.
-- If the visualizer opens in full screen, it might have opened in display 1.
-- So, take it out of full screen and into the browser.
-- Now go back into full screen and the visualizer should open in display 2.
-- Focus is now on the visualizer.
tell application "iTunes"
	launch
	activate
	set visuals enabled to true
	delay 2 -- this delay needed
	set full screen to false
	delay 2 -- this delay needed
	set full screen to true
end tell
delay 2 -- this delay needed

-- Move the browser back to display 1.
tell application "System Events"
	tell process "Dock"
		tell list 1
			tell UI element "iTunes"
				perform action "AXShowMenu"
				tell menu 1
					tell menu item "Options"
						click
						tell menu "Options"
							tell menu item "Desktop on Display 1"
								click
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

-- The focus is on display 2, last space (no index).
-- Set the focus on display 1, space 5 or 4.
tell application "System Events"
	key code 23 using control down --  Space 5
	key code 21 using control down -- Space 4
	delay 2
	key code 23 using control down -- Space 5
end tell

-- Reset where iTunes should open to None.
tell application "System Events"
	tell process "Dock"
		tell list 1
			tell UI element "iTunes"
				perform action "AXShowMenu"
				tell menu 1
					tell menu item "Options"
						click
						tell menu "Options"
							tell menu item "None"
								click
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

Try decreasing the delays if possible.

Edited: btw, Dock is set to always be open. I think that’s all.

Edited: one more thing if someone wants to make it international, then please do and post it. I don’t know how to get the indices for the menu items. Thanks.

gl,
kel :smiley:

Added one more delay and decreased the others:

property delay1 : 1.5
property delay2 : 0.5

-- iTunes' browser opens in the display where it was closed.
-- Set iTunes to open in display 2.
tell application "System Events"
	tell process "Dock"
		tell list 1
			tell UI element "iTunes"
				perform action "AXShowMenu"
				tell menu 1
					tell menu item "Options"
						click
						tell menu "Options"
							tell menu item "Desktop on Display 2"
								click
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

-- First move to space 5 where we want iTunes to open.
tell application "System Events"
	key code 23 using control down
end tell

-- Open iTunes and enable the visualizer.
-- If the visualizer opens in full screen, it might have opened in display 1.
-- So, take it out of full screen and into the browser.
-- Now go back into full screen and the visualizer should open in display 2.
-- Focus is now on the visualizer.
tell application "iTunes"
	launch
	activate
	set visuals enabled to true
	delay delay1 -- this delay needed
	set full screen to false
	delay delay1 -- this delay needed
	set full screen to true
end tell
delay delay1 -- this delay needed

-- Move the browser back to display 1.
tell application "System Events"
	tell process "Dock"
		tell list 1
			tell UI element "iTunes"
				perform action "AXShowMenu"
				tell menu 1
					tell menu item "Options"
						click
						tell menu "Options"
							tell menu item "Desktop on Display 1"
								click
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

-- The focus is on display 2, last space (no index).
-- Set the focus on display 1, space 5.
tell application "System Events"
	key code 23 using control down --  Space 5
	key code 21 using control down -- Space 4
	delay delay1
	key code 23 using control down -- Space 5
end tell

-- Reset where iTunes should open to None.
tell application "System Events"
	tell process "Dock"
		tell list 1
			tell UI element "iTunes"
				perform action "AXShowMenu"
				tell menu 1
					tell menu item "Options"
						click
						tell menu "Options"
							tell menu item "None"
								click
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end tell
delay delay2

tell application "iTunes"
	activate
	play
end tell

It should work ok for the time being. Might try speeding it up somehow.

Good Luck.