Retrieving Display sizes and layout in an AppleScript

I wanted a way to get the size and layout of my displays, e.g. if I'm on my MacBook Pro Retina there should be one display with a size of X
×Y
at an origin of 0,0
where X
×Y
varies depending on which scaling factor I have set in System Preferences
→Displays
→Resolution
. If the MBPr is plugged in at my desk, then there should be three displays each with their own sizes and origins. I don't care whether this is done in AppleScript or a unix command as one can always call the other.
This was surprisingly difficult to figure out how to do, but surprisingly easy to implement once I did figure it out.
First, a few things I tried that got me part way, but in the end were unfruitful:
xdpyinfo
The command line utility xdpyinfo
gives some useful information, but not everything I need and is particularly unhelpful in the multi-monitor case.
com.apple.windowserver.plist
At first glance /Library/Preferences/com.apple.windowserver.plist
looked very promising.
I could dump it to xml:
plutil -convert xml1 -o test.xml /Library/Preferences/com.apple.windowserver.plist
And then examine test.xml
in a text editor. (or even explore the original plist file in Xcode)
I could pull out individual bits of information, e.g.:
/usr/libexec/PlistBuddy -c "Print DisplaySets:0:0:Width" \
/Library/Preferences/com.apple.windowserver.plist
→ 1680
/usr/libexec/PlistBuddy -c "Print DisplaySets:0:0:OriginX" \
/Library/Preferences/com.apple.windowserver.plist
→ 0
I could even write a bash script that would output [width, height, originX, originY] for each screen in all DisplaySets:
The problem with this is that I could not figure out how to reliably know which DisplaySet is the active one.
AppleScriptObjC
Finally, I found AppleScriptObjC. Follow the instructions contained within the first gist file to install and use:
Pretty cool.
One note is that the coordinate origins start from Lower Left, while at least in some other places in the operating system I need to use coordinate systems starting from Upper Left. Oh well, that math is at least easy.

