Resize Your Windows Automatically for Different Resolutions

I use my MacBook Pro in a few different scenarios: by itself, plugged in to a 21” Apple Cinema Display, or plugged in to a 24” Dell 2405FPW.  I’m also rather OCD; I prefer my Firefox/Safari, Mail.app, and Vienna windows to be centered, stretch from the menu bar to the top of my Dock, and be a certain width.  I created a small AppleScript to auto-detect my resolution and size the windows accordingly:

tell application "Finder" set screen_resolution to bounds of window of desktop set screen_width to item 3 of screen_resolution set screen_height to item 4 of screen_resolution end tell tell application "System Events" to tell process "Dock" set dock_dimensions to size in list 1 set dock_height to item 2 of dock_dimensions end tell set desired_width to 1400 set side_space to screen_width - desired_width set left_bound to (side_space / 2) set right_bound to left_bound + desired_width set bottom_bound to screen_height - dock_height set top_bound to 22 (* for the menu bar *) try tell application "iTunes" activate set the bounds of the first window to {left_bound, top_bound, right_bound, bottom_bound} end tell end try try tell application "Firefox" activate set the bounds of the first window to {left_bound, top_bound, right_bound, bottom_bound} end tell end try try tell application "Mail" activate set the bounds of the first window to {left_bound, top_bound, right_bound, bottom_bound} end tell end try try tell application "Vienna" activate set the bounds of the first window to {left_bound, top_bound, right_bound, bottom_bound} end tell end try

With that in place, I saved it as an application in ~/Applications, and put it in my Dock. Now, whenever I change resolutions, I just click the button and everything is how I like it.

To change the script, you should be able to add any application with an AppleScript dictionary that supports moving and sizing the window.  The numbers I’ve used make the windows 1,400px wide, and the height that you want will depend on the size of your Dock. The script moves windows to the center, desired_width wide, and from the menubar to the Dock.

Note: I have had some trouble recently; sometimes when I change my resolution the AppleScript doesn’t pick it up.  To combat this, I told the Displays System Preferences pane to keep its icon in the menu bar; when my script uses the incorrect resolution, I change my screen resolution then change it back, which is enough for the script to detect the change.

Update 2008-05-28: Made some usability changes. Details here.

Published by

Jeff Kelley

I make iOS apps for Detroit Labs.

26 thoughts on “Resize Your Windows Automatically for Different Resolutions”

  1. Didn’t the window re-size button in early Mac OS toggle between two sizes — at least the default and the last size you set? When I resize in Leopard, a window fills the entire screen, which is a little ridiculous on a 24-inch iMac.

    I look forward to trying your script. I envision having a few different settings for various screen sizes and locations. I don’t know I have the expertise to write such a script yet, though I’m willing to try. In the meantime, anyone else want to give it a shot?

    Les
    lesliebradley@comcast.net

  2. Any idea why my applescript script editor is complaining about the following line on 10.5.2?

    tell application “Finder”

    error : “Expected expression, property or key form, etc. but found unknown token.”

  3. Very cool Jeff!

    However, I’m having trouble in Leopard running the script. It reports that “The Classic environment is no longer supported”. I’m kind of a noob on AppleScript. I just copied your script to a text file and saved is as a (.app) application.

    Any thoughts?

  4. @d: Try deleting the quotation marks, then putting them back in and pressing “Compile.” Apparently they aren’t copying correctly.

    @qs7: You need to open Script Editor, which is typically in /Applications/AppleScript. From Script Editor you can save it as an .app. Good luck! Check out this page for some more details.

  5. Great script, thanks!
    What would happen if you have 2 different resolutions at the same time? Normally when I connect my Cinema display to the MBP, I have 1440*900 on the MPB and 1920*1200 on the Cinema.

  6. Martijn,

    When you have multiple displays, it acts as one large display. If you have your displays next to one another, it’ll be something like 3360 x 1200. Look here for more information.

  7. Cool script.

    Anybody have any idea whether it’s possible to also adjust the desktop Grid spacing or Icon size through Applescript?

    It would be very useful to also be able to automatically adjust the layout of my desktop as I switch between monitors.

  8. My question is, can I have it resize the different programs differently? I like mail to take up an entire screen, but I like firefox smaller. Would that require me to make two separate scripts, and maybe an applescript to run both of them? Or can this be done in one script?

  9. PowerLlama,

    There’s no reason you can’t; my script uses variables like _nl and _nr, you could use _new_firefox_left and _new_mail_left, etc. Go nuts.

  10. Jeff,

    Re: correctly returning values when multiple monitors are connected and updating immediately after screen resolution change.

    This handler 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.

    –Test results
    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

  11. Hi Jeff,

    Thanks for your post. I wrote a post on my new blog with a slightly different approach. The idea is that you can resize the currently active window to one of several sizes using different keyboard shortcuts. Here is a link to that post.

    Stephan

    PS sorry about the domain name change. The previous comment (from the trackback) has the wrong address.

Comments are closed.