# 3x3 Matrix Bounds

Hi,
while sorting files hoarded over the years, thought I cud arrange finder windows (cud be other apps too) on one of the screen (I have two)

First Take, which works

``````
tell application "Finder" to set {a, b, c, d} to bounds of window of desktop
--3x3 Matrix
set nCol to 3
set nRow to 3
set w to (c - a) / nCol
set h to (d - b) / nRow

set win1 to {(a + 0 * w), (b + 0 * h), (a + 1 * w), (b + 1 * h)} --LeftTop
set win2 to {(a + 0 * w), (b + 1 * h), (a + 1 * w), (b + 2 * h)} --LeftMid
set win3 to {(a + 0 * w), (b + 2 * h), (a + 1 * w), (b + 3 * h)} --LeftBottom

set win4 to {(a + 1 * w), (b + 0 * h), (a + 2 * w), (b + 1 * h)} --MiddleTop
set win5 to {(a + 1 * w), (b + 1 * h), (a + 2 * w), (b + 2 * h)} --MiddleMid
set win6 to {(a + 1 * w), (b + 2 * h), (a + 2 * w), (b + 3 * h)} --Middle

set win7 to {(a + 2 * w), (b + 0 * h), (a + 3 * w), (b + 1 * h)} --RightTop
set win8 to {(a + 2 * w), (b + 1 * h), (a + 3 * w), (b + 2 * h)} --RightMid
set win9 to {(a + 2 * w), (b + 2 * h), (a + 3 * w), (b + 3 * h)} --RightBottom

``````

Then I tried this, which generates the bounds.

``````
tell application "Finder" to set {a, b, c, d} to bounds of window of desktop
--3x3 Matrix
set nCol to 3
set nRow to 3
set w to (c - a) / nCol
set h to (d - b) / nRow
set Hc to "1"
repeat until Hc = nCol + 1
set Wc to "1"
repeat until Wc = nRow + 1
set winBound to {(a + (Hc - 1) * w), (b + (Wc - 1) * h), (a + Hc * w), (b + Wc * h)}
-- do something with winBound

set Wc to Wc + 1
end repeat
set Hc to Hc + 1
end repeat

``````

Just wondering if it cud be written better,
cud take into account the "useable " area of the screen,
Assign these bounds to existing Finder windows.
I cant figure out how to count windows 1, windows 2 etc and assign them to generated bounds
Cheers

Thanks peavine, i wud try your script. Meanwhile plz have a look at another try
This assumes LeftTop window = 1, LeftMid = 2, MiddleMid=5 … RightBottom=9

``````
-- LeftBottom wud be 3
winBounds(GetColRow("3") of me)

on GetColRow(winNo)
if winNo = 0 then
return
else if winNo ≤ 3 then
set Hc to "1"
if winNo is "1" then
set Wc to "1"
return {Hc, Wc}
else if winNo is "2" then
set Wc to "2"
return {Hc, Wc}
else if winNo is "3" then
set Wc to "3"
return {Hc, Wc}
end if
else if winNo ≤ 6 then
set Hc to "2"
if winNo is "4" then
set Wc to "1"
return {Hc, Wc}
else if winNo is "5" then
set Wc to "2"
return {Hc, Wc}
else if winNo is "6" then
set Wc to "3"
return {Hc, Wc}
end if
else
set Hc to "3"
if winNo is "1" then
set Wc to "7"
return {Hc, Wc}
else if winNo is "2" then
set Wc to "8"
return {Hc, Wc}
else if winNo is "9" then
set Wc to "3"
return {Hc, Wc}
end if
end if
end GetColRow

on winBounds(GetColRow)
set {a, b, c, d} to {1920, 0, 3840, 1080}
set w to (c - a) / 3
set h to (d - b) / 3
set Hc to item 1 of GetColRow
set Wc to item 2 of GetColRow
set winBound to {(a + (Hc - 1) * w), (b + (Wc - 1) * h), (a + Hc * w), (b + Wc * h)}
return winBound
end winBounds

