Skip to content

Instantly share code, notes, and snippets.

@c4710n
Last active January 1, 2021 02:41
Show Gist options
  • Save c4710n/54084b1a39567f3a0890e3dcb2b6e04f to your computer and use it in GitHub Desktop.
Save c4710n/54084b1a39567f3a0890e3dcb2b6e04f to your computer and use it in GitHub Desktop.
macOS: position window with builtin utilities
#!/usr/bin/env osascript
#
# Usage:
# $ ./position-window.applescript <position>
# Available postions:
# - left
# - right
# - full
# - center
#
# Note:
# Currently, I have no idea about how to get the actived display.
# Because of that, this script supports one display only.
#
# References:
# + https://daringfireball.net/2006/12/display_size_applescript_the_lazy_way
# + http://stackoverflow.com/questions/5292204/macosx-get-foremost-window-title
# + https://github.com/1MikeMakuch/growwin/blob/6dc53c9f07b6e1ad397e09976705a12ccc633085/GrowLeft.scpt#L48
on run argv
global _desktopWidth, _desktopHeight
global _frontApp, _frontAppName
global _gap
set _gap to 15
tell application "Finder"
set _desktopSize to bounds of window of desktop
set _desktopWidth to item 3 of _desktopSize
set _desktopHeight to item 4 of _desktopSize
end tell
tell application "System Events"
set _frontApp to first application process whose frontmost is true
set _frontAppName to name of _frontApp
end tell
-- the first argument passed from CLI
set argv1 to item 1 of argv
if argv1 is "left" then
set position to leftPosition(_desktopWidth, _desktopHeight, _gap)
else if argv1 is "right" then
set position to rightPosition(_desktopWidth, _desktopHeight, _gap)
else if argv1 is "full" then
set position to fullPosition(_desktopWidth, _desktopHeight, _gap)
else if argv1 is "center" then
set position to centerPosition(_desktopWidth, _desktopHeight, _gap)
else
beep
display alert "Position window with unknown position, exiting"
return
end if
set x to item 1 of position
set y to item 2 of position
set width to item 3 of position
set height to item 4 of position
positionCurrentWindow(_frontAppName, x, y, width, height)
end run
on positionCurrentWindow(appName, x, y, width, height)
tell application "System Events" to tell process appName
-- The trick here is that you can't rely on "window 1" to be the one you're after,
-- So let's filter the UI elements list by subroles.
-- Emacs return a a total bogus AXTextField:AXStandardWindow, but we can stil work with it
set theWindows to (every UI element whose subrole is "AXStandardWindow")
-- For Activity Monitor (others?)
if theWindows is {} then set theWindows to (every UI element whose subrole is "AXDialog")
if theWindows is {} then
beep
return
end if
set theWindow to (first item of theWindows)
set position of theWindow to {x, y}
set size of theWindow to {width, height}
end tell
end positionCurrentWindow
on leftPosition(desktopWidth, desktopHeight, gap)
set width to (desktopWidth - 3 * gap) / 2
set height to desktopHeight - 2 * gap
set x to gap
set y to gap
return {x, y, width, height}
end leftPosition
on rightPosition(desktopWidth, desktopHeight, gap)
set width to (desktopWidth - 3 * gap) / 2
set height to desktopHeight - 2 * gap
set x to width + 2 * gap
set y to gap
return {x, y, width, height}
end rightPosition
on fullPosition(desktopWidth, desktopHeight, gap)
set width to desktopWidth - 2 * gap
set height to desktopHeight - 2 * gap
set x to gap
set y to gap
return {x, y, width, height}
end fullPosition
on centerPosition(desktopWidth, desktopHeight, gap)
set width to desktopWidth * 0.67 - gap
set height to desktopHeight * 0.85
set x to desktopWidth * 0.33
set y to gap
return {x, y, width, height}
end centerPosition
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment