just a script that i have been playing with, the purpose of which is to “tile” all windows from the front application.
It’s useful when u need to view several windows at the same time. for example when u r doing multiple window chatting using ichat or other chatting programs, or comparing two editor windows from the script editor.
--tile windows of frontmost applications in a grid
--this script is useful for
--multiple window chatting
--working side by side of several windows of the same app
--make need to make it as a stay open application later
--for now assume that it is opened and closed per invokation
on run {}
local a
set userscreen to my getUserScreen()
--display dialog (getFrntApp() as string)
try
set applist to getFrntApp()
if length of applist = 0 then
return
end if
set a to item 1 of getFrntApp()
on error
return
end try
try
tileScriptable(a, userscreen)
on error
tileUnscriptable(a, userscreen)
end try
end run
on tileScriptable(a, screen)
local i, c
set i to 1
tell application named a
set theWindows to every window of application a whose visible is true and floating is false and ¬
modal is false -- and miniaturized is false
set c to count theWindows
if c = 0 then
return
end if
set tiles to calTileBounds(c, screen, 1)
repeat with theWindow in theWindows
--tileScriptableWindow(a, theWindow, {0, 22, 1024, 728})
my tileScriptableWindow(a, theWindow, item i of tiles)
set i to i + 1
end repeat
end tell
end tileScriptable
on tileUnscriptable(a, screeninfo)
-- unscriptable app
local i, c
set i to 1
tell application "System Events"
set theWindows to (every window of application process a)
set theWindows to my filterUnscriptableInvisible(theWindows)
set c to count theWindows
if c = 0 then
return
end if
--display dialog screeninfo as string giving up after 5
set tiles to my calTileBounds(c, screeninfo, 1)
repeat with theWindow in theWindows
--display dialog (class of visible of theWindow)
my tileUnScriptableWindow(a, theWindow, item i of tiles)
set i to i + 1
end repeat
end tell
end tileUnscriptable
on filterUnscriptableInvisible(ws)
-- filter out from ws windows that are docked
set newws to {}
set docklist to getNamesDocked()
--display dialog (docklist as string)
repeat with theWindow in ws
if name of theWindow is not in docklist then
set end of newws to theWindow
end if
end repeat
--display dialog (count newws)
return newws
end filterUnscriptableInvisible
on getNamesDocked()
tell application "System Events" to tell process "Dock"'s list 1
set l to name of UI elements whose subrole is "AXMinimizedWindowDockItem"
end tell
return l
end getNamesDocked
on tileScriptableWindow(a, w, bound)
tell application a
set bounds of w to bound
end tell
end tileScriptableWindow
on tileUnScriptableWindow(a, w, bound)
tell application "System Events"
--display dialog (count position of w)
set AppleScript's text item delimiters to " "
set position of w to {(item 1 of bound), (item 2 of bound)}
set size of w to {(item 3 of bound) - (item 1 of bound) - 5, ¬
(item 4 of bound) - (item 2 of bound) - 5}
--display dialog (count properties of w)
end tell
end tileUnScriptableWindow
on calTileBounds(c, screen, direction)
-- return a list of lists of window bounds
-- a simple tile algo that tiles along direction (current only 1=horizontal)
local maxgridx, maxgridy, nrow, ncolumn, irow, icolumn
set {maxgridx, maxgridy} to {3, 3}
set {x0, y0, w0, h0} to screen
set ret to {}
-- case 0: c <= maxgridx. tile them beautifully!
if c ≤ maxgridx then
set {nrow, ncolumn} to {1, c}
set {wgrid, hgrid} to {(w0 / c as integer), h0}
repeat with icolumn from 1 to c
set itile to {x0 + (icolumn - 1) * wgrid, y0, x0 + (icolumn - 1) * wgrid + wgrid, y0 + hgrid}
--set itile to {x0 + (icolumn - 1) * wgrid, y0, wgrid, hgrid}
--set item 3 of itile to ((item 1 of itile) + (item 3 of itile))
--set item 4 of itile to ((item 2 of itile) + (item 4 of itile))
set end of ret to itile
end repeat
return ret
end if
--case 1: maxgridx<c<= maxgridx*maxgridy. tile them in maxgridy rows, but gracefully on the last row
if c ≤ maxgridx * maxgridy then
set temp to (c div maxgridx)
if 0 ≠(c - (temp) * maxgridx) then
set {nrow, ncolumn} to {temp + 1, maxgridx}
else
set {nrow, ncolumn} to {temp, maxgridx}
end if
--???
set {wgrid, hgrid} to {((w0 / ncolumn) as integer), (h0 / nrow) as integer}
repeat with irow from 1 to nrow - 1
repeat with icolumn from 1 to ncolumn
set itile to {x0 + (icolumn - 1) * wgrid, y0 + (irow - 1) * hgrid, x0 + (icolumn - 1) * wgrid + wgrid, y0 + (irow - 1) * hgrid + hgrid}
--display dialog item 3 of itile as string
--set itile to {x0 + (icolumn - 1) * wgrid, y0, wgrid, hgrid}
--set item 3 of itile to ((item 1 of itile) + (item 3 of itile))
--set item 4 of itile to ((item 2 of itile) + (item 4 of itile))
set end of ret to itile
end repeat
end repeat
set nleft to (c - (nrow - 1) * ncolumn)
set wgrid to (w0 / nleft)
repeat with i from 1 to nleft
set itile to {x0 + (i - 1) * wgrid, y0 + (nrow - 1) * hgrid, x0 + (i - 1) * wgrid + wgrid, y0 + (nrow - 1) * hgrid + hgrid}
set end of ret to itile
end repeat
return ret
end if
--case2 : c> maxgridx*maxgridy. no tile at all. put all windows to {0,22,800,600}
if c > maxgridx * maxgridy then
repeat with icolumn from 1 to c
set itile to {x0, y0, 800, 600}
set end of ret to itile
end repeat
return ret
end if
end calTileBounds
on getFrntApp()
tell application "System Events" to set frntProc to ¬
name of every process whose frontmost is true and visible ≠false
return frntProc
end getFrntApp
on getUserScreen()
-- size of menubar takes up wmenu=1024 hmenu=22
tell application "System Events"
set {wMenu, hMenu} to size of UI element 1 of application process "SystemUIServer"
set dockApp to (application process "Dock")
set sizeDock to size of UI element 1 of dockApp
--display dialog (item 1 of sizeDock as string) & " " & (item 2 of sizeDock)
set posDock to position of UI element 1 of dockApp
--display dialog (posDock as string)
end tell
-- size of the full screen
(*
{word 3 of (do shell script "defaults read /Library/Preferences/com.apple.windowserver | grep -w Width") as number, ¬
word 3 of (do shell script "defaults read /Library/Preferences/com.apple.windowserver | grep -w Height") as number}
*)
set wScreen to 1024
set hscreen to 768
--determine the userscreen origin and size
--case 0: bottom dock
if ((item 2 of posDock) + (item 2 of sizeDock) = hscreen) then
set wuser to wScreen
set hUser to hscreen - hMenu - (item 2 of sizeDock)
set xUser to 0
set yUser to hMenu
return {xUser, yUser, wuser, hUser}
end if
--case 1: hidden dock
if (item 1 of posDock < 0) then
set wuser to wScreen
set hUser to hscreen - hMenu
set xUser to 0
set yUser to hMenu + 1
return {wuser, hUser, xUser, yUser}
end if
--case 2: left dock
if (item 1 of posDock = 0) then
set wuser to wScreen - (item 1 of sizeDock)
set hUser to hscreen - hMenu
set xUser to (item 1 of sizeDock) + 1
set yUser to hMenu + 1
return {xUser, yUser, wuser, hUser}
end if
--case 3: right dock
if ((item 1 of posDock) + (item 1 of sizeDock) = wScreen) then
set wuser to wScreen - (item 1 of sizeDock)
set hUser to hscreen - hMenu
set xUser to 0
set yUser to hMenu
return {xUser, yUser, wuser, hUser}
end if
end getUserScreen