``````

Sorry–my mistake. I’ll try your script.

One208. I tested the second script in post 1, and, after adding the necessary Finder code and making a few other edits, it works well.

``````tell application "Finder"
activate
set {a, b, c, d} to bounds of window of desktop
end tell

set nCol to 3
set nRow to 3
set w to ((c - a) / nCol) as integer
set h to ((d - b) / nRow) as integer

set theBounds to {}
repeat with i from 1 to nCol
repeat with j from 1 to nRow
set winBound to {a + ((i - 1) * w), b + ((j - 1) * h), a + (i * w), b + (j * h)}
set end of theBounds to winBound
end repeat
end repeat

tell application "Finder"
repeat with i from 1 to (count Finder windows)
set bounds of Finder window i to (item i of theBounds)
end repeat
end tell
``````

Your script does not consider the dock height or width (if the dock is visible). To fix this, I think you would have to use the visible screen area as returned by the following:

``````use framework "Foundation"

set theFrame to current application's NSScreen's screens()'s firstObject()'s visibleFrame() as list
-- returns {{69.0, 0.0}, {1851.0, 1055.0}} on my computer with dock side-aligned
``````

Thanks peavine, I am happy I cud write a working script ``````
--change if Finder window count was less then 9
tell application "Finder"
set n to count of windows
repeat with i from 1 to n
set bounds of Finder window i to (item i of theBounds)
end repeat
end tell

``````

One208. Your script works extremely well. I’ll be interested to see how you edit the script to account for dock height or width.

@peavine, for the time being, I think I am going to copy
https://www.macscripter.net/viewtopic.php?id=46336

``````
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
set myScreenID to 188975774
set screensInfo to getUsableScreenBounds()
-- →{{screenID:188975774, usableBounds:{0, 23, 1920, 1017}}, {screenID:188815381, usableBounds:{1920, 0, 3840, 1080}}}
repeat with thisScreen in screensInfo
if (thisScreen's screenID is myScreenID) then
set {a, b, c, d} to thisScreen's usableBounds
exit repeat
end if
end repeat
set nCol to 3
set nRow to 3
set w to (c - a) / nCol
set h to (d - b) / nRow
set Hc to "1"
set theBounds to {}
repeat until Hc = nCol + 1
set Wc to "1"
repeat until Wc = nRow + 1
set winBound to {(a + (Hc - 1) * w), (b + (Wc - 1) * h), (a + Hc * w), (b + Wc * h)}
set end of theBounds to winBound
set Wc to Wc + 1
end repeat
set Hc to Hc + 1
end repeat

tell application "Finder"
set n to count of windows
repeat with i from 1 to n
set bounds of Finder window i to (item i of theBounds)
end repeat
end tell
--================================================================
--» HANDLER
--================================================================
on getUsableScreenBounds()
set |⌘| to current application
set theResult to {}
set theScreens to |⌘|'s class "NSScreen"'s screens()
repeat with thisScreen in theScreens
set screenID to ((thisScreen's deviceDescription())'s valueForKey:("NSScreenNumber")) as integer
set wholeFrame to thisScreen's frame()
set visibleFrame to thisScreen's visibleFrame()

-- In High Sierra, the frame rects are returned as lists instead of records, but the functions below work with either.
set x1 to (|⌘|'s NSMinX(visibleFrame)) as integer
-- The y origin in NSScreen is at the bottom of the screen. It needs to be converted to an origin at the top for AS.
set y1 to ((|⌘|'s NSMaxY(wholeFrame)) - (|⌘|'s NSMaxY(visibleFrame))) as integer
set x2 to (|⌘|'s NSMaxX(visibleFrame)) as integer
set y2 to (y1 + (|⌘|'s NSHeight(visibleFrame))) as integer
set end of theResult to {screenID:screenID, usableBounds:{x1, y1, x2, y2}}
end repeat

return theResult
end getUsableScreenBounds
--» End of Handler ===================================================

``````