Skip to content

Instantly share code, notes, and snippets.

@WardsParadox
Last active December 17, 2025 15:54
Show Gist options
  • Select an option

  • Save WardsParadox/9b300ca4a67cf5414a180bd060854fff to your computer and use it in GitHub Desktop.

Select an option

Save WardsParadox/9b300ca4a67cf5414a180bd060854fff to your computer and use it in GitHub Desktop.
Rectangle move to next window as applescript instead, Fully references Rectangle code for screendetection
-- AppleScript to move focused window to the next screen
use framework "Foundation"
use framework "AppKit"
use scripting additions
on run
moveWindowToNextScreen()
end run
on moveWindowToNextScreen()
-- Get all screens
set allScreens to current application's NSScreen's screens()
set screenCount to allScreens's |count|()
if screenCount < 2 then
display notification "Only one screen detected" with title "Move Window"
return
end if
-- Get main screen height for coordinate conversion (Cocoa uses bottom-left origin)
set mainScreen to (allScreens's objectAtIndex:0)
set mainFrame to mainScreen's frame()
set mainHeight to (item 2 of item 2 of mainFrame) as real
-- Get the frontmost application and its focused window
tell application "System Events"
set frontApp to first application process whose frontmost is true
try
set frontWindow to first window of frontApp
set {winX, winY} to position of frontWindow
set {winWidth, winHeight} to size of frontWindow
on error
display notification "No window found" with title "Move Window"
return
end try
end tell
-- Window center in System Events coordinates (origin top-left)
set windowCenterX to winX + (winWidth / 2)
set windowCenterY to winY + (winHeight / 2)
-- Build list of screens with their frames converted to System Events coordinates
set screenFrames to {}
repeat with i from 0 to (screenCount - 1)
set currentScreen to (allScreens's objectAtIndex:i)
set screenFrame to currentScreen's frame()
set visibleFrame to currentScreen's visibleFrame()
-- Cocoa frame coordinates
set frameX to (item 1 of item 1 of screenFrame) as real
set frameY to (item 2 of item 1 of screenFrame) as real
set frameW to (item 1 of item 2 of screenFrame) as real
set frameH to (item 2 of item 2 of screenFrame) as real
-- Cocoa visible frame coordinates
set visX to (item 1 of item 1 of visibleFrame) as real
set visY to (item 2 of item 1 of visibleFrame) as real
set visW to (item 1 of item 2 of visibleFrame) as real
set visH to (item 2 of item 2 of visibleFrame) as real
-- Convert Y coordinates from Cocoa (bottom-left origin) to System Events (top-left origin)
-- For full frame: top Y in SE coords = mainHeight - (cocoaY + cocoaHeight)
set screenTopY to mainHeight - (frameY + frameH)
-- For visible frame: need to convert the visible area's top position
set visibleTopY to mainHeight - (visY + visH)
set end of screenFrames to {screenIndex:i, x:frameX, y:screenTopY, width:frameW, height:frameH, visX:visX, visY:visibleTopY, visW:visW, visH:visH}
end repeat
-- Sort screens by X coordinate (left to right)
set sortedScreens to sortScreensByX(screenFrames)
-- Find which screen contains the window center
set currentScreenPos to 0
repeat with i from 1 to count of sortedScreens
set scr to item i of sortedScreens
set scrLeft to (x of scr)
set scrRight to scrLeft + (width of scr)
set scrTop to (y of scr)
set scrBottom to scrTop + (height of scr)
if windowCenterX � scrLeft and windowCenterX < scrRight and windowCenterY � scrTop and windowCenterY < scrBottom then
set currentScreenPos to i
exit repeat
end if
end repeat
-- Fallback: if no screen found, find by X only
if currentScreenPos = 0 then
repeat with i from 1 to count of sortedScreens
set scr to item i of sortedScreens
if windowCenterX � (x of scr) and windowCenterX < ((x of scr) + (width of scr)) then
set currentScreenPos to i
exit repeat
end if
end repeat
end if
-- Final fallback
if currentScreenPos = 0 then set currentScreenPos to 1
-- Calculate next screen (wrap around)
set nextScreenPos to currentScreenPos + 1
if nextScreenPos > (count of sortedScreens) then set nextScreenPos to 1
set targetScreen to item nextScreenPos of sortedScreens
set sourceScreen to item currentScreenPos of sortedScreens
-- Calculate relative position of window on current screen's visible area
set relX to (winX - (x of sourceScreen)) / (width of sourceScreen)
set relY to (winY - (y of sourceScreen)) / (height of sourceScreen)
-- Calculate new position on target screen (maintaining relative position)
set newX to (x of targetScreen) + (relX * (width of targetScreen))
set newY to (y of targetScreen) + (relY * (height of targetScreen))
-- Ensure window fits within target screen's visible area
set targetVisLeft to (visX of targetScreen)
set targetVisTop to (visY of targetScreen)
set targetVisRight to targetVisLeft + (visW of targetScreen)
set targetVisBottom to targetVisTop + (visH of targetScreen)
if newX < targetVisLeft then set newX to targetVisLeft
if newY < targetVisTop then set newY to targetVisTop
if (newX + winWidth) > targetVisRight then
set newX to targetVisRight - winWidth
end if
if (newY + winHeight) > targetVisBottom then
set newY to targetVisBottom - winHeight
end if
-- Move the window
tell application "System Events"
tell frontApp
set position of first window to {newX as integer, newY as integer}
end tell
end tell
end moveWindowToNextScreen
on sortScreensByX(screenList)
set sortedList to screenList
repeat with i from 1 to (count of sortedList) - 1
repeat with j from 1 to (count of sortedList) - i
if (x of item j of sortedList) > (x of item (j + 1) of sortedList) then
set temp to item j of sortedList
set item j of sortedList to item (j + 1) of sortedList
set item (j + 1) of sortedList to temp
end if
end repeat
end repeat
return sortedList
end sortScreensByX
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment