I looked and looked, but every example of changing screen resolution with UI scripting ended up with someone posting a link to cscreen instead. …and all of those links seem to be broken today.
I have finally figured out how to do it with UI scripting instead; no cscreen download necessary. I’m posting it here just in case anyone else comes looking for results without cscreen.
--Open System Preferences and switch to the Displays preference pane
tell application "System Preferences"
activate
set current pane to pane "com.apple.preference.displays"
end tell
tell application "System Events"
--Make sure we are on the "Displays" tab (as opposed to "Arrangement" or "Color")
click radio button "Display" of tab group 1 of window 1 of process "System Preferences"
--Set the resolution to whatever is in row 2 for the primary display;
select row 2 of table 1 of scroll area 1 of group 1 of tab group 1 of window 1 of process "System Preferences"
--Change "row 2" to whatever row you want; change "window 1" to "window 2" for a secondary display;
--So.
(*
select row 1 of table 1 of scroll area 1 of group 1 of tab group 1 of window 2 of process "System Preferences"
*)
--.would select the first row on the second window (the second window being settings for a secondary display).
--Replace 'window 1' with 'window "Color LCD"' or whatever the window's title is to change a specific device
--So.
(*
select row 1 of table 1 of scroll area 1 of group 1 of tab group 1 of window "VK246" of process "System Preferences"
*)
--.would would change settings for "VK246," regardless of whether it is the primary or secondary display.
end tell
--Finally, quit System Preferences again.
tell application "System Preferences"
quit
end tell
If you’re interested, you can open the “Display” tab directly like this:
--Open System Preferences on the Displays->Display tab
tell application "System Preferences"
reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
activate
end tell
tell application "System Events"
--etc.
On my Snow Leopard machine, having the ‘reveal anchor’ line before ‘activate’ makes System Preferences appear with the tab already open.
This gets a little more elaborate if you have two screens as I have. Then there are two windows opened whose titles are the screens involved (e.g., in my case “iMac” and “Syncmaster”). The screen without the title bar is window 2 of the panes shown. That’s the only one I ever change.
I’m not clear where your comment’s directed. Are you saying my ‘reveal anchor’ suggestion doesn’t work with multiple monitors? Or are you referring to the process as a whole?
Your part works perfectly, Nigel; I was commenting on the UI Scripting portion where identifying the screen you’re working with becomes important because the main (menu) screen is window 1 and a second monitor will be window 2.
Sorry for the delay answering, btw – I’m not home.
This post was dead useful for me. Figuring out UI scripting is always easiest if someone else does it for you =]
I’ve got a slightly modified version that works as a toggle, so run it a second time and it reverts to your original setting. Using a fragile method, but it works…
-- This is here to make it work like a toggle.
-- I couldn't find a way to query the table to
-- see what is selected, so this a hack.
property runCount : 1
-- You add lists to this list to control the toggle values for each display. So with a value of {1,10},
-- 1 is the row number in system preferences of its native resolution, and 10 is the row
-- number of the resolution that it will toggle to. You can add more to it, eg {1, 10, 12}, this
-- will give you three toggle states.
-- The default setting of {{1, 10}, {1, 12}} is because I have 2 displays. delete one list if you only
-- have one. Add another if you have three.
-- Work out the values you want by counting the rows in the resolution table in displays
-- in system preferences.
property rowNumberList : {{1, 10}, {1, 12}}
tell application "System Preferences"
activate
set current pane to pane "com.apple.preference.displays"
end tell
-- Reset the counter to make it work as a toggle
if runCount is greater than (count item 1 of rowNumberList) then
set runCount to 1
end if
tell application "System Events"
repeat with i from 1 to (count rowNumberList)
--Make sure we are on the "Displays" tab (as opposed to "Arrangement" or "Color")
click radio button "Display" of tab group 1 of window 1 of process "System Preferences"
--Set the resolution to whatever is in row 2 for the primary display;
select row (item runCount of (item i of rowNumberList)) of table 1 of scroll area 1 of group 1 of tab group 1 of window i of process "System Preferences"
-- minor delay to let a potential "ok", "cancel" sheet display (this happens when I choose a HiDPI resolution)
do shell script "sleep 0.25"
-- will choose the default value of "ok" if the sheet is there by pressing enter (ugh!)
keystroke (ASCII character 3)
end repeat
end tell
--Finally, quit System Preferences again.
tell application "System Preferences"
quit
end tell
set runCount to runCount + 1