RSVP - Please Reply

Armin's Spot on the Web


Home

Impressum

My Code


What is a Weblog?

Pictures (.Mac)


NetNewsWire: More news, less junk. Faster

Discussion

Recent Discussion

Create New Topic


Safari Script - Stack Windows

iCab had this wonderful menu command to bring back order into your browser windows. However Cocoa does not support this window handling command by default, so Safari misses it as well. You can implement this feature with the following script.

The Code

Copy and paste this into Script Editor or open in Script Editor

property x_offset : 12
property y_offset : 18
property preferred_width : 800
property preferred_height : 600
tell application "Safari"
	set allWindows to (every window where visible is true)
	set n to count of allWindows
	if (n > 0) then
		activate
		
		-- determine available screen dimensions
		set avail_width to do JavaScript "screen.availWidth" in document 1
		set avail_height to do JavaScript "screen.availHeight" in document 1
		
		tell window 1
			-- set the first window's top left corner correctly, respecting the dock
			set bounds to {0, 0, 400, 300}
			set zoomed to true
			set {x_min, y_min, x, y} to bounds -- we don't need x and y
			
			-- calculate the available screen dimensions
			set x_max to x_min + avail_width
			set y_max to y_min + avail_height
			
			set x1 to x_min
			set x2 to x_min + preferred_width
			if (x2 - x1) > avail_width then ¬
				set x2 to x_min + avail_width
			
			set y1 to y_min
			set y2 to y_min + preferred_height
			if (y2 - y1) > avail_height then ¬
				set y2 to y_min + avail_width
		end tell
		
		-- work through the windows in backwards order so the frontmost window appears bottom right
		repeat with i from n to 1 by -1
			tell window i
				set bounds to {x1, y1, x2, y2}
				set x1 to x1 + x_offset
				set y1 to y1 + y_offset
				set x2 to x2 + x_offset
				if x2 > x_max then set x2 to x_max
				set y2 to y2 + y_offset
				if y2 > y_max then set y2 to y_max
			end tell
		end repeat
		-- this re-focuses the first window
		set index of window 1 to 1
	end if
end tell

The Description

The Script is pretty straightforward. First it will gather all visible (not-minimized) windows and if there are any, proceed.

The next part will determine the available screen dimensions, which is actually quite tricky, because there is no AppleScript equivalent of Cocoa's [[NSScreen mainScreen] visibleFrame]. First we have to determine the available width and height using JavaScript. Then we change the bounds of the first window to an arbitrary value and mimic clicking on the zoom button, which will give us the offset, of the top-left corner of the window. This will be {0, 0} unless you have the dock on the left, which is the only sensible place. Most window zoom scripts will ignore a dock on the left, which is annoying.

Once we've determined the screen dimensions, we simply work through the list of visible windows and set the bounds of the windows accordingly. We work through the list backwards, because AppleScript will move the resized window to the front, so we move backwards through the list and retain the proper order. Finally we have to use a trick line to re-focus on the first window.

The properties in the beginning of the script should be pretty self-explanatory. Change them to your liking and screen resources.

What's Left to do...

(as an exercise to the reader)

  • now the windows will get smaller when they hit the screen border. I'll have to think about some alternative appraoches and how to implement them:
    • calculate the stacking parameters before you stack the windows
    • when the windows hit the bottom of the screen start a second pile to the right of the first (for those with super wide screens or two screens
    • combine windows with single URLs into tabbed windows
  • have not tested it with multiple windows yet
  • More Scripts on RSVP

    Discuss

  • Google
    WWW RSVP.atsites.de

    This page was last updated: Tuesday, November 18, 2003 at 12:41:42 PM
    Copyright 2010 RSVP - Please Reply
    Mail me @ arminbatmacdotcom
    Create your own Manila site in minutes. Everyone's doing it!