« An aside: Every Conference Call Ever | Main | How to stop CrashPlan from continuously crashing »
Tuesday
Feb042014

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 PreferencesDisplaysResolution. 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.