You are not logged in.
I'm using screen list from the Jon's Commands OSAX to get the resolution of the screen, but as an Applescript neophyte, nested lists confuse me to no end. I've found a way to do it, but it seems horribly inelegant. I figure there must be a better way. Here's what I'm doing:
Applescript:
set scrRes to screen size of (item 1 of (item 1 of {screen list}))
set scrWidth to item 1 of scrRes
set scrHeight to item 2 of scrRes
Can someone show me a better way to do this? Here's the beginning of what screen list returns, per Jon's docs:
Applescript:
{
{
name:"AppleVision 1710AV Display",
screen id:1,
bounds:{0, 0, 832, 624},
screen size:{832, 624},
color depth:32,
in color:true,
has menu bar:true,
refresh rate:75,
resolution index:6,
safe resolution:true,
supported resolutions:{
Thanks for any suggestions!
Greg Orman
Information Technology
Scripps College
Offline
If you don't mind uisng an other OSAX, you can try XTool that has a command to get the screen size.
http://www.osaxen.com
Offline
You could use another OSAX but as to your original question: screen list actually returns a list of records (one for each screen--even if there is only one screen) not lists. You've added to the complexity by adding another list simply by placing screen list in brackets instead of parentheses. Fixing that, though, your code is fairly sound although you could simplify the setting of the two variables with a single copy statement:.
Applescript:
copy screen size of (item 1 of (screen list)) to {scrWidth, scrHeight}
Jon (not of Jon's Commands fame -- that's Pugh, a real godsend to AppleScript for many years)
Offline
And if you need a non-osax solution you can use the following handler. This works on multiple monitors and returns correct dimensions immediately after a screen resize. Originally tested to return correct results immediately after second screen connection or disconnection, but I can't reconfirm that currently. The monitorProperties() handler below returns the count of connected monitors and the dimensions of each. It currently is coded to handle only two monitors due to my laptops connection options.
Applescript:
set MonitorProps to monitorProperties()
--{monitor1:{Width:1440, Height:900, OriginX:0, OriginY:0}, monitor2:{Width:missing value, Height:missing value, OriginX:missing value, OriginY:missing value}, monitorCount:1}
set {monHeight, MonWidth} to {Height of monitor1, Width of monitor1} of MonitorProps
--{900,1440}
on monitorProperties()
--paulskinner Friday, March 14, 2008 6:11:53 PM
--system_profiler parsing
set SPDisplaysData to (do shell script "system_profiler SPDisplaysDataType")
set text item delimiters to "Displays:"
set SPDisplaysData to text item 3 of SPDisplaysData
set text item delimiters to (word 1 of SPDisplaysData)
copy text item 1 of SPDisplaysData to text item delimiters
set SPDisplaysData to text items 2 thru -1 of SPDisplaysData
set text item delimiters to ""
repeat with i from 2 to length of SPDisplaysData
if character 1 of item i of SPDisplaysData is not " " then
set monitor1 to items 2 thru (i - 1) of SPDisplaysData
set monitor2 to items (i + 1) thru -1 of SPDisplaysData
exit repeat
end if
end repeat
--END OF system_profiler parsing
set {monitorCount, output} to {1, {}}
repeat with curList in {monitor1, monitor2}
set mainDisplay to false
curList
if item 1 of curList contains "Status: No display connected" then
return {monitor1:{Width:y as integer, Height:x as integer, OriginX:0, OriginY:0}, monitor2:{Width:missing value, Height:missing value, OriginX:missing value, OriginY:missing value}, monitorCount:monitorCount}
else
repeat with i from 1 to length of curList
set curItem to item i of curList
if curItem contains "Resolution:" then
set {y, x} to {word 2 of curItem, word 4 of curItem}
end if
if curItem contains "Main Display: Yes" then
set mainDisplay to true
end if
end repeat
end if
if mainDisplay then
set display1 to {Width:y as integer, Height:x as integer, OriginX:missing value, OriginY:missing value}
else
set monitorCount to 2
set display2 to {Width:y as integer, Height:x as integer, OriginX:missing value, OriginY:missing value}
end if
end repeat
-- If there are two monitors then use com.apple.windowserver to try to acquire Origins
set {monitor1, monitor2} to {{}, {Height:missing value, Width:missing value, OriginX:missing value, OriginY:missing value}}
set PrefFilePath to do shell script "find " & (POSIX path of ((path to preferences from user domain as Unicode text) & "ByHost:")) & " -name 'com.apple.windowserver*'"
tell application "System Events"
set wsp to item 1 of (item 1 of (get value of property list items of property list file PrefFilePath))
end tell
repeat with mon from 1 to length of wsp
set monData to item mon of wsp
if (|OriginX| of monData is 0) and (|OriginY| of monData is 0) then
set monitor1 to {Height:|Height| of monData, Width:|Width| of monData, OriginX:|OriginX| of monData, OriginY:|OriginY| of monData}
else
set monitor2 to {Height:|Height| of monData, Width:|Width| of monData, OriginX:|OriginX| of monData, OriginY:|OriginY| of monData}
end if
end repeat
set WSmp to {monitor1:monitor1, monitor2:monitor2, monitorCount:(length of wsp) as integer}
--END OF If there are two monitors then use com.apple.windowserver to try to acquire Origins
if monitorCount is monitorCount of WSmp then --If monitor count matches, compare dimensions reported by the two sources.
if (Height of display1 is (Height of monitor1 of WSmp)) and (Width of display1 is (Width of monitor1 of WSmp)) and (Height of display2 is (Height of monitor2 of WSmp)) and (Width of display2 is (Width of monitor2 of WSmp)) then
return WSmp -- All match, return windowserver data since it is most complete.
end if
end if
return {monitor1:display1, monitor2:display2, monitorCount:monitorCount} -- Not all match, return system_profiler data.
end monitorProperties
Offline
This is the one I use. It returns a list of two lists (for two screens) with the first two terms in each being the pixel dimensions of the screen, and the last two the top left-hand corner of the screen. It will return the dimensions and location of a second screen that has been connected even if it is not currently connected.
Applescript:
set f to (path to preferences from local domain as Unicode text) & "com.apple.windowserver.plist"
tell application "System Events"
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
end tell
{{w1, h1, OX1, OY1}, {w2, h2, OX2, OY2}}
Offline
just to prove that there is yet another way... I'm so grateful for all the help I got here...
These methods serve me well, when it comes to AppleScript and displays:
Applescript:
(*
screenInfo.scpt
get basic display(s) information
Written on 090522 by SwissalpS
Uses a shell script to read display settings from defaults.
I don't know about OS X 10.5 but on earlier versions the read info was not up-to-date
more like state-at-boot-time so I wouldn't be surprised if the information returned from this
script isn't accurate at all times.
usage:
set screenInfo to getSomeScreenInfo()
note: I can't figure out on which display the menu bar is (when not on main) so safebounds is allways cropped
returns a list containing a record for each display that was found (in the plist!). Example with 2 screens, the main screen is situated to the right of the second:
{
{id:"69670400", origin:{0, 0}, size:{1440, 900}, bounds:{0, 0, 1440, 900}, safebounds:{0, 44, 1440, 900}, unmirroredSize:{1440, 900}, isMirrored:false},
{id:"1535231425", origin:{-1280, -52}, size:{1280, 1024}, bounds:{-1280, -52, 0, 972}, safebounds:{-1280, -8, 0, 972}, unmirroredSize:{1280, 1024}, isMirrored:false}
}
thanks to Julio for posting the shell script on macscripter.net
http://macscripter.net/profile.php?id=7
http://macscripter.net/viewtopic.php?pid=12313#p12313
Important: use at your own risk ;-P
*)
-- demo
{getSomeScreenInfo(), getInfoFromSystemProfiler()}
to getSomeScreenInfo()
set {iMainScreenIsInternal, iActiveScreens, iScreens, iMirrors, aHeights, aWidths, aNativeHeights, aNativeWidths, aIDs, aOx, aOy, aMirrored} to {0, 0, 0, 0, {}, {}, {}, {}, {}, {}, {}, {}}
-- main screen stuff
set iMainScreenIsInternal to (my getGrepFor("DisplayMainOnInternal"))'s last word as number
-- active screen count
set iActiveScreens to count of (my getGrepFor("Active"))'s paragraphs
-- anything mirrored?
set aTmp to (my getGrepFor("Mirrored"))'s paragraphs
repeat with sTmp in aTmp
set i to sTmp's last word as number
set aMirrored's end to i
set iMirrors to iMirrors + i
end repeat
-- display ids
set aTmp to (getGrepFor("DisplayID"))'s paragraphs
repeat with sTmp in aTmp
set aIDs's end to sTmp's last word as text
end repeat
-- display count
set iScreens to aIDs's length
-- current widths
set aTmp to (getGrepFor("Width"))'s paragraphs
repeat with sTmp in aTmp
set aWidths's end to sTmp's last word as number
end repeat
-- current heights
set aTmp to (getGrepFor("Height"))'s paragraphs
repeat with sTmp in aTmp
set i to sTmp's last word as number
set aHeights's end to i
end repeat
-- native widths
set aTmp to (getGrepFor("UnmirroredWidth"))'s paragraphs
repeat with sTmp in aTmp
set aNativeWidths's end to sTmp's last word as number
end repeat
-- native heights
set aTmp to (getGrepFor("UnmirroredHeight"))'s paragraphs
repeat with sTmp in aTmp
set aNativeHeights's end to sTmp's last word as number
end repeat
-- origin X
set aTmp to (getGrepFor("OriginX"))'s paragraphs
repeat with sTmp in aTmp
set aOx's end to sTmp's characters ((offset of "=" in sTmp) + 1) thru -2 as text as number
end repeat
-- origin Y
set aTmp to (getGrepFor("OriginY"))'s paragraphs
repeat with sTmp in aTmp
set i to sTmp's characters ((offset of "=" in sTmp) + 1) thru -2 as text as number
set aOy's end to i
end repeat
-- to return in info in another format, uncomment the following line by removing the preceding '--'
--return {mainScreenIsInternal:iMainScreenIsInternal, numberOfScreens:iScreens, numberOfActiveScreens:iActiveScreens, numberOfMirrors:iMirrors, heights:aHeights, widths:aWidths, unmirroredHeights:aNativeHeights, unmirroredWidths:aNativeWidths, originXs:aOx, originYs:aOy, allIDs:aIDs}
-- now we have it all, let's make uasable grouping
set aScreens to {}
repeat with i from 1 to aIDs's length
set {x0, y0, w, h} to {aOx's item i, aOy's item i, aWidths's item i, aHeights's item i}
set {x1, y1} to {x0 + w, y0 + h}
set hScreen to {id:aIDs's item i, origin:{x0, y0}, size:{w, h}, bounds:{x0, y0, x1, y1}, safebounds:{x0, y0 + 44, x1, y1}, unmirroredSize:{aNativeWidths's item i, aNativeHeights's item i}, isMirrored:false}
if 0 ≠ (aMirrored's item i) then set hScreen's isMirrored to true
set aScreens's end to hScreen
end repeat
return aScreens
end getSomeScreenInfo
(* used by getSomeScreenInfo() *)
to getGrepFor(sString)
return do shell script "defaults read /Library/Preferences/com.apple.windowserver | grep -w " & sString
end getGrepFor
Offline