Macbook Pro Retina MBPr 15" change resolution script

*Edit: does this belong in the code sharing section? Sorry if it does… If so, please move it sir mod! But spare me the rod, mod.

Hey all,

Some utilities (cscreen, screenutil, etc.) are available for easy scripting to change screen resolution to non-default modes, but when these utilities are used to set back to a default mode (ie. 1440x900) the display is not “retina”. Here’s a script to take care of this.

When a resolution other than the 5 that os x natively supports is selected, the screenutil utility is used. When one of the 5 is selected, System Preferences is used via gui scripting.

Before you use this, you need to download screenutil and install it in /usr/local/bin (the way I have it set here) (get screenutil from Download ScreenUtil v1.0 http://www.mowlem-enterprises.co.uk/screenutil/ScreenUtil_v1.0.zip).

MBPr 13" owners can easily modify the script with whatever resolutions are applicable. Note the delimiters that are used in the parseLine handler, and that only tab, not space, is used between the resolution and it’s description (megapixels etc.).

Hope someone finds this useful.

Tim

PS
Haven’t had a chance to check what this does with an external display attached, or when that external display is set as the primary monitor, so maybe someone can test that case and improve this.

*Edit: Added a few lines so that if System Preferences was already running then it returns to the previously open pane after the script runs (only if another pane was open. I couldn’t figure out how to get it back to the main window without closing and reopening it, which is stupid).

**Edit: The script is now specific to use the primary display’s window, so it works if you have a secondary (or tertiary) display hooked up.

on run
	set resList to {"2880 x 1800		5.2MP* Max", "2560 x 1600		4.1MP", "2304 x 1440		3.3MP", "2048 x 1280		2.6MP", "1920 x 1200		2.3MP*", "1680 x 1050		1.8MP*", "1440 x 900		1.4MP* \"Best\"", "1280 x 800		1.0MP*", "1024 x 640		0.7MP* Lowest"}
	set pickedRes to choose from list resList with prompt "Select resolution (* Retina)"
	if pickedRes is false then return 0
	set strList1 to item 1 of parseLine(pickedRes as string, tab)
	set strList to parseLine(strList1 as string, space)
	set resStr to (first item of strList) & " " & (last item of strList)
	if first item of strList is "1024" or first item of strList is "1280" or first item of strList is "1440" or first item of strList is "1680" or first item of strList is "1920" then
		if first item of strList is "1024" then set resButton to 1
		if first item of strList is "1280" then set resButton to 2
		if first item of strList is "1440" then set resButton to 3
		if first item of strList is "1680" then set resButton to 4
		if first item of strList is "1920" then set resButton to 5
		retinaRes(resButton)
	else
		do shell script "/usr/local/bin/scrutil t " & resStr & " 32"
	end if
end run

on retinaRes(screenRes)
	if appIsRunning("System Preferences") then
		set closeSysPref to false
		tell application "System Preferences" to set currentPane to current pane
	else
		set closeSysPref to true
	end if
	
	tell application "System Preferences"
		activate
		reveal pane id "com.apple.preference.displays"
	end tell
	
        -- Below line specifies the name of the window. Window 1 if only main display in use.
	tell application "System Events" to tell process "System Preferences" to tell window "Color LCD" --1
		click radio button "Display" of tab group 1
		click radio button "Scaled" of tab group 1
		
		click radio button screenRes of radio group 1 of group 1 of tab group 1
		
	end tell
	
	if screenRes is 1 then
		tell application "System Preferences" to activate
		tell application "System Events" to key code 36
	end if
	
	tell application "System Preferences"
		if closeSysPref then
			quit
		else
			try
				set current pane to currentPane
			end try
		end if
	end tell
end retinaRes

on parseLine(theLine, delimiter)
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {delimiter}
	set theTextItems to theLine's text items
	set AppleScript's text item delimiters to astid
	
	repeat with i from 1 to (count theTextItems)
		if (item i of theTextItems is "") then set item i of theTextItems to missing value
	end repeat
	
	return theTextItems's every text
end parseLine

on appIsRunning(appName)
	tell application "System Events" to (name of processes) contains appName
end appIsRunning

Model: MBP-r
AppleScript: 2.2.4
Browser: Safari 536.25
Operating System: Mac OS X (10.8)