Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Tile Safari windows via AppleScript Web Browsers
A friend recently switched to Mac, and asked me if Safari had an equivalent of the "Tile" function on a PC. After asking a few people and poking around, I decided to write a quick script to do just that. With some tweaking it can be used for other applications, and/or multiple apps.

[robg adds: I tested the script, and it works as described. Run it with a number of Safari windows open, and it places them all side-by-side, even spanning across multiple monitors. Each window is sized such that all of them will exactly fill the available horizontal space.]
    •    
  • Currently 2.33 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (6 votes cast)
 
[25,303 views]  

Tile Safari windows via AppleScript | 19 comments | Create New Account
Click here to return to the 'Tile Safari windows via AppleScript' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Tile Safari windows via AppleScript
Authored by: simonpie on Dec 29, '06 07:50:58AM

Well, MacosX does have a system wide tiling function. One just need to use exposť! Just push F10 and you done.



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: adrianm on Dec 29, '06 08:16:44AM

Would be good if it sized each window according to the content... most web pages these days seem to be a fixed width, and a bit of javascript introspection could check that.

---
~/.sig: not found



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: HintGuy2006 on Dec 29, '06 11:29:18AM

Expose will shrink the entire page for all open windows. There's no comparison, Expose wins. jr



[ Reply to This | # ]
Not the same as Exposť
Authored by: anoved on Dec 29, '06 12:04:15PM

Neat. I'll use it. Reminds me of Apple's example "Side by Side" script, except that this works with more than two windows and does not rely on Javascript.

Clicking a window in Exposť brings it forward and deactivates Exposť. I don't think this script is intended to compete with Exposť's "see all windows and select among them" functionality, as some comments seem to conclude. Rather, it arranges the browser windows such that they all remain visible as you continue to work in them.



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: lantzn on Dec 29, '06 12:15:33PM

I find expose to work fine when needing to tile all open windows within a program. However, when it comes to browsing in Safari under Tiger 10.4.8 I tend to use tab browsing. I think Apple should turn tab browsing on by default. It's one of the first things I do when setting up a Mac and then show the owner how to use it. It's great for when you need to do research or price/product comparing.
Now if there was a way to make it so that you could get Safari to tile all the tabbed windows at once, once you've found all the pages you want, it would really be easy to compare all your information side by side.



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: lxmorj on Dec 29, '06 01:55:35PM

I made a few adjustments: this will keep the Dock in mind, but only if it is on the bottom or the right. I haven't yet worked out what to do when its on the left.

tell application "Safari"
-- For some reason Safari has two invisible windows
set allWindows to (every window where visible is true)
set n to count of allWindows
-- Determine screen size of your machine, factoring in the Dock
set screenWidth to do JavaScript "screen.availWidth" in document 1
set screenHeight to do JavaScript "screen.availHeight" in document 1
-- Dividing by zero is bad
if n is equal to 0 then return
-- Determine each window's width
set windowWidth to (screenWidth / n)
set x to 1
-- Position each window in turn
repeat
tell window x
-- 21 is the size of the Menu Bar (for 10.4 at least)
set bounds to {windowWidth * (x - 1), 21, windowWidth * x, screenHeight}
end tell
set x to x + 1
if x is equal to (n + 1) then exit repeat
end repeat
end tell



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: lxmorj on Dec 29, '06 02:31:45PM

The location of the dock is stored as the string "left" "right" or "bottom" in ~/Library/Preferences/com.apple.dock.plist. If someone can please let me know how to get the plist stored as a string, it will be very simple to account for left-side docks...



[ Reply to This | # ]
reading preferences with 'defaults'
Authored by: anoved on Dec 29, '06 03:48:25PM
The location of the dock is stored as the string "left" "right" or "bottom" in ~/Library/Preferences/com.apple.dock.plist. If someone can please let me know how to get the plist stored as a string, it will be very simple to account for left-side docks...

Here's one way:

set dockSide to do shell script "defaults read ~/Library/Preferences/com.apple.dock orientation"

Now dockSide should contain the value of the Dock's orientation preference. Note that in this case the defaults program doesn't need the .plist suffix to be specified.

I think you can read and write preference defaults directly in AppleScript Studio (XCode), but do shell script works for regular scripts.



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: Frederico on Dec 29, '06 03:54:20PM

use:

do shell script "defaults read ~/Library/Preferences/com.apple.dock | grep orientation"

Beware, however, that the orientation flag is never (at least under 10.2 and earlier) generated until the user changes the default location of the Dock from 'bottom' at least once. Thus, be sure to error check for a null result of the above code snippet, and assume that null is default (bottom).



[ Reply to This | # ]
Reading property list items with System Events
Authored by: anoved on Dec 30, '06 07:19:17PM

Just for the sake of reference, here is another way to read a property list preference item with plain AppleScript:

tell application "System Events"
	set dockProps to property list file "~/Library/Preferences/com.apple.dock.plist"
	set dockSide to the value of the property list item "orientation" of dockProps
end tell

Again, dockSide should end up with the value of the orientation property. Just an alternative to do shell script.



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: lxmorj on Dec 29, '06 11:27:07PM

Thanks for the help. Here is the latest reworking:

tell application "Safari"

-- For some reason Safari has (two) invisible windows
set allWindows to (every window where visible is true)
set n to count of allWindows

-- Get dock position
set dock to do shell script "defaults read com.apple.dock orientation"

-- Get actual width to help with left-side docks
tell application "Finder"
set screenSize to bounds of window of desktop
set actualWidth to item 3 of screenSize
end tell

-- Determine space open on your screen, factoring in the Dock
set screenWidth to do JavaScript "screen.availWidth" in document 1
set screenHeight to do JavaScript "screen.availHeight" in document 1

-- Get dock size
set dockSize to actualWidth - screenWidth

-- Get rid of 4 pixel buffer on Dock
if dockSize is 4 then
set dockSize to 0
end if

-- Dividing by zero is bad
if n is equal to 0 then return

-- Determine each window's width
set windowWidth to (screenWidth / n)
set x to 1

-- Position each window in turn
repeat
tell window x
-- 21 is the size of the Menu Bar (for 10.4 at least)
if (dock is not equal to "left") then
set bounds to {windowWidth * (x - 1), 21, windowWidth * x, screenHeight}
else
set bounds to {windowWidth * (x - 1) + dockSize, 21, windowWidth * x + dockSize, screenHeight}
end if
end tell
set x to x + 1
if x is equal to (n + 1) then exit repeat
end repeat
end tell



[ Reply to This | # ]
some suggestions..
Authored by: airdrummer on Dec 30, '06 11:07:13AM
u can apply a script to the frontmost application:
       tell frontmost application
why check for n==0 when you later do if(n>0)? just move everything after ur return inside the if (and everything else 4 that matter...i hate redundant code;-)
	if (n > 0) then 		-- Dividing by zero is bad
		tell application "Finder"
			set screenSize to bounds of window of desktop
			set screenWidth to item 3 of screenSize
			set screenHeight to item 4 of screenSize
		end tell
		set windowWidth to screenWidth / n
		activate
		-- Position each window in turn
and applescript's repeat is full-featured: u don't have 2 code an exit repeat...
		repeat with x from 1 to n
			tell window x to set bounds to {windowWidth * (x - 1), 0, windowWidth * x, screenHeight}
		end repeat
	end if
u also might want to set a lower bound on the width...

[ Reply to This | # ]
some suggestions..
Authored by: lxmorj on Dec 30, '06 03:51:31PM

Yeah, I meant to take the check for if zero return bit out when I put the if n >0 in, but I overlooked it. Also, thanks for the tip on the repeat. The only problem with frontmost application I have come across is that some applications do not respond well to the current code. I personally only have a use for it with Safari. Anything more than around five windows becomes insanely useless, so I am not sure what good a minimum width would accomplish... baba, i will look into it : )



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: baba on Dec 30, '06 02:53:48PM

Hmm, does anyone know of it's possible to check for content windows only? Perhaps check for the existence of a url and/or address window?

Otherwise, auxillary windows, such as the preferences or download windows, will also be tiled.

Thanks for the hint.



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: DougAdams on Dec 30, '06 05:06:29PM

It would be nice if the script ignored any open "View Source" windows and the "Downloads" window. Otherwise, helpful script!

---
Doug's AppleScripts for iTunes
http://www.dougscripts.com/itunes/



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: lxmorj on Dec 31, '06 12:38:19AM
Factors in Downloads and Source, less redundant : ). Still need a better way to determine the download window. Leads thus far are:
1- It's window id is constant unless Safari is restarted.
2- It's document field is blank.


tell application "Safari"

-- For some reason Safari has (two) invisible windows
set allWindows to (every window where visible is true)

set n to count of allWindows
set goodWindows to {}

-- Might run into problems with actual websites titled "Downloads", open for suggestions a more perfect solution : )
repeat with x from 1 to n
set windowX to item x of allWindows
if ((name of windowX does not contain "Source of http://";) and (name of windowX is not "Downloads")) then
set goodWindows to goodWindows & {windowX}
end if
end repeat

set n to count of goodWindows

if n is 0 then return
-- Dividing by zero is bad


-- Get dock position
set dock to do shell script "defaults read com.apple.dock orientation"

-- Get actual width of screen to help with left-side docks
tell application "Finder"
set screenSize to bounds of window of desktop
set actualWidth to item 3 of screenSize
end tell

-- Determine space open on your screen, factoring in the Dock
set screenWidth to do JavaScript "screen.availWidth" in document 1
set screenHeight to do JavaScript "screen.availHeight" in document 1

-- Get dock size
set dockSize to actualWidth - screenWidth

-- Get rid of 4 pixel buffer on Dock
if dockSize is 4 then
set dockSize to 0
end if

-- Determine each window's width
set windowWidth to (screenWidth / n)

-- Position each window in turn
repeat with x from 1 to n
tell item x of goodWindows
set index to 1 --Makes sure the Source and Downloads windows are behind the tiled ones
if (dock is not equal to "left") then
set bounds to {windowWidth * (x - 1), 21, windowWidth * x, screenHeight} -- 21 is the size of the Menu Bar (for 10.4 at least)

else
set bounds to {windowWidth * (x - 1) + dockSize, 21, windowWidth * x + dockSize, screenHeight}
end if
end tell
end repeat
end tell

[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: Frederico on Dec 31, '06 10:55:17AM

"-- Might run into problems with actual websites titled "Downloads", open for suggestions a more perfect solution : )"

The actual downloads window should not have a URL; check for it, and ignore it. e.g.,

set pageURL to URL of document of window 1

You might also want to note under which versions of Safari you have tested this; it breaks on older versions.



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: lxmorj on Jan 06, '07 11:40:02AM

Perfected : ) (Although perhaps not optimized)

--Tested only on a 17in Powerbook G4 running 10.4.8, Safari Version 2.0.4
tell application "Safari"

-- For some reason Safari has (two?) invisible windows
set allWindows to (every window where visible is true)

set n to count of allWindows

--This list will exclude all Source windows, and the Download window
set goodWindows to {}

repeat with x from 1 to n
set windowX to item x of allWindows
if (URL of document of windowX exists) then
set goodWindows to goodWindows & {windowX}
end if
end repeat

set n to count of goodWindows

-- Dividing by zero is bad
if n is 0 then return

-- If Downloads or Source window is frontmost, screenWidth and screenHeight will not be defined
set goodDoc to document of first item of goodWindows

-- Get dock position
set dock to do shell script "defaults read com.apple.dock orientation"

-- Get actual width of screen to help with left-side docks
tell application "Finder"
set screenSize to bounds of window of desktop
set actualWidth to item 3 of screenSize
end tell

-- Determine space open on your screen, factoring in the Dock
set screenWidth to do JavaScript "screen.availWidth" in goodDoc
set screenHeight to do JavaScript "screen.availHeight" in goodDoc

-- Get dock size
set dockSize to actualWidth - screenWidth

-- Get rid of pixel buffer on Dock
set screenHeight to screenHeight + 26

-- Determine desired width of each window
set windowWidth to (screenWidth / n)

-- Position each window in turn
repeat with x from 1 to n
tell item x of goodWindows
set index to 1 --Makes sure the Source and Downloads windows are behind the tiled ones
if (dock is not equal to "left") then --Coordinates are measured from the upper left corner, so the left-side dock is the special case

set bounds to {windowWidth * (x - 1), 21, windowWidth * x, screenHeight} -- 21 is the size of the Menu Bar (for 10.4 at least)

else
set bounds to {windowWidth * (x - 1) + dockSize, 21, windowWidth * x + dockSize, screenHeight}
end if
end tell
end repeat

end tell



[ Reply to This | # ]
Tile Safari windows via AppleScript
Authored by: deviantintegral on Apr 11, '09 09:12:02AM
Here is a version which easily allows tiling only on the primary monitor (assuming it's the largest monitor). This works for me as I have a 24" LCD connected to my Macbook, and I really don't want the script to treat them as one wide monitor. Set the first variable to the width of your primary monitor. When on the road without it connected, the script should still work as expected.
set primaryWidth to 1920

tell application "Safari"
	
	-- For some reason Safari has (two) invisible windows
	set allWindows to (every window where visible is true)
	set n to count of allWindows
	
	-- Get dock position
	set dock to do shell script "defaults read com.apple.dock orientation"
	
	-- Get actual width to help with left-side docks
	tell application "Finder"
		set screenSize to bounds of window of desktop
		set actualWidth to item 3 of screenSize
		if actualWidth is greater than primaryWidth then set actualWidth to primaryWidth
	end tell
	
	-- Determine space open on your screen, factoring in the Dock
	set screenWidth to do JavaScript "screen.availWidth" in document 1
	set screenHeight to do JavaScript "screen.availHeight" in document 1
	
	-- Get dock size
	set dockSize to actualWidth - screenWidth
	
	-- Get rid of 4 pixel buffer on Dock
	if dockSize is 4 then
		set dockSize to 0
	end if
	
	-- Dividing by zero is bad
	if n is equal to 0 then return
	
	-- Determine each window's width
	set windowWidth to (screenWidth / n)
	set x to 1
	
	-- Position each window in turn
	repeat
		tell window x
			-- 21 is the size of the Menu Bar (for 10.4 at least)
			if (dock is not equal to "left") then
				set bounds to {windowWidth * (x - 1), 21, windowWidth * x, screenHeight}
			else
				set bounds to {windowWidth * (x - 1) + dockSize, 21, windowWidth * x + dockSize, screenHeight}
			end if
		end tell
		set x to x + 1
		if x is equal to (n + 1) then exit repeat
	end repeat
end tell


[ Reply to This | # ]